#### Howdy, Stranger!

We are about to switch to a new forum software. Until then we have removed the registration on this forum.

# Linear algebra question - how to rotate a figure around point

edited February 2018

Here is a sketch, in this sketch I tried to impement a rotation of a figure in 3 dimensions. The rotation should be around the point of mouse coordintates (please hold left button and move the mouse), but it don't work properly. I used following method - find mouse coordinates, calculate new point coodinates in new axis space, rotate all the points around this new center, return the translation of coordinates in normal coordinate space (hope the explanation makes sence). The question is - why my rotation is stange and not around the point?

``````Figure figure=new Figure();
PVector mus;
PVector dirx;
PVector diry;
float anglx;
float angly;
float locX=0;
float locY=0;

void setup()
{
size(500,500,P3D);
ortho();
dirx=new PVector(0,0,0);
diry=new PVector(0,0,0);
}

void draw()
{
mus=new PVector(mouseX-pmouseX,mouseY-pmouseY,0);
mus.setMag(0.04);

dirx = new PVector(1,0,0);
dirx.add(mus.copy());
dirx.setMag(1);

diry = new PVector(0,1,0);
diry.add(mus.copy());
diry.setMag(1);

background(200);
figure.display();
}

void mousePressed()
{
locX=mouseX;
locY=mouseY;
}

void mouseDragged()
{

ellipse(locX,locY,5,5);

float ax = figure.A.x-locX;
float bx = figure.B.x-locX;
float cx = figure.C.x-locX;

float ay= figure.A.y-locY;
float by= figure.B.y-locY;
float cy= figure.C.y-locY;

{// rotation by X axis

float nax=(figure.A.x*1)+(0)+(0);
float nay=(0)+(ay*dirx.x)+(figure.A.z*dirx.y);
float naz=(0)+(ay*-dirx.y)+(figure.A.z*dirx.x);

float nbx=(figure.B.x*1)+(0)+(0);
float nby=(0)+(by*dirx.x)+(figure.B.z*dirx.y);
float nbz=(0)+(by*-dirx.y)+(figure.B.z*dirx.x);

float ncx=(figure.C.x*1)+(0)+(0);
float ncy=(0)+(cy*dirx.x)+(figure.C.z*dirx.y);
float ncz=(0)+(cy*-dirx.y)+(figure.C.z*dirx.x);

figure.A.x=nax;
figure.A.y=nay+locY;
figure.A.z=naz;
figure.B.x=nbx;
figure.B.y=nby+locY;
figure.B.z=nbz;
figure.C.x=ncx;
figure.C.y=ncy+locY;
figure.C.z=ncz;
}

{// rotation by Y axis

float nax=(ax*diry.y)+(0)+(figure.A.z*-diry.x);
float nay=(0)+(figure.A.y*1)+(0);
float naz=(ax*diry.x)+(0)+(figure.A.z*diry.y);

float nbx=(bx*diry.y)+(0)+(figure.B.z*-diry.x);
float nby=(0)+(figure.B.y*1)+(0);
float nbz=(bx*diry.x)+(0)+(figure.B.z*diry.y);

float ncx=(cx*diry.y)+(0)+(figure.C.z*-diry.x);
float ncy=(0)+(figure.C.y*1)+(0);
float ncz=(cx*diry.x)+(0)+(figure.C.z*diry.y);

figure.A.x=nax+locX;
figure.A.y=nay;
figure.A.z=naz;
figure.B.x=nbx+locX;
figure.B.y=nby;
figure.B.z=nbz;
figure.C.x=ncx+locX;
figure.C.y=ncy;
figure.C.z=ncz;

}
}

class Figure
{
PVector A;
PVector B;
PVector C;

Figure()
{
A=new PVector(random(width*2, width*4), random(width*2, width*4), random(width*2, width*4));
B=new PVector(random(width*2, width*4), random(width*2, width*4), random(width*2, width*4));
C=new PVector(random(width*2, width*4), random(width*2, width*4), random(width*2, width*4));
}

void display()
{

stroke(255, 150);
fill(#73C1C1);

beginShape(TRIANGLES);
vertex(A.x, A.y, A.z);
vertex(B.x, B.y, B.z);
vertex(C.x, C.y, C.z);
endShape();

fill(255);
text("AX="+A.x, 10, 20);
text("AY="+A.y, 10, 40);
text("AZ="+A.z, 10, 60);

text("BX="+B.x, 10, 100);
text("BY="+B.y, 10, 120);
text("BZ="+B.z, 10, 140);

text("CX="+B.x, 10, 180);
text("CY="+B.y, 10, 200);
text("CZ="+B.z, 10, 220);

text(locX, 10, 260);
text(locY, 10, 280);
}
}
``````
Tagged:

## Answers

• Hm... i dunno.....

Why don’t you use rotateX and -Y and -Z ?

• @Chrisir , I want to understand how rotation works in linear algebra, without using built-in functions of processing, so I can implement this approach in any programming language.

• Possibly of interest: the Processing implementation of its built-in rotate functions in 3D:

https://github.com/processing/processing/blob/0abee5af6ad3b11cf2b73bb794b8a97c157c4762/core/src/processing/core/PMatrix3D.java#L223

• @jeremydouglass, thanks for the link.

• just wanted to show this (not by me) which also has some trigonometry / angles / rotation for a 3D sphere when positioning each sphere. See constructor of the class - might be similar problem

``````import peasy.*;

PeasyCam cam;

Node[] nodes;
Node curr=null;

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

void setup() {
size(1200, 800, P3D);

int NUM_PARTICLES = 350;
nodes = new Node[NUM_PARTICLES];

background(255);
cam = new PeasyCam(this, width);

for (int i=0; i<NUM_PARTICLES; i++) {
// Node n = new Node( PI, .3 );  // belt
Node n = new Node(i, map(i, 0, NUM_PARTICLES, -1, 1));   // full sphere
nodes[i] = n;
}
}

void draw() {
background(255);

lights();

pushMatrix();
translate(0, 0, 0);
fill(0, 244, 255);
box(10);
stroke(0, 0, 0, 20);
popMatrix();

for (int i=0; i<nodes.length; i++) {
Node n = nodes[i];
n.render();
}

cam.beginHUD();
noLights();
fill(0);
text("click a node to select (it appears red), then space key "
+"to change Z; use peasycam outside sphere; use mousewheel to zoom etc.",
19, 19);
cam.endHUD();
}

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

void keyPressed() {
if (curr!=null)
curr.z+=6;
}

void mousePressed() {

boolean done=false;
Node  old=curr;

// search node
for (int i=0; i<nodes.length; i++) {
Node n = nodes[i];
if (dist(n.scrX, n.scrY, mouseX, mouseY)<6) {
n.selected=!n.selected;
curr=n;
done = true;
break; // leave
}
}
if (done&&old!=null&&(curr!=old)) {
old.selected=false;
}
}

// =====================================================================

class Node extends PVector {

float radius = 150;

float theta, u;
float scrX, scrY;
boolean selected= false;

color c = color(random(100, 255),
random(100, 255),
random(100, 255));

// constructor
Node(float Theta, float U) {
theta = Theta;

u = U;

x = radius*cos(theta)*sqrt(1-(u*u));
y = radius*sin(theta)*sqrt(1-(u*u));
z = u*radius;
}  // constructor

void render() {
pushMatrix();
translate(x, y, z);
noStroke();
if (selected)
fill(255, 0, 0);
else {
// fill(0, 244, 0);
fill(c);
}

sphere(10) ;
scrX=screenX(0, 0, 0);
scrY=screenY(0, 0, 0);

popMatrix();
}
}//class
//
``````
Sign In or Register to comment.