# Find centre of pyramid and rotate from there, not the apex

**URL:** <https://discourse.processing.org/t/find-centre-of-pyramid-and-rotate-from-there-not-the-apex/40411>\
**Category:** Coding Questions\
**Created:** [January 2, 2023, 6:04pm UTC](https://discourse.processing.org/t/find-centre-of-pyramid-and-rotate-from-there-not-the-apex/40411 "2023-01-02T18:04:10Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![JonnieNightTime](https://avatars.discourse-cdn.com/v4/letter/j/ecb155/32.png) [@JonnieNightTime](https://discourse.processing.org/u/JonnieNightTime)\
**Post date:** [January 2, 2023, 6:04pm UTC](https://discourse.processing.org/t/find-centre-of-pyramid-and-rotate-from-there-not-the-apex/40411/1 "2023-01-02T18:04:10Z")

</div>

Hi all,  
How can I rotate this from a centre point within the geometry rather from the vertex /apex (not sure of the correct terminology)

```auto
PGraphics canvas;
PVector[] basePts = new PVector[3];

void setup() {
  size(768, 768, P3D);  
  canvas = createGraphics(width, height, P3D);
}

void draw() {
 
  canvas.beginDraw();
  canvas.background(0);
  canvas.noStroke();

  canvas.pushMatrix();
  
  canvas.translate(width/2, height/2, 0);
  canvas.rotateZ(PI/2);
  
  canvas.rotateY(radians(frameCount/2 % 360));
  
  for (int i = 0; i < 3; ++i ) {
  float ang = TWO_PI * i / 3;
   basePts[i] = new PVector(cos(ang) * 400/2, sin(ang) * 400/2, -400/2);
  }
 
  canvas.fill(255);
  canvas.strokeWeight(3);
  canvas.stroke(123);
  
  canvas.beginShape(TRIANGLES);
  for (int i = 0; i < 3; ++i ) {
    int i2 = (i+1) % 3;
  canvas.vertex(basePts[i].x, basePts[i].y, basePts[i].z);
  canvas.vertex(basePts[i2].x, basePts[i2].y, basePts[i2].z);
  canvas.vertex(0, 0, PI/2);
}
  canvas.endShape();//sides
  
  beginShape(); //base
  for (int i = 0; i < 3; ++i ) {
    canvas.vertex(basePts[i].x, basePts[i].y, basePts[i].z);
  }
  endShape(CLOSE);
  
  canvas.popMatrix();
  canvas.endDraw();

  blendMode(BLEND);
  image(canvas, 0, 0);
}

```

Many thanks for any suggestions.

---

<div class="post-metadata">

**Author:** ![debxyz](https://avatars.discourse-cdn.com/v4/letter/d/58956e/32.png) [@debxyz](https://discourse.processing.org/u/debxyz)\
**Post date:** [January 2, 2023, 8:00pm UTC](https://discourse.processing.org/t/find-centre-of-pyramid-and-rotate-from-there-not-the-apex/40411/2 "2023-01-02T20:00:15Z")

</div>

Hello @JonnieNightTime

In this section:

> [@JonnieNightTime](#):
>
> ```auto
> canvas.beginShape(TRIANGLES);
> for (int i = 0; i < 3; ++i ) {
> int i2 = (i+1) % 3;
> canvas.vertex(basePts[i].x, basePts[i].y, basePts[i].z);
> canvas.vertex(basePts[i2].x, basePts[i2].y, basePts[i2].z);
> canvas.vertex(0, 0, PI/2); // I think here!! :-)
> 
> ```

I changed this:

`canvas.vertex(0, 0, PI/2);`

To this:

`canvas.vertex(0, 0, 180);`

It moved the rotation off the apex.  
It’s not prefect, in that now there is a bit of perspective distortion which needs to be cleaned up.  
But it’s a place to start. 🙂

🤓

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [January 2, 2023, 9:36pm UTC](https://discourse.processing.org/t/find-centre-of-pyramid-and-rotate-from-there-not-the-apex/40411/3 "2023-01-02T21:36:18Z")

</div>

here is my version with mouse rotation

```auto

PGraphics canvas;
PVector[] basePts = new PVector[3];

float angleMouseX, angleMouseY; 

void setup() {
  size(768, 768, P3D);  
  canvas = createGraphics(width, height, P3D);

  for (int i = 0; i < 3; i++ ) {
    float ang = TWO_PI * i / 3;
    basePts[i] = new PVector(cos(ang) * 400/2, 
      sin(ang) * 400/2, 
      -100 );
    println(basePts[i]);
  }
}

void draw() {
  angleMouseX = map(mouseX, 0, width, -TWO_PI, TWO_PI);
  angleMouseY = map(mouseY, 0, height, height+200, -200);

  float rad = 810; 
  float posX = (0) + cos(angleMouseX) * rad ;
  float posZ = 0 + sin(angleMouseX) * rad ;
  canvas.camera(posX, angleMouseY, posZ, 
    width/2.0-0, height/2.0, 0, 
    0, 1, 0);

  // canvas.camera(); 

  canvas.beginDraw();
  canvas.background(0);
  canvas.lights(); 
  canvas.noStroke();

  canvas.pushMatrix();
  canvas.translate(width/2, height/2, 0);
  // canvas.rotateZ(PI/2);
  // canvas.rotateY(radians(frameCount/2 % 360));

  canvas.fill(255);
  canvas.strokeWeight(3);
  canvas.stroke(123);

  //sides
  canvas.beginShape(TRIANGLES);
  for (int i = 0; i < 3; i++ ) {
    int i2 = (i+1) % 3;
    canvas.vertex(basePts[i].x, basePts[i].y, basePts[i].z);
    canvas.vertex(basePts[i2].x, basePts[i2].y, basePts[i2].z);
    canvas.vertex(0, 0, 100);
  }
  canvas.endShape();//sides

  //base
  canvas.fill(255, 0, 9); 
  canvas.beginShape(); //base
  for (int i = 0; i < 3; i++ ) {
    canvas.vertex(basePts[i].x, basePts[i].y, basePts[i].z);
  }
  canvas.endShape(CLOSE);

  canvas.popMatrix();
  canvas.endDraw();

  blendMode(BLEND);
  image(canvas, 0, 0);
}

```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [January 2, 2023, 9:58pm UTC](https://discourse.processing.org/t/find-centre-of-pyramid-and-rotate-from-there-not-the-apex/40411/4 "2023-01-02T21:58:49Z")

</div>

here is an other version

the base is in the X Z plane (like standing on a table), the top is in y direction

This reflects more my approach for P3D that the room / space has its floor in X Z plane (like standing on a table)

```auto

PGraphics canvas;
PVector[] basePts = new PVector[3];

float angleMouseX, angleMouseY; 

void setup() {
  size(768, 768, P3D);  
  canvas = createGraphics(width, height, P3D);

  for (int i = 0; i < 3; i++ ) {
    float ang = TWO_PI * i / 3;
    basePts[i] = new PVector(cos(ang) * 400/2, 
      -100, 
      sin(ang) * 400/2 );
    println(basePts[i]);
  }
}

void draw() {

  background(0);
  lights(); 
  //noStroke();

  //angleMouseX = map(mouseX, 0, width, -TWO_PI, TWO_PI);
  //angleMouseY = map(mouseY, 0, height, height+200, -200);

  //float rad = 810; 
  //float posX = (0) + cos(angleMouseX) * rad ;
  //float posZ = 0 + sin(angleMouseX) * rad ;
  //camera(posX, angleMouseY, posZ, 
  // width/2.0-0, height/2.0, 0, 
  // 0, 1, 0);

  // camera(); 

  translate(width/2, height/2, 0);
  rotateX(radians(frameCount/8 % 360));
  rotateY(radians(frameCount/2 % 360));

  fill(255);
  strokeWeight(3);
  stroke(123);

  //sides
  beginShape(TRIANGLES);
  for (int i = 0; i < 3; i++ ) {
    int i2 = (i+1) % 3;
    vertex(basePts[i].x, basePts[i].y, basePts[i].z);
    vertex(basePts[i2].x, basePts[i2].y, basePts[i2].z);
    vertex(0, 100, 0 );
  }
  endShape();//sides

  //base
  fill(255, 0, 9); 
  beginShape(); //base
  for (int i = 0; i < 3; i++ ) {
    vertex(basePts[i].x, basePts[i].y, basePts[i].z);
  }
  endShape(CLOSE);
}

```

---

<div class="post-metadata">

**Author:** ![JonnieNightTime](https://avatars.discourse-cdn.com/v4/letter/j/ecb155/32.png) [@JonnieNightTime](https://discourse.processing.org/u/JonnieNightTime)\
**Post date:** [January 2, 2023, 10:59pm UTC](https://discourse.processing.org/t/find-centre-of-pyramid-and-rotate-from-there-not-the-apex/40411/5 "2023-01-02T22:59:05Z")

</div>

nice - thanks both. Here’s where I’m taking it - inspired by classic cognitive psychology - Kanisza’s triangle [Kanizsa triangle - New World Encyclopedia](https://www.newworldencyclopedia.org/entry/Kanizsa_triangle)

```auto
PGraphics canvas;
PVector[] basePts = new PVector[3];
PVector[] basePtsBlk = new PVector[3];
float angleMouseX, angleMouseY;

void setup() {
  size(768, 768, P3D);  
  canvas = createGraphics(width, height, P3D);
  
    for (int i = 0; i < 3; i++ ) {
    float ang = TWO_PI * i / 3;
    basePts[i] = new PVector(cos(ang) * 400/2, -100, sin(ang) * 400/2 );
    println(basePts[i]);
  }
}

void draw() {
 
  canvas.beginDraw();
  canvas.background(30);
  canvas.camera(mouseX, height/2, (height/2) / tan(PI/6), width/2, height/2, 0, 0, 1, 0);
  canvas.noStroke();
  //canvas.ambientLight(255, 0, 0);
  //canvas.directionalLight(0, 255, 0, 0, -1, 0);
  //canvas.spotLight(0, 0, 255, width/2, height/2, 100, 0, 0, -1, PI/4, 2);
  canvas.ortho(-width/2, width/2, -height/2, height/2);
  
/// white pyramid
  canvas.pushMatrix();
  canvas.translate(width/2, height/2, 0);
  canvas.rotateX(radians(frameCount*0.99 % 360));
  canvas.rotateZ(radians(frameCount/2 % 360));
  
  canvas.fill(255);
  canvas.strokeWeight(1);
  canvas.stroke(0);
  
  //sides
  canvas.beginShape(TRIANGLES);
  for (int i = 0; i < 3; ++i ) {
    int i2 = (i+1) % 3;
  canvas.vertex(basePts[i].x, basePts[i].y, basePts[i].z);
  canvas.vertex(basePts[i2].x, basePts[i2].y, basePts[i2].z);
  canvas.vertex(0, 180, 0 );
}
  canvas.endShape();//sides
  
  canvas.beginShape(); //base
  canvas.fill(255); 
  for (int i = 0; i < 3; ++i ) {
    canvas.vertex(basePts[i].x, basePts[i].y, basePts[i].z);
  }
  canvas.endShape(CLOSE);
  canvas.popMatrix(); /// white pyramid end
  
  /// pyramid 2 (blk)
  canvas.pushMatrix();
  canvas.translate(width/2+5, height/2-3, 0);
  canvas.rotateY(radians(frameCount % 360)*-1);
  canvas.rotateZ(radians(frameCount/1.8 % 360*-1));
  
  canvas.fill(0);
  canvas.strokeWeight(2);
  canvas.stroke(50);
  
  //sides
  canvas.beginShape(TRIANGLES);
  for (int i = 0; i < 3; ++i ) {
    int i2 = (i+1) % 3;
  canvas.vertex(basePts[i].x, basePts[i].y, basePts[i].z);
  canvas.vertex(basePts[i2].x, basePts[i2].y, basePts[i2].z);
  canvas.vertex(0, 180, 0 );
}
  canvas.endShape();//sides
  
  canvas.beginShape(); //base
  canvas.fill(0); 
  for (int i = 0; i < 3; ++i ) {
    canvas.vertex(basePts[i].x, basePts[i].y, basePts[i].z);
  }
  canvas.endShape(CLOSE);
  canvas.popMatrix(); /// pyramid 2 (blk) end
  
    /// pyramid 3 (blk)
  canvas.pushMatrix();
  canvas.translate(width/2-5, height/2+3, 0);
  canvas.rotateX(radians(frameCount*0.98 % 360)*-1);
  canvas.rotateZ(radians(frameCount/1.9 % 360));
  
  canvas.fill(0);
  canvas.strokeWeight(2);
  canvas.stroke(50);
  
  //sides
  canvas.beginShape(TRIANGLES);
  for (int i = 0; i < 3; ++i ) {
    int i2 = (i+1) % 3;
  canvas.vertex(basePts[i].x, basePts[i].y, basePts[i].z);
  canvas.vertex(basePts[i2].x, basePts[i2].y, basePts[i2].z);
  canvas.vertex(0, 180, 0 );
}
  canvas.endShape();
  
  canvas.beginShape(); //base
  canvas.fill(0); 
  for (int i = 0; i < 3; ++i ) {
    canvas.vertex(basePts[i].x, basePts[i].y, basePts[i].z);
  }
  canvas.endShape(CLOSE);
  canvas.popMatrix(); /// pyramid 2 (blk) end
  canvas.endDraw();

  blendMode(BLEND);
  image(canvas, 0, 0);
}

```
