Skip to content

Instantly share code, notes, and snippets.

@nataliefreed
Created October 2, 2014 02:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nataliefreed/5e0904dd3e90f48dd985 to your computer and use it in GitHub Desktop.
Save nataliefreed/5e0904dd3e90f48dd985 to your computer and use it in GitHub Desktop.
//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();
}
}
@SZooo
Copy link

SZooo commented Oct 2, 2014

good

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment