Drawing regular polygons

edited July 2014 in Share Your Work

Hi:

There are probably other ways of doing this; but I wrote this simple sketch to draw regular polygons and wanted to share it with you. They look better when run in P1.5.1. Let me know if you have any suggestions or find any problems.

Hope its useful for others.

Thanks.

final int minNumberOfSides=3;
final int maxNumberOfSides=10;

void setup()
{
  size(1300, 600);
  background(0);
}

void draw()
{
  float radio=70;
  for (int k=minNumberOfSides;k<maxNumberOfSides+1;k++)
  {
    int numberOfSides=k;
    float centerPositionX=(k-minNumberOfSides+1)*2.2*radio-radio/2;
    float centerPositionY=height/2;
    drawPolygon(radio, centerPositionX, centerPositionY, numberOfSides);
  }
}

void drawPolygon(float radio, float centerPositionX, float centerPositionY, int numberOfSides)
{  
  numberOfSides=constrain(numberOfSides, minNumberOfSides, maxNumberOfSides);
  float sideAngle=TWO_PI/numberOfSides;
  float halfSideLineLength=sin(sideAngle/2)*radio;
  float lineY=cos(sideAngle/2)*radio;
  strokeWeight(1);
  stroke(255); 
  for (int i=0;i<numberOfSides;i++)
  {    
    pushMatrix();
    translate(centerPositionX, centerPositionY);    
    rotate(i*sideAngle); 
    line(-halfSideLineLength, -lineY, halfSideLineLength, -lineY);    
    //line(0,0, halfSideLineLength, -lineY);
    popMatrix();
  }
  //fill(255);
  //ellipse(centerPositionX, centerPositionY,4,4);
  //noFill();
  //ellipse(centerPositionX, centerPositionY,2*radio,2*radio);
}

Comments

  • _vk_vk
    edited July 2014

    Cool! Once I made a similar function, look:

    void setup() {
      size(800, 800);
      frameRate(4);
    }
    void draw() {
    background(0);
      fill(255);
      int sides = 2 + frameCount/5;
    
      // makeSides(int sides, int magnitude);
      makeShape(sides, 100);
    
      println(sides + " sides");
    }
    
    
    void makeShape(int sides, int size) {
      sides = sides >= 3? sides:3;
    
      float slice = TWO_PI/(float) sides;
    
      float[] angles = new float [sides];
    
      for (int i = 0; i < angles.length; i++ ) {
        angles[i] =  i*slice;
      }  
    
    
    
      PVector[] vtx = new PVector[sides];
      for (int i = 0; i < vtx.length; i++ ) {
        vtx[i] = new PVector(cos(angles[i])*size, sin(angles[i])*size);
      }
    
    
      translate(width/2, height/2);
      beginShape();
    
      for (int i = 0; i < vtx.length; i++ ) {
        vertex(vtx[i].x, vtx[i].y);
      }
    
      endShape(CLOSE);
    }
    
  • Yeah, I see yours is pretty cool. Thanks

  • Excellent.

  • Trig is cool, isn't it : )

  • Oh yeah, I love it.

  • edited July 2014

    For the curious processor65's program output looks thus:

    polygons

  • @ jas0501 thanks for the picture

    Its better to clear the background at the beginning of each loop(), therefore background(0); should be in void draw() and not void setup(). Sorry.

    like this:

    final int minNumberOfSides=3;
    final int maxNumberOfSides=10;
    
    void setup()
    {
      size(1300, 600);
     }
    
    void draw()
    {
      background(0);
      float radio=70;
      for (int k=minNumberOfSides;k<maxNumberOfSides+1;k++)
      {
        int numberOfSides=k;
        float centerPositionX=(k-minNumberOfSides+1)*2.2*radio-radio/2;
        float centerPositionY=height/2;
        drawPolygon(radio, centerPositionX, centerPositionY, numberOfSides);
      }
    }
    
    void drawPolygon(float radio, float centerPositionX, float centerPositionY, int numberOfSides)
    {  
      numberOfSides=constrain(numberOfSides, minNumberOfSides, maxNumberOfSides);
      float sideAngle=TWO_PI/numberOfSides;
      float halfSideLineLength=sin(sideAngle/2)*radio;
      float lineY=cos(sideAngle/2)*radio;
      strokeWeight(1);
      stroke(255); 
      for (int i=0;i<numberOfSides;i++)
      {    
        pushMatrix();
        translate(centerPositionX, centerPositionY);    
        rotate(i*sideAngle); 
        line(-halfSideLineLength, -lineY, halfSideLineLength, -lineY);    
        //line(0,0, halfSideLineLength, -lineY);
        popMatrix();
      }
      //fill(255);
      //ellipse(centerPositionX, centerPositionY,4,4);
      //noFill();
      //ellipse(centerPositionX, centerPositionY,2*radio,2*radio);
    }
    
  • The output looks better now: image

  • those thick lines on the first one were due to accumulation of alpha - you'll notice that the horizontal and vertical lines aren't affected.

    http://wiki.processing.org/w/Why_are_text_and_graphics_so_ugly_and_blocky?

    the fix is, as you've realised, to call background() in draw()

    BUT there's no point constantly redrawing an image that doesn't change - add noLoop() after line 19.

  • @processor65 - what is more interesting than the shapes is the algorithm you used to draw them.

    If I had been asked to do this I would have used trig to calculate the vertices and then drawn lines between. @_vk also calculated the vertices but used vertex() to define the shape.

    Your approach of using the transformation matrix is a powerful technique and a useful one to learn, so well done.

    You might be interested to know that we can reduce the number of push/pop matrices to just one per polygon, this is shown below.

    void drawPolygon(float radio, float centerPositionX, float centerPositionY, int numberOfSides)
    { 
      numberOfSides=constrain(numberOfSides, minNumberOfSides, maxNumberOfSides);
      float sideAngle=TWO_PI/numberOfSides;
      float halfSideLineLength=sin(sideAngle/2)*radio;
      float lineY=cos(sideAngle/2)*radio;
      strokeWeight(1);
      stroke(255);
      pushMatrix();
      translate(centerPositionX, centerPositionY);   
      for (int i=0; i<numberOfSides; i++)
      {   
        rotate(sideAngle); // incremental rotation
        line(-halfSideLineLength, -lineY, halfSideLineLength, -lineY);   
      }
      popMatrix();
    }
    
  • Hi: Thanks to all for your great replies.

    @koogs Yes you are right there is no point in drawing the same thing over and over. That was the reason I forgot background(0) in void setup() as I was drawing everything there only once. Then I moved it to void draw() and forgot clearing the background. I decided to move it there because if this is going to be used for real its most likely to be together with other drawings and buttons, etc. Good point yours anyways. Thanks

    @quarks Thanks, that was my real interest, to share the algorithm. I tried your approach of using push and popMatrix() only once and could not make it work as I was trying to rotate the polygons. Please take a look at what happens with that approach when trying to rotate the polygons with the mouse using your suggestion. I don't know why??

    final int minNumberOfSides=3;
    final int maxNumberOfSides=10;
    float rotationAngle;
    
    void setup()
    {
      size(1300, 600);
    }
    
    void draw()
    {
      background(0);
      float radio=70;
      float rotationAngle=map(mouseX, 0, width, 0, TWO_PI ); 
      for (int k=minNumberOfSides;k<maxNumberOfSides+1;k++)
      {
        int numberOfSides=k;
        float centerPositionX=(k-minNumberOfSides+1)*2.2*radio-radio/2;
        float centerPositionY=height/2;
        drawPolygon(radio, centerPositionX, centerPositionY, numberOfSides, rotationAngle);
      }
    }
    
    void drawPolygon(float radio, float centerPositionX, float centerPositionY, int numberOfSides, float rotationAngle)
    { 
      numberOfSides=constrain(numberOfSides, minNumberOfSides, maxNumberOfSides);
      float sideAngle=TWO_PI/numberOfSides;
      float halfSideLineLength=sin(sideAngle/2)*radio;
      float lineY=cos(sideAngle/2)*radio;
      strokeWeight(1);
      stroke(255);
      pushMatrix();
      translate(centerPositionX, centerPositionY);   
      for (int i=0; i<numberOfSides; i++)
      {   
        rotate(sideAngle+rotationAngle); // incremental rotation
        line(-halfSideLineLength, -lineY, halfSideLineLength, -lineY);
        if (mousePressed)
        { 
          line(0, 0, halfSideLineLength, -lineY);
        }
      }
      popMatrix();
      if (mousePressed)
      {
        fill(255);
        ellipse(centerPositionX, centerPositionY, 4, 4);
        noFill();
        ellipse(centerPositionX, centerPositionY, 2*radio, 2*radio);
      }
      textAlign(CENTER);
      fill(255);
      textSize(15);
      text("Move mouse sideways to see rotation. Press mouse to see additions", width/2, 100);
    }
    
  • While using my original approach of multiple transformations it works fine. Does anybody knows why?

    final int minNumberOfSides=3;
    final int maxNumberOfSides=10;
    
    void setup()
    {
      size(1300, 600);
    }
    
    void draw()
    {
      background(0);
      float radio=70;
      float rotationAngle=map(mouseX, 0, width, 0, TWO_PI );  
      for (int k=minNumberOfSides;k<maxNumberOfSides+1;k++)
      {
        int numberOfSides=k;
        float centerPositionX=(k-minNumberOfSides+1)*2.2*radio-radio/2;
        float centerPositionY=height/2;
        drawPolygon(radio, centerPositionX, centerPositionY, numberOfSides, rotationAngle);
      }
    }
    
    void drawPolygon(float radio, float centerPositionX, float centerPositionY, int numberOfSides, float rotationAngle)
    {  
      numberOfSides=constrain(numberOfSides, minNumberOfSides, maxNumberOfSides);
      float sideAngle=TWO_PI/numberOfSides;
      float halfSideLineLength=sin(sideAngle/2)*radio;
      float lineY=cos(sideAngle/2)*radio; 
      strokeWeight(1);
      stroke(255); 
      for (int i=0;i<numberOfSides;i++)
      {    
        pushMatrix();
        translate(centerPositionX, centerPositionY);    
        rotate(i*sideAngle+rotationAngle); 
        line(-halfSideLineLength, -lineY, halfSideLineLength, -lineY);
        if (mousePressed)
        { 
          line(0, 0, halfSideLineLength, -lineY);
        }   
        popMatrix();
      }
      if (mousePressed)
      {
        fill(255);
        ellipse(centerPositionX, centerPositionY, 4, 4);
        noFill();
        ellipse(centerPositionX, centerPositionY, 2*radio, 2*radio);
      }
      textAlign(CENTER);
      fill(255);
      textSize(15);
      text("Move mouse sideways to see rotation. Press mouse to see additions", width/2, 100);
    }
    
  • I think its because of the way in which the event mousePressed(); is treated in the software; but not sure.

  • Humm. Actually no because the rotation has nothing to do with mousePressed...

  • edited July 2014

    Botton line is the rotationAngle is not applied equally to all sides except for 0 and TWO_PI using only one push and popMatrix().

  • @goToLoop What I have done before was; but perhaps your suggestion is better???

    void setup() { drawFigures(); }

    void draw() {} // do noting;

  • You only need to apply the rotation angle before the loop not inside it.

    void drawPolygon(float radio, float centerPositionX, float centerPositionY, int numberOfSides, int rotationAngle)
    {
      numberOfSides=constrain(numberOfSides, minNumberOfSides, maxNumberOfSides);
      float sideAngle=TWO_PI/numberOfSides;
      float halfSideLineLength=sin(sideAngle/2)*radio;
      float lineY=cos(sideAngle/2)*radio;
      strokeWeight(1);
      stroke(255);
      pushMatrix();
      translate(centerPositionX, centerPositionY);  
      rotate(rotationAngle);
      for (int i=0; i<numberOfSides; i++)
      {  
        rotate(sideAngle); // incremental rotation
        line(-halfSideLineLength, -lineY, halfSideLineLength, -lineY);  
      }
      popMatrix();
    }
    
  • yes, true. Thanks.

  • edited July 2014

    Corrections made thanks to quarks. Here it is:

    final int minNumberOfSides=3;
    final int maxNumberOfSides=10;
    float rotationAngle;
    
    void setup()
    {
      size(1300, 600);
      textAlign(CENTER);
    }
    
    void draw()
    {
      background(0);
      float radio=70;
      float rotationAngle=map(mouseX, 0, width, 0, TWO_PI ); 
      for (int k=minNumberOfSides;k<maxNumberOfSides+1;k++)
      {
        int numberOfSides=k;
        float centerPositionX=(k-minNumberOfSides+1)*2.2*radio-radio/2;
        float centerPositionY=height/2;
        drawPolygon(radio, centerPositionX, centerPositionY, numberOfSides, rotationAngle);
      }
    }
    
    void drawPolygon(float radio, float centerPositionX, float centerPositionY, int numberOfSides, float rotationAngle)
    {
      numberOfSides=constrain(numberOfSides, minNumberOfSides, maxNumberOfSides);
      float sideAngle=TWO_PI/numberOfSides;
      float halfSideLineLength=sin(sideAngle/2)*radio;
      float lineY=cos(sideAngle/2)*radio;
      strokeWeight(1);
      stroke(255);
      pushMatrix();
      translate(centerPositionX, centerPositionY);  
      rotate(rotationAngle);
      for (int i=0; i<numberOfSides; i++)
      {  
        rotate(sideAngle); // incremental rotation
        line(-halfSideLineLength, -lineY, halfSideLineLength, -lineY);
        if (mousePressed)
        { 
          line(0, 0, halfSideLineLength, -lineY);
        }
      }
      popMatrix();
      if (mousePressed)
      {
        fill(255);
        ellipse(centerPositionX, centerPositionY, 4, 4);
        noFill();
        ellipse(centerPositionX, centerPositionY, 2*radio, 2*radio);
      }
      fill(255);
      textSize(15);
      text("Move mouse sideways to see rotation. Press mouse to see additions", width/2, 100);
    }
    
  • edited July 2014

    And here is the output with some additions: Thanks to all. DrawingPolygonsFinal

  • By drawing triangles instead of lines the polygons can be filled. The junction lines can be seeing a little bit though. I tried strokeWeight(2); the lines disappear; but the corners overshoot a bit. Here is the example with strokeWeight(1);

    final int minNumberOfSides=3;
    final int maxNumberOfSides=10;
    float rotationAngle;
    
    void setup()
    {
      size(1300, 600);
      textAlign(CENTER);
    }
    
    void draw()
    {
      background(0);
      float radio=70;
      float rotationAngle=map(mouseX, 0, width, 0, TWO_PI ); 
      for (int k=minNumberOfSides;k<maxNumberOfSides+1;k++)
      {
        int numberOfSides=k;
        float centerPositionX=(k-minNumberOfSides+1)*2.2*radio-radio/2;
        float centerPositionY=height/2;
        drawPolygon(radio, centerPositionX, centerPositionY, numberOfSides, rotationAngle);
      }
    }
    
    void drawPolygon(float radio, float centerPositionX, float centerPositionY, int numberOfSides, float rotationAngle)
    {
      numberOfSides=constrain(numberOfSides, minNumberOfSides, maxNumberOfSides);
      float sideAngle=TWO_PI/numberOfSides;
      float halfSideLineLength=sin(sideAngle/2)*radio;
      float lineY=cos(sideAngle/2)*radio;
    
      stroke(255);
      pushMatrix();
      translate(centerPositionX, centerPositionY);  
      rotate(rotationAngle);
      for (int i=0; i<numberOfSides; i++)
      {  
        rotate(sideAngle); // incremental rotation
        fill(0, 200, 200);
        stroke(0, 200, 200);
        strokeWeight(1);
        triangle(-halfSideLineLength, -lineY, halfSideLineLength, -lineY, 0, 0);
      }
      popMatrix();
      if (mousePressed)
      {
        //fill(255,0,0);
        //ellipse(centerPositionX, centerPositionY, 4, 4);
        noFill();  
        ellipse(centerPositionX, centerPositionY, 2*radio, 2*radio);
      }
      fill(255);
      textSize(15);
      text("Move mouse sideways to see rotation. Press mouse to see additions", width/2, 100);
    }
    

    DrawingPolygonsFinal

  • This creates and exploded view of the Polygons:

    final int minNumberOfSides=3;
    final int maxNumberOfSides=10;
    float rotationAngle;
    
    void setup()
    {
      size(1300, 600);
      textAlign(CENTER);
    }
    
    void draw()
    {
      background(0);
      float radio=70;
      float rotationAngle=map(mouseX, 0, width, 0, TWO_PI ); 
      for (int k=minNumberOfSides;k<maxNumberOfSides+1;k++)
      {
        int numberOfSides=k;
        float centerPositionX=(k-minNumberOfSides+1)*2.2*radio-radio/2;
        float centerPositionY=height/2;
        drawPolygon(radio, centerPositionX, centerPositionY, numberOfSides, rotationAngle);
      }
    }
    
    void drawPolygon(float radio, float centerPositionX, float centerPositionY, int numberOfSides, float rotationAngle)
    {
      numberOfSides=constrain(numberOfSides, minNumberOfSides, maxNumberOfSides);
      float sideAngle=TWO_PI/numberOfSides;
      float halfSideLineLength=sin(sideAngle/2)*radio;
      float explosionFactor=0;
      if (mousePressed)
      {
       explosionFactor=0.25*radio; 
      }
      float lineY=cos(sideAngle/2)*radio+explosionFactor;
      stroke(255);
      pushMatrix();
      translate(centerPositionX, centerPositionY);  
      rotate(rotationAngle);
      for (int i=0; i<numberOfSides; i++)
      {  
        rotate(sideAngle); // incremental rotation
        fill(0, 200, 200);
        stroke(0, 200, 200);
        strokeWeight(1);
        triangle(-halfSideLineLength, -lineY, halfSideLineLength, -lineY, 0, -explosionFactor);
      }
      popMatrix();
      fill(255);
      textSize(15);
      text("Move mouse sideways to see rotation. Press mouse to see additions", width/2, 100);
    }
    

    DrawingPolygonsFinal

  • And this creates Stars: (and I'll leave it there for you to play with this).

    final int minNumberOfSides=3;
    final int maxNumberOfSides=10;
    float rotationAngle;
    
    void setup()
    {
      size(1300, 600);
      textAlign(CENTER);
    }
    
    void draw()
    {
      background(0);
      float radio=70;
      float rotationAngle=map(mouseX, 0, width, 0, TWO_PI ); 
      for (int k=minNumberOfSides;k<maxNumberOfSides+1;k++)
      {
        int numberOfSides=k;
        float centerPositionX=(k-minNumberOfSides+1)*2.2*radio-radio/2;
        float centerPositionY=height/2;
        drawPolygon(radio, centerPositionX, centerPositionY, numberOfSides, rotationAngle);
      }
    }
    
    void drawPolygon(float radio, float centerPositionX, float centerPositionY, int numberOfSides, float rotationAngle)
    {
      numberOfSides=constrain(numberOfSides, minNumberOfSides, maxNumberOfSides);
      float sideAngle=TWO_PI/numberOfSides;
      float halfSideLineLength=sin(sideAngle/2)*radio;
      float explosionFactor=0;
      if (mousePressed)
      {
       explosionFactor=0.25*radio; 
      }
      float lineY=cos(sideAngle/2)*radio-explosionFactor;
      stroke(255);
      pushMatrix();
      translate(centerPositionX, centerPositionY);  
      rotate(rotationAngle);
      for (int i=0; i<numberOfSides; i++)
      {  
        rotate(sideAngle); // incremental rotation
        fill(0, 200, 200);
        stroke(0, 200, 200);
        strokeWeight(1);
        triangle(-halfSideLineLength, -lineY, halfSideLineLength, -lineY, 0, -explosionFactor);
      }
      popMatrix();
      fill(255);
      textSize(15);
      text("Move mouse sideways to see rotation. Press mouse to see additions", width/2, 100);
    }
    

    DrawingPolygonsStars

  • edited July 2014

    The instructions at the top should be written only once per loop() also, so they are not overwritten over and over everytime a Polygon is drawn, which causes the letters to look bad. Therfore taking that part from inside the drawPolygon(); function and moving it to void draw(); after the Polygons are drawn, is the way to go.

    like this:

    //Drawing Starts with Polygons.
    final int minNumberOfSides=3;
    final int maxNumberOfSides=10;
    float rotationAngle;
    
    void setup()
    {
      size(1300, 600);
      textAlign(CENTER);
    }
    
    void draw()
    {
      background(0);
      float radio=70;
      float rotationAngle=map(mouseX, 0, width, 0, TWO_PI ); 
      for (int k=minNumberOfSides;k<maxNumberOfSides+1;k++)
      {
        int numberOfSides=k;
        float centerPositionX=(k-minNumberOfSides+1)*2.2*radio-radio/2;
        float centerPositionY=height/2;
        drawPolygon(radio, centerPositionX, centerPositionY, numberOfSides, rotationAngle);
      }
      fill(255);
      textSize(15);
      text("Move mouse sideways to see rotation. Press mouse to see additions", width/2, 100); 
    }
    
    void drawPolygon(float radio, float centerPositionX, float centerPositionY, int numberOfSides, float rotationAngle)
    {
      numberOfSides=constrain(numberOfSides, minNumberOfSides, maxNumberOfSides);
      float sideAngle=TWO_PI/numberOfSides;
      float halfSideLineLength=sin(sideAngle/2)*radio;
      float explosionFactor=0;
      if (mousePressed)
      {
       explosionFactor=0.25*radio; 
      }
      float lineY=cos(sideAngle/2)*radio-explosionFactor;
      stroke(255);
      pushMatrix();
      translate(centerPositionX, centerPositionY);  
      rotate(rotationAngle);
      for (int i=0; i<numberOfSides; i++)
      {  
        rotate(sideAngle); // incremental rotation
        fill(0, 200, 200);
        stroke(0, 200, 200);
        strokeWeight(1);
        triangle(-halfSideLineLength, -lineY, halfSideLineLength, -lineY, 0, -explosionFactor);
      }
      popMatrix();
    }
    

    and now the text looks much better.

    DrawingPolygonsFinal

  • Although this is not the kind of work (art) I normally do, it has been a lot of fun to play with this code and perhaps its useful for the real artists here. If pushMatrix() and popMatrix() aren't used to apply and fully reverse the transformations and only part of them are reversed using translate(-x,-y); and rotate(-angle); then some useful effects can be achieved. I have used this before and tried here now. There is a problem though, anything else in the screen will go crazy. That's the reason why I did not write the instructions at the top in this case as they will keep rotating wildly. The instructions are the same though. "Move mouse sideways to see rotations. Press mouse to see additions". The effect in this case is a folding and unfolding spiral. You can run the program to watch the effect.

    final int minNumberOfSides=3;
    final int maxNumberOfSides=11;
    float rotationAngle;
    
    void setup()
    {
      size(1300, 690);
      textAlign(CENTER);
    }
    
    void draw()
    {
      background(0);
      float radioSum=0;
      float radio=20;
      float rotationAngle=map(mouseX, 0, width, 4*PI/3, TWO_PI ); 
      for (int k=minNumberOfSides;k<maxNumberOfSides+1;k++)
      {
        int numberOfSides=k;
        radio=radio*sqrt(k)/2;
        radioSum=radioSum+radio;
        float centerPositionX=width/2+radioSum;
        float centerPositionY=height/2;
        drawPolygon(radio, centerPositionX, centerPositionY, numberOfSides, rotationAngle);
      }
    }
    
    void drawPolygon(float radio, float centerPositionX, float centerPositionY, int numberOfSides, float rotationAngle)
    {
      numberOfSides=constrain(numberOfSides, minNumberOfSides, maxNumberOfSides);
      float sideAngle=TWO_PI/numberOfSides;
      float halfSideLineLength=sin(sideAngle/2)*radio*0.2;
      float explosionFactor=0.3*radio;
      if (mousePressed)
      {
        halfSideLineLength=sin(sideAngle/2)*radio*0.4; 
        explosionFactor=explosionFactor=0.4*radio;
      }
      float lineY=cos(sideAngle/2)*radio-explosionFactor;
      translate(centerPositionX, centerPositionY);  
      rotate(rotationAngle);
      for (int i=0; i<numberOfSides; i++)
      {  
        rotate(sideAngle); // incremental rotation
        fill(25*numberOfSides, 10*numberOfSides, 30*i);
        stroke(15*numberOfSides, 30*numberOfSides, 20*i);
        strokeWeight(1);
        triangle(-halfSideLineLength, -lineY, halfSideLineLength, -lineY, 0, -explosionFactor);
      }   
      noStroke();
      if (mousePressed)
      { 
        fill(255, 180, 100);
        ellipse(0, 0, 1.7*explosionFactor, 1.7*explosionFactor);
      }
      else
      {   
        fill(255, 180, 0);
        ellipse(0, 0, 1.5*explosionFactor, 1.5*explosionFactor);
      }
      rotate(-(numberOfSides-1)*sideAngle);
      translate(-centerPositionX, -centerPositionY);
    }
    

    DrawingPolygonsStars2

    DrawingPolygonsStars3

Sign In or Register to comment.