fullscreen // 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));
}
Move the mouse horizontally and vertically to change the image. X and Y control two different parameters.
This was an experiment with a method used to produce Arabic/Islamic star tiling patterns, from an underlying grid of polygons.
Starting with an underlying grid of polygons, the star pattern is produced by drawing lines from two equidistant points on each polygon edge at some fixed angle (controlled by the mouse). At the point where the lines would intersect with other lines, they are clipped.
Y controls the distance from the center of the polygon edge.
X controls angle.
Paola