Created
October 2, 2014 02:43
-
-
Save nataliefreed/5e0904dd3e90f48dd985 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Bezier curve cute blob shapes code generator | |
//The fancier version! | |
//Natalie Freed Oct. 2014 | |
DraggableHandler points; | |
String codeString; | |
void setup() | |
{ | |
size(700, 700); | |
points = new DraggableHandler(this); | |
//starting point | |
points.addToEnd(new DraggableCircle(226, 328, 16, color(0, 100, 0, 150))); | |
//control points for first curve | |
points.addToEnd(new DraggableCircle(152, 206, 10, color(160, 0, 160, 150))); | |
points.addToEnd(new DraggableCircle(395, 59, 10, color(255, 0, 255, 150))); | |
//ending point | |
points.addToEnd(new DraggableCircle(432, 214, 16, color(0, 150, 0, 150))); | |
//control points for second curve | |
points.addToEnd(new DraggableCircle(460, 431, 10, color(255, 100, 0, 150))); | |
points.addToEnd(new DraggableCircle(316, 471, 10, color(160, 100, 0, 150))); | |
((DraggableCircle)points.get(1)).connect((DraggableCircle)points.get(5), (DraggableCircle)points.get(0)); | |
((DraggableCircle)points.get(5)).connect((DraggableCircle)points.get(1), (DraggableCircle)points.get(0)); | |
((DraggableCircle)points.get(2)).connect((DraggableCircle)points.get(4), (DraggableCircle)points.get(3)); | |
((DraggableCircle)points.get(4)).connect((DraggableCircle)points.get(2), (DraggableCircle)points.get(3)); | |
} | |
void draw() | |
{ | |
background(100); | |
points.display(); | |
noFill(); | |
stroke(0); | |
beginShape(); | |
vertex(points.get(0).getX(), points.get(0).getY()); | |
bezierVertex(points.get(1).getX(), points.get(1).getY(), points.get(2).getX(), points.get(2).getY(), points.get(3).getX(), points.get(3).getY()); | |
bezierVertex(points.get(4).getX(), points.get(4).getY(), points.get(5).getX(), points.get(5).getY(), points.get(0).getX(), points.get(0).getY()); | |
endShape(); | |
// bezier(130, 254, 134, 80, 415, 48, 459, 288); | |
fill(0); | |
textSize(18); | |
codeString = "beginShape();" | |
+ "\nvertex(" + round(points.get(0).getX()) + ", " + round(points.get(0).getY()) + ");" | |
+ "\nbezierVertex(" + round(points.get(1).getX()) + ", " + round(points.get(1).getY()) + ", " + round(points.get(2).getX()) + ", " + round(points.get(2).getY()) + ", " + round(points.get(3).getX()) + ", " + round(points.get(3).getY()) + ");" | |
+ "\nbezierVertex(" + round(points.get(4).getX()) + ", " + round(points.get(4).getY()) + ", " + round(points.get(5).getX()) + ", " + round(points.get(5).getY()) + ", " + round(points.get(0).getX()) + ", " + round(points.get(0).getY()) + ");" | |
+ "\nendShape();"; | |
text(codeString, 20, 450, width-20, 30*6); | |
fill(255); | |
textSize(16); | |
text("Click and drag the endpoints and control points to change the bezier curves.", 20, 620); | |
text("You can copy the generated code from the Processing console.", 20, 640); | |
text("Constraining control points to tangent lines makes cute round shapes without points.", 20, 660); | |
text("Hit spacebar to toggle constraints.", 20, 680); | |
} | |
class DraggableCircle implements Draggable | |
{ | |
PVector center; | |
int radius; | |
boolean dragged; | |
int fillColor; | |
PVector clickOffset; //offset of cursor from center | |
DraggableCircle connectedTo = null; | |
DraggableCircle connectedThrough = null; | |
ArrayList<DraggableCircle> connectedList; | |
boolean allowConstraints; | |
DraggableCircle(int centerX, int centerY, int tempRadius, int tempColor) | |
{ | |
center = new PVector(centerX, centerY); | |
radius = tempRadius; | |
fillColor = tempColor; | |
dragged = false; | |
PVector clickOffset = new PVector(0, 0); | |
connectedList = new ArrayList<DraggableCircle>(); | |
allowConstraints = true; | |
} | |
void display() | |
{ | |
noStroke(); | |
fill(fillColor); | |
ellipse(center.x, center.y, radius*2, radius*2); | |
} | |
float getX() | |
{ | |
return center.x; | |
} | |
float getY() | |
{ | |
return center.y; | |
} | |
boolean isOver(int x, int y) | |
{ | |
//return true if distance between point and center is smaller than radius | |
if (dist(center.x, center.y, x, y) <= radius) | |
{ | |
return true; | |
} | |
else | |
{ | |
return false; | |
} | |
} | |
void update() //move with mouse | |
{ | |
if (dragged) | |
{ | |
if(mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) //don't let it get away! | |
{ | |
setCenter(PVector.add(new PVector(mouseX, mouseY), clickOffset)); | |
} | |
} | |
} | |
void setCenter(PVector v) | |
{ | |
if(allowConstraints) | |
{ | |
if(connectedList.size() > 0) | |
{ | |
PVector offset = PVector.sub(v, center); | |
for(int i=0;i<connectedList.size();i++) | |
{ | |
connectedList.get(i).center.add(offset); | |
} | |
} | |
if(connectedTo != null && connectedThrough != null) | |
{ | |
PVector dir = PVector.sub(connectedThrough.center, v); | |
dir.normalize(); | |
dir.setMag(PVector.dist(connectedThrough.center, connectedTo.center)); | |
PVector newLoc = PVector.add(connectedThrough.center, dir); | |
connectedTo.center = newLoc; | |
} | |
} | |
center.set(v); | |
} | |
void connect(DraggableCircle to, DraggableCircle through) | |
{ | |
connectedTo = to; | |
connectedThrough = through; | |
through.connectedList.add(this); | |
} | |
void toggleConstraints() | |
{ | |
allowConstraints = !allowConstraints; | |
} | |
void setDragged(int fromX, int fromY) | |
{ | |
dragged = true; | |
clickOffset = PVector.sub(center, new PVector(fromX, fromY)); | |
} | |
void releaseDragged() | |
{ | |
dragged = false; | |
} | |
} | |
//You don't need to change anything below here! | |
//Here in case you want to peek under the hood, but | |
//there's some slightly weird stuff. | |
interface Draggable | |
{ | |
void update(); | |
void display(); | |
void setDragged(int fromX, int fromY); | |
void releaseDragged(); | |
void toggleConstraints(); | |
float getX(); | |
float getY(); | |
boolean isOver(int x, int y); | |
} | |
public class DraggableHandler | |
{ | |
ArrayList<Draggable> draggables; | |
Draggable currentDragged; | |
DraggableHandler(PApplet app) | |
{ | |
draggables = new ArrayList<Draggable>(); | |
currentDragged = null; | |
app.registerMethod("draw", this); | |
app.registerMethod("mouseEvent", this); | |
} | |
void addToEnd(Draggable d) | |
{ | |
draggables.add(d); | |
} | |
void addToFront(Draggable d) | |
{ | |
draggables.add(0, d); //add to index 0, shift all others | |
} | |
void remove(Draggable d) | |
{ | |
draggables.remove(d); | |
} | |
Draggable get(int index) | |
{ | |
return draggables.get(index); | |
} | |
void toggleConstraints() | |
{ | |
for(int i=0;i<draggables.size();i++) | |
{ | |
draggables.get(i).toggleConstraints(); | |
} | |
} | |
void display() | |
{ | |
for (int i=draggables.size()-1;i>=0;i--) //draw backwards so first will be on top | |
{ | |
draggables.get(i).display(); | |
} | |
} | |
public void draw() //this draw is automatically called at the end of each draw() | |
{ | |
for (int i=0;i<draggables.size();i++) | |
{ | |
draggables.get(i).update(); | |
} | |
} | |
public void mouseEvent(MouseEvent event) | |
{ | |
int x = event.getX(); | |
int y = event.getY(); | |
switch (event.getAction()) { | |
case MouseEvent.PRESS: | |
// choose top draggable to drag if clicked on | |
if (currentDragged == null) | |
{ | |
for (int i=0;i<draggables.size();i++) | |
{ | |
if (draggables.get(i).isOver(x, y)) | |
{ | |
currentDragged = draggables.get(i); | |
currentDragged.setDragged(x, y); | |
break; | |
} | |
} | |
} | |
break; | |
case MouseEvent.RELEASE: | |
// release any dragged objects | |
if (currentDragged != null) | |
{ | |
currentDragged.releaseDragged(); | |
currentDragged = null; | |
} | |
break; | |
case MouseEvent.CLICK: | |
// | |
break; | |
case MouseEvent.DRAG: | |
// | |
break; | |
case MouseEvent.MOVE: | |
// | |
break; | |
} | |
} | |
} | |
void mouseDragged() | |
{ | |
println(); | |
println(codeString); | |
} | |
void keyPressed() | |
{ | |
if(key == ' ') | |
{ | |
points.toggleConstraints(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
good