class LazyFont { Node[] nodes = new Node[0]; PVector[] originalPositions = new PVector[0]; Spring[] springs = new Spring[0]; int endurance_cnt = 0; int endurance_limit = 40; int node_num = 0; int pos_x = 0; int pos_y = 0; float min_x = 0; float min_y = 0; float max_x = width; float max_y = height; float w = -1; float h = -1; PVector offset = new PVector(); String theChar; public LazyFont(String theChar) { this.theChar = theChar; } void init() { //RCommand.setSegmentStep(11); //RCommand.setSegmentator(RCommand.UNIFORMSTEP); RCommand.setSegmentLength(segmentLength); //RCommand.setSegmentator(RCommand.UNIFORMLENGTH); //RCommand.setSegmentAngle(random(0,HALF_PI/6)); //RCommand.setSegmentator(RCommand.ADAPTATIVE); RGroup grp; grp = font.toGroup(theChar); //grp = grp.toPolygonGroup(); //pnts = grp.getPoints(); endurance_cnt = 0; min_x = Float.MAX_VALUE; min_y = Float.MAX_VALUE; max_x = -Float.MAX_VALUE; max_y = -Float.MAX_VALUE; //nodes = new Node[grp.getPoints().length]; nodes = new Node[0]; println("grp.getPoints().length = " + grp.getPoints().length); // init nodes float rad = nodeDiameter/2; node_num = 0; springs = new Spring[0]; int tmpNodeIndex = 0; Node newNode; PVector originalPos; for ( int i = 0; i < grp.elements.length; i++ ) { RShape shp = grp.elements[i].toShape(); for ( int j = 0; j < shp.paths.length; j++ ) { RPath sushp = shp.paths[j]; RPoint[] pnts = sushp.getPoints(); println("---" + pnts.length); for ( int k = 0; k < pnts.length-1; k++ ) { if(k ==0) tmpNodeIndex = node_num; fill(0, 221, 255); stroke(0); newNode = new Node(pnts[k].x + pos_x, (int)pnts[k].y + pos_y); newNode.setBoundary(rad, rad, width-rad, height-rad); newNode.setRadius(50); newNode.setStrength(-2); nodes = (Node[]) append(nodes, newNode); originalPos = new PVector(pnts[k].x + pos_x, (int)pnts[k].y + pos_y, 0); originalPositions = (PVector[])append(originalPositions, originalPos); if(nodes[node_num].x > max_x) max_x = (int)nodes[node_num].x; if(nodes[node_num].y > max_y) max_y = (int)nodes[node_num].y; if(nodes[node_num].x < min_x) min_x = (int)nodes[node_num].x; if(nodes[node_num].y < min_y) min_y = (int)nodes[node_num].y; w = max_x - min_x; h = max_y - min_y; Spring newSpring; if (k > 0) { newSpring = new Spring(nodes[node_num], nodes[node_num-1]); newSpring.setLength(springLength); newSpring.setStiffness(stiffness); springs = (Spring[]) append(springs, newSpring); } if(k == pnts.length-2) { newSpring = new Spring(nodes[node_num], nodes[tmpNodeIndex]); newSpring.setLength(springLength); newSpring.setStiffness(stiffness); springs = (Spring[]) append(springs, newSpring); } node_num++; } } } //println("node_num" + node_num); } float getWidth() { return w; } void draw() { // draw nodes strokeWeight(0.8); if(monochrome) { stroke(0); } else { stroke(0, 221, 255); } if(isShowPath) { for (int i = 0 ; i < springs.length; i++) { line(springs[i].fromNode.x, springs[i].fromNode.y, springs[i].toNode.x, springs[i].toNode.y); } } if(isShowNode) { textSize(9); noStroke(); for (int i = 0 ; i < node_num; i++) { if(monochrome) { fill(0); } else { fill(color(255, 0, 0)); } //text("" + i, nodes[i].x + 4, nodes[i].y); ellipse(nodes[i].x, nodes[i].y, nodeDiameter, nodeDiameter); fill(0); } } if(isDrawCharBound) { stroke(204, 102, 0); noFill(); rect(min_x, min_y, w, h); } } void update() { if(animating) { PVector diff; float dist; boolean convergence = true; for (int i = 0 ; i < node_num; i++) { diff = PVector.sub(originalPositions[i], (PVector)nodes[i]); dist = PVector.dist(originalPositions[i], (PVector)nodes[i]); nodes[i].x += diff.x * 0.3; nodes[i].y += diff.y * 0.3; if(dist > 0.5) { convergence = false; } } if(convergence) { animating = false; endurance_cnt = 0; } } else { if(endurance_cnt > endurance_limit) { for (int i = 0 ; i < node_num; i++) { nodes[i].attract(nodes); } for (int i = 0 ; i < springs.length; i++) { springs[i].update(); } for (int i = 0 ; i < node_num; i++) { nodes[i].update(); } if (selectedNode != null) { selectedNode.x = mouseX; selectedNode.y = mouseY; } } endurance_cnt++; } } void setPos(int _x, int _y) { this.pos_x = _x; this.pos_y = _y; } void findNode() { float maxDist = 20; for (int i = 0; i < nodes.length; i++) { Node checkNode = nodes[i]; float d = dist(mouseX, mouseY, checkNode.x, checkNode.y); if (d < maxDist) { selectedNode = checkNode; maxDist = d; } } } Node getNodeByScreenPos(float theX, float theY) { float mx = theX-width/2; float my = theY-height/2; return getNodeByPos(mx, my); } Node getNodeByPos(float theX, float theY) { float maxDist = 20; Node selectedNode = null; for (int i = 0; i < nodes.length; i++) { Node checkNode = nodes[i]; float d = dist(mouseX, mouseY, checkNode.x, checkNode.y); if (d < maxDist) { selectedNode = checkNode; maxDist = d; } } return selectedNode; } void setSpringLength(float theLength) { for (int i = 0 ; i < springs.length; i++) { springs[i].setLength(theLength); } } void setSpringStiffness(float theStiffness) { for (int i = 0 ; i < springs.length; i++) { springs[i].setStiffness(stiffness); } } }