import traer.physics.*; float SPRING_CONSTANT = 1.0; float DAMP_CONSTANT = 0.0; float TIME_STEP = 0.1; float GLOBAL_DAMP_CONSTANT = 1.5; int NUM_ANCHOR_POINTS = 10; int MAX_NUM_POINTS = 10000; int NUM_FIT_POINTS = 50; ParticleSystem physics; PVector[] points; int numPoints = 0; int lastPoint = 0; MultiBezier mBezier; boolean drawCurve = true; boolean editCurve = false; boolean dispXEnabled = false; boolean dispYEnabled = false; boolean rotEnabled = false; boolean showInfo = false; Anchors anchors; PFont font; String str1 = "This program allows you to draw a line that is automatically converted into a spline representation using the " + "same algorithm as in Inkscape's freehand mode.\n\n"; String str2 = "The blue circles are anchor points the line can be attached to. Just pass the line through them to attach.\n\n"; String str3 = "Once the line it has been drawn, the anchor points can moved around one by one (by cliking and dragging them), " + "or using predetermied animation modes (horizontal/vertical displacement and rotation around the center of the screen).\n\n"; String str4 = "The anchor and control points of the line can also be moved around by clicking and dragging them.\n\n"; String str5 = " resets the drawing.\n"; String str6 = "<1> enables/disables anchor points motion from left to rigth.\n"; String str7 = "<2> enables/disables anchor points motion from top to bottom.\n"; String str8 = "<3> enables/disables anchor points rotation around the center of the screen.\n"; void setup() { size(800, 600); smooth(); physics = new ParticleSystem(0, GLOBAL_DAMP_CONSTANT); anchors = new Anchors(); points = new PVector[MAX_NUM_POINTS]; numPoints = 0; mBezier = new MultiBezier(); font = loadFont("BrowalliaNew-24.vlw"); textFont(font); noFill(); } void draw() { background(0); physics.tick(TIME_STEP); if (dispXEnabled) anchors.displaceX(); if (dispYEnabled) anchors.displaceY(); if (rotEnabled) anchors.rotateAroundScreenCenter(); anchors.render(); mBezier.update(); mBezier.render(editCurve); if (drawCurve) { stroke(255); PVector p0 = 0 < lastPoint ? points[lastPoint - 1] : null; for (int i = lastPoint; i < numPoints; i++) { PVector p = points[i]; if (p0 != null) line(p0.x, p0.y, p.x, p.y); p0 = p; } } println(frameRate); if (showInfo) { noStroke(); fill(255, 50); rect(5, 5, width - 10, 0.5 * height); fill(255); text(str1 + str2 + str3 + str4 + str5 + str6 + str7 + str8 , 10, 30, width - 10, 0.5 * height); text("Press any key to put this information away.", 10, height - 30); } else { fill(255); text("Press ENTER for some information.", 10, height - 30); } } void mouseReleased() { if (showInfo) { showInfo = false; return; } if (drawCurve) { if (lastPoint < numPoints - 1) { mBezier.addPoints(points, lastPoint, numPoints - lastPoint); lastPoint = numPoints - 1; } mBezier.setupAnchors(anchors.points); drawCurve = false; } } void keyPressed() { if (showInfo) { showInfo = false; return; } if (key == BACKSPACE) { mBezier.clear(); anchors.clear(); numPoints = 0; lastPoint = 0; drawCurve = true; editCurve = false; } else if ((key == ENTER) || (key == RETURN)) { showInfo = !showInfo; } else if (key == '1') { dispXEnabled = !dispXEnabled; } else if (key == '2') { dispYEnabled = !dispYEnabled; } else if (key == '3') { rotEnabled = !rotEnabled; } else editCurve = !editCurve; } void mouseDragged() { if (showInfo) { showInfo = false; return; } if (drawCurve) addPoint(mouseX, mouseY); else { anchors.setSelectedPoint(mouseX, mouseY); if (editCurve) mBezier.setSelectedPoint(mouseX, mouseY); } } void mousePressed() { if (showInfo) { showInfo = false; return; } if (drawCurve) addPoint(mouseX, mouseY); else { boolean sel = anchors.selectPoint(mouseX, mouseY, 20); if (sel) return; if (editCurve) { boolean res = mBezier.selectPoint(mouseX, mouseY, 10); if (!res) editCurve = false; } else editCurve = true; } } void addPoint(float x, float y) { if (numPoints < MAX_NUM_POINTS) { if (points[numPoints] != null) points[numPoints].set(x, y, 0); else points[numPoints] = new PVector(x, y); numPoints++; int idx = anchors.getAnchorIndex(points[numPoints - 1], 10); if (-1 < idx) mBezier.addAnchor(idx); if (numPoints - lastPoint >= NUM_FIT_POINTS) { mBezier.addPoints(points, lastPoint, numPoints - lastPoint); lastPoint = numPoints - 1; } } }