Reputation: 25
I'm writing solar system symulation, and I need to be able to zoom in/out where my mouse is pointing. What I've got so far is moving planets and zooming in/out where point (0, 0) is located.
Here's my code:
Main class
Planeta sun = new Planeta(color(235, 225, 52), 0, 696000, 0, 0);
Planeta mercury = new Planeta(color(166, 142, 88), 57909170, 2439, 0, 87.989);
Planeta venus = new Planeta(color(250, 193, 50), 108208926, 6052, 0, 224.701);
color stroke = color(70, 70, 70, 70);
int sx, sy;
int centerX, centerY;
static float m1 = 1000;
public static float magn = 1/m1;
void setup() {
fullScreen();
background(0);
sx = width/2;
sy = height/2;
ellipseMode(RADIUS);
stroke(stroke);
strokeWeight(3);
centerX = width/2;
centerY = height/2;
}
void draw() {
magn = 1/m1;
background(0);
translate(sx, sy);
sun.drawOrbit();
sun.drawPlanet();
mercury.drawOrbit();
mercury.drawPlanet();
venus.drawOrbit();
venus.drawPlanet();
if(mousePressed) {
float wx = mouseX - pmouseX;
float wy = mouseY - pmouseY;
sx += wx;
sy += wy;
}
}
void mouseWheel(MouseEvent event) {
float e = float(event.getCount())*m1/3;
if(m1+e > 0.2) {
m1 += e;
}
}
Second class
class Planeta {
color c;
float distance;
float radius;
float angle;
float orbit_time;
Planeta(color kolor, float dystans, float promien, float kat, float czas) {
this.c = kolor;
this.distance = dystans/100;
this.radius = promien/100;
this.angle = kat;
this.orbit_time = czas;
}
public PVector getPos() {
float x = this.distance*sin(this.angle);
float y = this.distance*cos(this.angle);
return new PVector(x, y);
}
public void drawOrbit() {
noFill();
circle(0, 0, this.distance*magn);
}
public void drawPlanet() {
fill(this.c);
PVector pos = getPos();
circle(pos.x*magn, pos.y*magn, this.radius*magn);
}
}
sx and sy are for translate, centerX and centerY are constant, magn and m1 are for zooming.
So moving planets is working like a charm, but I don't know how to zoom in/out into point where my mouse is. I've searched google for code, nothing worked for me.
I appreciate every help.
Upvotes: 2
Views: 190
Reputation: 211258
I recommend to use floating point variables for the translation, to increase the accuracy:
float sx, sy;
You have to change the translation, dependent on the change of the scale factor.
Compute the relative change of the scale factor:
float fromM = m1;
float toM = m1 + e;
float scaleRel = fromM / toM;
Compute the distance from the mouse cursor to the current translation:
float dx = mouseX - sx;
float dy = mouseY - sy;
Change the the translation dependent on the distance of the mouse cursor to the current translation (dx
, dy
) and the delta of the relative scale (1 - scaleRel
):
sx += dx * (1.0-scaleRel);
sy += dy * (1.0-scaleRel);
e.g:
void mouseWheel(MouseEvent event) {
float e = float(event.getCount())*m1/3;
if(m1+e > 0.2) {
float fromM = m1;
float toM = m1 + e;
float scaleRel = fromM / toM;
float dx = mouseX - sx;
float dy = mouseY - sy;
sx += dx * (1.0-scaleRel);
sy += dy * (1.0-scaleRel);
m1 = toM;
}
}
Upvotes: 2