// do some stuff // Convert pattern to stars, using something like the Hankin method. // To do: add line separation... Vector polys; boolean isInteractive = false; // turn off when you've found a good ratio for this tiling... float minx=10000, maxx=-10000, miny=10000, maxy=-10000; float dxs = 1; float dys = 1; float lm = 10; float tm = 10; float ratio = 1; float angStar = (2*PI)/18; // 30 degrees float edgeDist = .1; float starEdge = 1000; void setup() { size(600,600); colorMode(RGB, 1); smooth(); strokeWeight(2); // noLoop(); polys = new Vector(); ReadFile("altair1.txt"); } void draw() { angStar = .001 + (float) mouseX/width*PI; edgeDist = (float) mouseY/height; // println("angstar = " + angStar + " lm = " + lm); // println("ratio = " + ratio); // } background(.5); for (int i = 0; i < polys.size(); ++i) { Poly poly = (Poly) polys.elementAt(i); poly.doDraw(); } } void ReadFile(String vFileName) { Vector vipts = new Vector(); String lines[] = loadStrings(vFileName); for (int i = 0; i < lines.length; ++i) { if (lines[i].length() < 3) continue; String nums[] = lines[i].split(","); for (int j = 0; j < nums.length; ++j) { if (nums[j].substring(0,1).equals(" ")) nums[j] = nums[j].substring(1); if (nums[j].length() > 0) vipts.addElement(new Float(float(nums[j]))); } } polys = new Vector(); float[] ipts; ipts = new float[vipts.size()]; println("loaded " + vipts.size() + " points"); for (int i = 0; i < vipts.size(); ++i) { ipts[i] = ((Float) vipts.elementAt(i)).floatValue(); } for (int i = 0; i < vipts.size(); ) { int nbrSides = (int) ipts[i++]; Poly poly = new Poly(nbrSides); for (int j = 0; j < nbrSides; ++j) { poly.AddDot(ipts[i+j*2],ipts[i+j*2+1]); } i += nbrSides*2; polys.addElement(poly); } println("loaded " + polys.size() + " polys"); dxs = (width-lm*2)/(float)(maxx-minx); dys = (height-tm*2)/(float)(maxy-miny); } class Point { float x,y; Point(float x, float y) { this.x = x; this.y = y; if (x < minx) minx = x; if (x > maxx) maxx = x; if (y < miny) miny = y; if (y > maxy) maxy = y; } } // this crashes in certain situations... Point intersection(float x1,float y1,float x2,float y2, float x3, float y3, float x4,float y4 ) { float d = (x1-x2)*(y3-y4) - (y1-y2)*(x3-x4); try { // float xi = ((x3-x4)*(x1*y2-y1*x2)-(x1-x2)*(x3*y4-y3*x4))/d; // float yi = ((y3-y4)*(x1*y2-y1*x2)-(y1-y2)*(x3*y4-y3*x4))/d; float denom = (y4-y3)*(x2-x1) - (x4-x3)*(y2-y1); float numea = (x4-x3)*(y1-y3) - (y4-y3)*(x1-x3); float numeb = (x2-x1)*(y1-y3) - (y2-y1)*(x1-x3); if (abs(denom) < 0.01) { if (numea == 0.0 && numeb == 0.0) { // coincident println("c"); return new Point ( x1, y1 ); } else { // parallel println("p"); return null; } } float ua = numea / denom; float ub = numeb / denom; if (ua >= 0.0f && ua <= 1.0f && ub >= 0.0f && ub <= 1.0f) { float xi = x1 + ua*(x2-x1); float yi = y1 + ua*(y2-y1); if (xi > 0 && xi < width && yi > 0 && yi < width) return new Point(xi,yi); else return null; } else { // not intersecting - this works well... return new Point (x1, y1 ); } } catch (Exception e) { println("e"); return null; } } class Poly { Vector pts; int nbrSides; Poly(int nbrSides) { this.nbrSides = nbrSides; this.pts = new Vector(); } void AddDot(float x, float y) { pts.add( new Point(x,y) ); } void doDraw() { if (outsideBorder()) { fill(.5); return; } else fill(1); float r = sin(nbrSides*PI*2/8.0); float g = sin(nbrSides*PI*2/8.0+2); float b = sin(nbrSides*PI*2/8.0+4); fill (.9+r*.1, .9+g*.1, .9+b*.1); stroke(.8+r*.1, .8+g*.1, .8+b*.1); String outStr = nbrSides +","; beginShape(); for (int i = 0; i <= nbrSides; ++i) { Point pt = (Point) pts.elementAt(i % nbrSides); vertex( tx(pt.x), ty(pt.y) ); if (i < nbrSides) outStr += pt.x + "," + pt.y + ","; } endShape(); // println(outStr); stroke(0); float cx = 0; float cy = 0; for (int i = 0; i < nbrSides; ++i) { Point pt = (Point) pts.elementAt(i % nbrSides); cx += tx(pt.x); cy += ty(pt.y); } cx /= nbrSides; cy /= nbrSides; for (int i = 0; i < nbrSides; ++i) { Point p1 = (Point) pts.elementAt(i % nbrSides); Point p2 = (Point) pts.elementAt((i+1) % nbrSides); Point p3 = (Point) pts.elementAt((i+2) % nbrSides); // Draw segment that starts at midpoint of p2,p1 and goes at angle p2,p1 + (PI-angStar)/2 // to the point where it intersects segment that starts at midpoint of p2,p3 and goes at angle p2,p3-(PI-angStar)/2 float mx1 = (p1.x + p2.x)/2; float my1 = (p1.y + p2.y)/2; mx1 += (p1.x - p2.x)*edgeDist; my1 += (p1.y - p2.y)*edgeDist; float mx2 = (p3.x + p2.x)/2; float my2 = (p3.y + p2.y)/2; mx2 += (p3.x - p2.x)*edgeDist; my2 += (p3.y - p2.y)*edgeDist; float ang1 = atan2(p2.y-p1.y,p2.x-p1.x) + (PI-angStar)/2; float ang2 = atan2(p2.y-p3.y,p2.x-p3.x) - (PI-angStar)/2; float ex1 = mx1+cos(ang1)*starEdge; float ey1 = my1+sin(ang1)*starEdge; float ex2 = mx2+cos(ang2)*starEdge; float ey2 = my2+sin(ang2)*starEdge; Point ip = intersection(mx1,my1,ex1,ey1,mx2,my2,ex2,ey2); if (ip == null) continue; line(tx(mx1),ty(my1), tx(ip.x), ty(ip.y)); line(tx(mx2),ty(my2), tx(ip.x), ty(ip.y)); // Find point where these lines intersect, and draw line from mx1,my1 ix,iy and mx2,my2,ix,iy } } boolean outsideBorder() { float cx = 0; float cy = 0; for (int i = 0; i < nbrSides; ++i) { Point pt = (Point) pts.elementAt(i % nbrSides); cx += tx(pt.x); cy += ty(pt.y); } cx /= nbrSides; cy /= nbrSides; float dx = cx - width/2; float dy = cy - height/2; return sqrt(dx*dx + dy*dy) > ratio*width/2 ; } } float tx(float x) { return (x - minx)*dxs + lm; } float ty(float y) { return (y - miny)*dys + tm; } void myLine(float x1, float y1, float x2, float y2) { line(tx(x1),ty(y1),tx(x2),ty(y2)); }