# Rotate and zoom question

**URL:** <https://discourse.processing.org/t/rotate-and-zoom-question/14891>\
**Category:** Coding Questions\
**Created:** [October 23, 2019, 7:38am UTC](https://discourse.processing.org/t/rotate-and-zoom-question/14891 "2019-10-23T07:38:33Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![companje](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/companje/32/2418_2.png) [@companje](https://discourse.processing.org/u/companje)\
**Post date:** [October 23, 2019, 7:38am UTC](https://discourse.processing.org/t/rotate-and-zoom-question/14891/1 "2019-10-23T07:38:33Z")

</div>

Hi everyone,

I’m trying to zoom in on a sphere. Instead of zooming in from the center I would like to zoom in such a way that the red square stays in the yellow ellipse.

What would be a good way to achieve this do you think?

![](https://hualab.nl/sphere-rotate-zoom.mov.gif)

```auto
float r = 400;

void setup() {
  size(800, 800, P3D);
  smooth();
}

void draw() {
  background(0);
  ortho();
  translate(width/2, height/2);

  float scaler = map(mouseY, 0, height, 1, 1.5);
  
  //draw sphere with red box
  pushMatrix();
  scale(scaler);
  rotateX(-.7);
  //how should I rotate back here to correct for zoom
  //so that the red box stays within the yellow ellipse?
  noFill();
  strokeWeight(1);
  fill(128);
  stroke(255);
  sphere(r);
  strokeWeight(10);
  noStroke();
  fill(255, 0, 0);
  translate(0, 0, r);
  box(20);
  popMatrix();

  //draw yellow circle
  hint(DISABLE_DEPTH_TEST);
  rotateX(-.7);
  translate(0, 0, r);
  noFill();
  strokeWeight(2);
  stroke(255,255,0);
  ellipse(0, 0, 40, 40);
  hint(ENABLE_DEPTH_TEST);
}

```

---

<div class="post-metadata">

**Author:** ![bohnacker](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/bohnacker/32/5868_2.png) [@bohnacker](https://discourse.processing.org/u/bohnacker)\
**Post date:** [October 23, 2019, 8:49am UTC](https://discourse.processing.org/t/rotate-and-zoom-question/14891/2 "2019-10-23T08:49:54Z")

</div>

Hi Rick,

I think, below is a solution of what you want to achieve. This might not be the only solution and might also be optimized somehow.

```auto
float r = 400;

void setup() {
  size(800, 800, P3D);
  smooth();
}

void draw() {
  background(0);
  ortho();
  translate(width/2, height/2);

  float scaler = map(mouseY, 0, height, 1, 1.5);
  
  // calculate screen position of the red box
  pushMatrix();
  scale(scaler);
  rotateX(-.7);
  translate(0, 0, r);
  float redY = screenY(0, 0, 0);
  popMatrix();

  // calculate screen position of yellow circle
  pushMatrix();
  rotateX(-.7);
  translate(0, 0, r);
  float yellowY = screenY(0, 0, 0);
  popMatrix();

  float dy = yellowY - redY;
  
  //draw sphere with red box
  pushMatrix();
  translate(0, dy, 0); // move the sphere 
  scale(scaler);
  rotateX(-.7);
  //how should I rotate back here to correct for zoom
  //so that the red box stays within the yellow ellipse?
  noFill();
  strokeWeight(1);
  fill(128);
  stroke(255);
  sphere(r);
  strokeWeight(10);
  noStroke();
  fill(255, 0, 0);
  translate(0, 0, r);
  box(20);
  popMatrix();

  //draw yellow circle
  hint(DISABLE_DEPTH_TEST);
  rotateX(-.7);
  translate(0, 0, r);
  noFill();
  strokeWeight(2);
  stroke(255,255,0);
  ellipse(0, 0, 40, 40);
  hint(ENABLE_DEPTH_TEST);
}

```

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [October 23, 2019, 10:23am UTC](https://discourse.processing.org/t/rotate-and-zoom-question/14891/3 "2019-10-23T10:23:17Z")

</div>

I assume the red square is a position on the sphere and its 3D coordinates are [rx, ry, rz] if my assumption is correct then this might work

1. translate(width/2, height/2);
2. Get the screen position with [screenX(rx, ry, rz)](https://processing.org/reference/screenX_.html) and [screenY(rx, ry, rz)](https://processing.org/reference/screenY_.html)
3. translate to the calculated position
4. scale the screen
5. draw the sphere

You might have to play with the translation and scaling in steps 3 & 4

---

<div class="post-metadata">

**Author:** ![companje](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/companje/32/2418_2.png) [@companje](https://discourse.processing.org/u/companje)\
**Post date:** [October 23, 2019, 4:53pm UTC](https://discourse.processing.org/t/rotate-and-zoom-question/14891/4 "2019-10-23T16:53:30Z")

</div>

Hi @bohnacker and @quark,

Thank you so much for your help. It works! Here is my updated example where you can see it also working for a moving target (mouse on sphere)

![](https://hualab.nl/rotate-back.mp4.gif)

Here’s the updated code:

```auto
float scaler = 1;
float r = 400;

void setup() {
  size(800, 800, P3D);
  smooth();
}

void draw() {
  background(0);
  ortho();
  translate(width/2, height/2);

  //mouse on sphere
  PVector p = new PVector(mouseX-width/2,mouseY-height/2);
  p.z = sqrt(r*r - p.mag());

  //calculate screen position of the mouse in scaled and unscaled mode
  pushMatrix();
  PVector unscaled = new PVector(screenX(p.x, p.y, p.z), screenY(p.x, p.y, p.z));
  scale(scaler);
  PVector scaled = new PVector(screenX(p.x, p.y, p.z), screenY(p.x, p.y, p.z));
  popMatrix();
  PVector delta = unscaled.sub(scaled);
  
  //draw sphere and mouse on sphere
  pushMatrix();
  translate(delta.x, delta.y, 0); 
  scale(scaler);
  noFill();
  stroke(255);
  strokeWeight(1);
  sphere(r);
  noStroke();
  fill(255, 0, 0);
  translate(p.x, p.y, p.z);
  box(20);
  popMatrix();
  
  saveFrame();
}

void mouseWheel(MouseEvent event) {
  //zoom factor needs to be between about 0.99 and 1.01 to be able to multiply so add 1
  scaler = constrain(scaler * (-event.getCount()*.01f + 1.0f), 1, 1.7);
}

```
