Finding polygons – the code

// kind of extensions to classes TPoint and Tiling

// show points without polygons
//-----------------------------------------------------------------------------------

void tilingShowPointsWithoutPolygons(){  
  for (int i=0;i<tiling.points.length;i++){
    if (tiling.points[i].connections.length<2) tiling.points[i].vec.show();
  }
}

// show regular polygons
//-----------------------------------------------------------------------------------

void tilingShowRegularPolygons(int numberCorners){         //  regular polygons with given number of corners
  float angle=PI*(1-2./numberCorners);
      for (int i=0;i<tiling.points.length;i++){
      pointShowPolygons(tiling.points[i],angle);
    }
}

void pointShowPolygons(TPoint start,float angle){
  if (start.connections.length<2) return;
  // search for the polygons
  int out,in;
  for(in=0;in<start.connections.length;in++){
    out=in-1;
    if (out<0) out=start.connections.length-1;
    if(start.above(start.connections[in])&&start.above(start.connections[out])&&
    equalAngles(start.angles[in]-start.angles[out],angle)) tryPolygon(start,start.connections[out],angle);
  }
}

//  test if we are at a regular polygon ... and draw it
void tryPolygon(TPoint start,TPoint nextStart,float deltaAngleMust){
  Vector[] corners=new Vector[1];
  corners[0]=start.vec;
  TPoint next,now,newNext;
  now=start;
  next=nextStart;
  while (next!=start){
    newNext=nextConnection(now,next,deltaAngleMust);
    if(newNext==null) return;
    corners=(Vector[])append(corners,next.vec);
    now=next;
    next=newNext;
  }
  showPolygon(corners);
}

//  show rhombs
//-------------------------------------------------------------------------------

void tilingShowRhombs(float acuteAngle){         //  regular polygons with given number of corners
      for (int i=0;i<tiling.points.length;i++){
      pointShowRhombs(tiling.points[i],acuteAngle);
    }
}

void pointShowRhombs(TPoint start,float angle){
  if (start.connections.length<2) return;
  // search for the polygons
  int out,in;
  for(in=0;in<start.connections.length;in++){
    out=in-1;
    if (out<0) out=start.connections.length-1;
    if(equalAngles(start.angles[in]-start.angles[out],angle)) tryRhomb(start,start.connections[out],angle);
  }
}

// test if we are at a rhomb, and draw it
void tryRhomb(TPoint start,TPoint nextStart,float deltaAngleMust){
  Vector[] corners=new Vector[4];
  corners[0]=start.vec;
  TPoint next,now,newNext;
  now=start;
  next=nextStart;
// obtuse angle
  newNext=nextConnection(now,next,PI-deltaAngleMust);
  if(newNext==null) return;
//  newNext is corner opposed to start, with acute angle
  if (start.above(newNext)) return;
  corners[1]=next.vec;
  corners[2]=newNext.vec;
  now=next;
  next=newNext;
  newNext=nextConnection(now,next,deltaAngleMust);
  if(newNext==null) return;
//got second corner with obtuse angle
  corners[3]=newNext.vec;
  // test last angle
  now=next;
  next=newNext;
  newNext=nextConnection(now,next,PI-deltaAngleMust);
  if(newNext!=start) return;
  showPolygon(corners);
}

TPoint nextConnection(TPoint from,TPoint now,float deltaAngleMust){
  TPoint nothing=null;
  int iFrom=0,iNext;
  float deltaAngle;
  // find connection to the point we are coming from
  if(now.connections.length<2) return nothing;      //  no polygon possible
  while (now.connections[iFrom]!=from){              // search connection going back
    iFrom++;
  }
  // now take next connection at the left
  iNext=iFrom-1;
  if (iFrom==0) iNext=now.connections.length-1;
  //  test for correct angle at corner
  if(equalAngles(now.angles[iFrom]-now.angles[iNext],deltaAngleMust)) return now.connections[iNext];
  return nothing;                //  wrong angle - no regular polynom
}

//--------------------------------------------------------------------------------

void showPolygon(Vector[] corners){
  beginShape();
  for (int i=0;i<corners.length;i++){
    vertex(corners[i].x,corners[i].y);
  }
  endShape(CLOSE);
}

// map angle into -PI,+PI
float mapAngle(float angle){
  if (angle>=PI) return mapAngle(angle-TWO_PI);
  if (angle<-PI) return mapAngle(angle+TWO_PI);
  return angle;
}

//  compare angles( modulo 2*PI=TWO_PI)
boolean equalAngles(float one, float two){
  return (abs(mapAngle(one-two))<small);
}
This entry was posted in programming, Quasiperiodic design and tagged , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s