#### Howdy, Stranger!

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

# Align box with vector

edited January 2017

Hi forums :)

I'm new to 3D and can't get my head around this very basic 3D logic problem. Say I have two 3D vectors, and I want to draw an elongated box or rod connecting the two. How? In 2D it's easy - get the angle with simple trigonometry, push matrix, rotate, draw, pop matrix.

I understand that in 3D two angles are needed, and I've come across some different ways of calculating them. I can't get any reasonable results though - I think because the first rotation rotates the entire system and makes that second angle I calculated invalid.

Another way of wording it - how can I align the matrix's rotation with a specific unit vector?

What I get:

What I want:

(images stolen from here: https://forum.openframeworks.cc/t/rotate-3d-object-to-align-to-vector/5085 , this guy had the same problem but that environment could be asked to rotate along an arbitrary axis which doesn't seem possible in processing)

Tagged:

• edited January 2017 Answer ✓

Oh, I solved it! What's the etiquette around here, should I delete the thread or just post my solution for others to see?

For now I'll post it:

This code draws a sphere at pos, and an elongated box between pos and parentPos.

``````     PVector pos, parentPos

pushMatrix();

translate(pos.x, pos.y, pos.z);

PVector rtVc = pos.copy().sub(parent.pos).setMag(1.0);//unit vector
float dst = dist(pos.x, pos.z, pos.y, parentPos.x, parentPos.z, parentPos.y);

float rotx = -atan2(rtVc.y, rtVc.z);
float roty = atan2(rtVc.x, sqrt(rtVc.y*rtVc.y + rtVc.z*rtVc.z));

rotateX(rotx);
rotateY(roty);

sphere(5);

translate(0, 0, -dst*0.5); //go half the dist to draw box in-between points

box(2, 2, dst);

popMatrix();
``````
• Just found the formulas in an old project, maybe still helpful, since i cannot run your code.

``````PVector p1, p2, dir;

void setup() {
size(800, 800, P3D);
p1 = new PVector(-200, 100, -200);
p2 = new PVector(200, 100, -500);
}

void draw() {
background(200);

// vary position of sphere
p1.x = map(mouseX, 0, width, -300, 300);
p1.y = map(mouseY, 0, height, -300, 300);

// calculate direction and angles
PVector dir = PVector.sub(p2, p1);
float pitch = asin(dir.y / dir.mag());
float yaw = -asin( dir.x / (cos(pitch)*dir.mag()) );

// draw the stuff

translate(width/2, height/2, 0);

pushMatrix();
translate(p1.x, p1.y, p1.z);
sphere(10);
popMatrix();

pushMatrix();
translate(p2.x, p2.y, p2.z);
rotateX(pitch);
rotateY(yaw);
box(100);
popMatrix();
}
``````
• Yes, post solution for others unless homework

• @benja: Woe, this is amazing. What does this sketch do?

Let the box look at the sphere wherever you move it?

• btw the old 2D line command has a version with 6 paramy which is in fact a 3D version. It looks crappy though.

additionally let me mention a 3D-ine by James :

``````  void line3D(float x1, float y1, float z1,
float x2, float y2, float z2,
float weight, color colorLine)
// drawLine was programmed by James Carruthers
// see http://processing.org/discourse/yabb2/YaBB.pl?num=1262458611/0#9
{
// scale(90);

PVector p1 = new PVector(x1, y1, z1);
PVector p2 = new PVector(x2, y2, z2);
PVector v1 = new PVector(x2-x1, y2-y1, z2-z1);
float rho = sqrt(pow(v1.x, 2)+pow(v1.y, 2)+pow(v1.z, 2));
float phi = acos(v1.z/rho);
float the = atan2(v1.y, v1.x);
v1.mult(0.5);
pushMatrix();
PVector v2 = new PVector ( x1, y1, z1 );
translate(v2.x, v2.y, v2.z);
translate(v1.x, v1.y, v1.z);
rotateZ(the);
rotateY(phi);
noStroke();
fill(colorLine);

box(weight, weight, p1.dist(p2));
popMatrix();
} // method
``````
• :)

• Impressive!

Kf

• edited January 2017

amazing. It is like a tree in space. A star tree.

I think Dan Simmons has an Orbital that's a growing tree around a sun. He calls it star tree. IIRC.

I tried to add to your sketch a Z-component for the sphere, and I don't think that works really. Could you improve that for me please? Or have I made a mistake?

To invoke the z component of the sphere you need to hold a key while moving the mouse vertically.

At first the sphere is to near towards you then, so you have to move the mouse UP

Thank you!

Best Chrisir ;-)

``````// https : // forum.processing.org/two/discussion/20235/align-box-with-vector#latest

PVector spherePos, boxPos, dir;

void setup() {
size(800, 800, P3D);
spherePos = new PVector(-200, 100, -200);
boxPos = new PVector(200, 100, -500);
}

void draw() {
background(200);
lights();

// vary position of sphere (target)

// mouse x is always on changing sphere x
spherePos.x = map(mouseX, 0, width, -300, 300);

// mouse y is on changing sphere x OR z !!!!!!!!!!!!!!!
if (keyPressed)
spherePos.z = map(mouseY, 0, height, -900, 900);
else
spherePos.y = map(mouseY, 0, height, -300, 300);

// calculate direction and angles
PVector dir = PVector.sub(boxPos, spherePos);
float pitch = asin(dir.y / dir.mag());
float yaw = -asin( dir.x / (cos(pitch)*dir.mag()) );

// draw the stuff

translate(width/2, height/2, 0);

fill(255);
stroke(0);

// sphere
pushMatrix();
noStroke();
fill(0, 255, 0);
translate(spherePos.x, spherePos.y, spherePos.z);
sphere(10);
popMatrix();

pushMatrix();
stroke(0);
fill(255);
translate(boxPos.x, boxPos.y, boxPos.z);
rotateX(pitch);
rotateY(yaw);
box(100);
noStroke();
fill(255, 0, 0);

// eyes -----------------

int xOffset=21;
int yOffset=18;
int zOffset=57;

pushMatrix();
translate(-xOffset, -yOffset, zOffset );
sphere(11);
popMatrix();

pushMatrix();
translate(xOffset, -yOffset, zOffset );
sphere(11);
popMatrix();

//
popMatrix();
}
``````
• edited January 2017

I see what you mean, you ave to adjust yaw, if direction is facing positive z-values. Try this:

[...]

``````  // calculate direction and angles
PVector dir = PVector.sub(boxPos, spherePos);
float pitch = asin(dir.y / dir.mag());
float yaw = -asin( dir.x / (cos(pitch)*dir.mag()) );

// handle positive z- values
if (dir.z>0) {
yaw = PI-yaw;
}
``````

[...]

@JLJac: looks great :)

• Not quite so solved after all :(

Even rotation on the XY plane, and Z angle attached to moouse. That perpendicular line is supposed to be in the same direction and not wobble.

There's some strange rotation going on along the Z axis. I vaguely recognize the pattern (could it be a tangent?) but I'm too bad at trigonometry to figure out exactly what's going on. If I could figure out the formula for the wobble I could just apply the opposite rotation. I've tried brute forcing the problem (applying a bunch of random trigonometry operations to that z rotation) but to no avail.

Here's what my code looks like:

Any ideas?