PDA

View Full Version : Projecting one vector onto another... why?


sealfin
2005.07.14, 11:17 AM
Okay, I'm currently working through Dunn & Parberry's 3D Math Primer, and I've just come to a topic which has me totally lost; the book has a short topic on projecting one vector, 'v', onto another, 'n', splitting the vector v into two two sub-vectors, 'v-parallel-to-n' and 'v-perpendicular-to-n'.

For retrieving 'v-parallel-to-n', the book gives the formula:
http://blog.sealfin.com/_images/_maths/_Dunn_Parberry-5.10.3/formula.png

I've worked through a few examples to try to gain an understanding of the workings of this formula (and the related formula for retrieving 'v-perpendicular-to-n'), but I'm lost; the topic seems to be presenting an overly complex method for retrieving either the x or y component of the vector 'v', simply returning a copy of 'v' with the unwanted component negated…

I'm just at a loss as to what I'm supposed to be achieving with these formulas? If somebody could throw some light on this topic? (Preferably using short, easy to understand words :wacko:)

The first example I worked through:
http://blog.sealfin.com/_images/_maths/_Dunn_Parberry-5.10.3/example_vectors.png

http://blog.sealfin.com/_images/_maths/_Dunn_Parberry-5.10.3/example_working.png

funkboy
2005.07.14, 11:49 AM
From what I remember from Calc 3, it's essentially a way to find the portion of a vector that lies in the same direction.

If the dot product is 0, the vectors are in no way in the same direction. (perp.)

It's not just an x,y component, but rather components in relation to the vector.

Can someone verify that's correct? That wasn't a great explanation, but it's a start.

ThemsAllTook
2005.07.14, 12:53 PM
If I correctly understand what you're trying to do, I might be able to help. This (http://www.sacredsoftware.net/temp/FunStuff.tar.gz) is a small test application I wrote a little while ago that projects one vector onto another. (Click and drag to move the target, option-drag and shift-drag to move the line.) Let me know if this is what you're looking for, and I'll explain how it works.

- Alex Diener

unknown
2005.07.14, 12:57 PM
The formula is n * (whatever) and the whatever will always be a scalar value, so the result of the formula will be the vector n scaled by the value.

looking at v.n / |n*n| is similar to v.n / |n*v| (= cos(a))
so in terms of cos(a)

(v.n)/(|n||v|)=cos(a)
(v.n)/(|n||n|)=( |v| / |n| ) cos(a)

so the scalar is (the ratio of the lengths of vectors v to n) * ( cos(a) )

from this:
the length of the resultant vector will be larger if v is larger than n
and because a will always be less than 180 degrees, as the angle between the vectors increase the length of the resultant vector will decrease.

Thats just the way i view it though..

Leisure Suit Lurie
2005.07.14, 01:07 PM
I have this book at home somewhere. What page is this on?

Mazilurik
2005.07.14, 02:37 PM
the topic seems to be presenting an overly complex method for retrieving either the x or y component of the vector 'v'

In this example, projn v (the projection of v onto n) is the x component of v since n is parallel to the x axis. If n were, for example, (1, 1), projn v would equal (4, 4), a vector at the same angle as n whose magnitude is the "component" of v parallel to n.

To break down the formula a bit: n*(v.n)/(|n|^2) can be rewritten as (n/|n|)*(v.(n/|n|)); the |n|^2 in the denominator normalizes both uses of the n vector. Since a.b = |a|*|b|*cos(theta), v.(n/|n|) = |v|*cos(theta), which is the magnitude of the resulting vector. Essentially, what you're doing is constructing a right triangle with v as the hypotenuse and projn v as the leg adjacent to theta. Since cos(theta) = adj./hyp. in right-triangle trig, the length of the adjacent side (|projn v|) equals the length of the hypotenuse (|v|) times cos(theta). Thus the (v.(n/|n|)) bit gives you the magnitude of the projected vector; multiplying this by n/|n| points it in the direction of vector n.

Hopefully that makes at least a little sense; it's a bit hard for me to explain without pretty pictures and/or wild gesticulations.

sealfin
2005.07.14, 02:37 PM
@Daniel_Lurie: page 61 (plus a .pdf of corrections from the web-site of the book...)

unknown
2005.07.14, 04:00 PM
Mazilurik, thats what i meant but put much better

sealfin
2005.07.14, 04:44 PM
Thanks for the help so far, I'm trying vainly to follow everybody's help on this ;) But I'm now even more lost than before, if that were possible... According to the explanation given in the book, 'v-odd,-inverted-T' is the vector perpendicular to 'n'.
I've tried working through several examples, but none of them result in a 'perpendicular'/'v-odd,-inverted-T' vector anywhere close to 90° from 'n'. Is this correct, and Dunn and Parberry have a revolutionary new definition of perpendicular (http://en.wikipedia.org/wiki/Perpendicular) I haven't heard of? :wacko:

http://blog.sealfin.com/_images/_maths/_Dunn_Parberry-5.10.3/not_perpendicular.png

Mazilurik
2005.07.14, 06:06 PM
Those values for VII seem off; the magnitude of the projection shouldn't be greater than that of the original vector. According to my math:

VII = (3, -2) * ((3, 1).(3, -2))/|(3, -2)|^2
= (3, -2) * (9-2)/(√(9+4))^2
= (3, -2) * 7/13
= (21/13, -14/13) ~= (1.615, -1.077)

And for the perpendicular (projection onto vector orthogonal to n):

Vp = (2, 3) * ((3, 1).(2, 3))/|(2, 3)|^2
= (2, 3) * (6+3)/13
= (18/13, 27/13) ~= (1.385, 2.077)

Leisure Suit Lurie
2005.07.14, 07:07 PM
I am wondering what in 3D this would be used for...other than figuring the distance to the picture plane...

sealfin
2005.07.14, 07:28 PM
@Mazilurik: right, I'm printing your post and settling in for a long night in front of the calculator ;)

@Daniel_Lurie: I'm likewise wondering, but the book says the formula will be used later, so I'd like to understand it before I move on... It's just annoying that the (for myself) most complex math in the book thus far has the shortest explanation :rolleyes:

Leisure Suit Lurie
2005.07.14, 07:32 PM
@Daniel_Lurie: I'm likewise wondering, but the book says the formula will be used later, so I'd like to understand it before I move on... It's just annoying that the (for myself) most complex math in the book thus far has the shortest explanation :rolleyes:

I have no doubt that if you see it in the context of what's done with it, the light bulb in your head will go off. I say ignore the frigging thing for the moment.

It may make more sense when you see how they do it in code anyway.

unknown
2005.07.14, 07:45 PM
yeah, absolutly please tell us what it used for later

MattDiamond
2005.07.15, 04:31 PM
I've always found it easiest to think of it in terms of basic trig.

cos() of a triangle's angle is the "length(adjacent)/length(hypotenuse)". So if you know the cos() of the angle already, and the length of the hypotenuse, you can easily figure out the length of the "adjacent" side of the triangle.

And the dot product is simply a vector math equivalent of cos().

So what is it used for? As funkboy wrote, "it's essentially a way to find the portion of a vector that lies in the same direction [as a 2nd vector]."

- If the 2nd vector is perpendicular to the ground, you can use this to compute the "bounce" of a moving object against the ground. The object keeps moving sideways but the "up-down" movement is reversed.
- Similarly, you can figure out how heavily an object is pushing against a slanted or flat surface, to compute friction.
- I've used it to figure out the impact point of a sphere moving along a vector and passing close to a plane, or another sphere.

Etc. It comes up a lot.

unknown
2005.07.15, 05:50 PM
Can you add the bit for Vperp, i dunno the formula.


// <applet code="ProjectingVectors.class" width="400" height="400"></applet>

import java.awt.Graphics;
import java.awt.Color;
import java.awt.event.*;

public class ProjectingVectors extends java.applet.Applet {
int dragMode;

int nx, ny;
int vx, vy;

int scX, scY;

Vect2D n, v;
Vect2D vParr, vPerp;

double nDv, nAbs, scale;

public void init() {
nx = (int)(Math.random()*400);
ny = (int)(Math.random()*400);
vx = (int)(Math.random()*400);
vy = (int)(Math.random()*400);

addMouseListener(new ML());
addMouseMotionListener(new MML());
}

public void paint(Graphics g) {
n = new Vect2D(nx-200, ny-200);
n.mult(1.0/200.0);
v = new Vect2D(vx-200, vy-200);
v.mult(1.0/200.0);

nDv = n.dot(v);
nAbs = n.absSqrd();

scale = nDv/nAbs;

nAbs = Math.sqrt(nAbs);

vParr = n.dup();
vParr.mult(scale);
scX = (int)(vParr.x*200+200);
scY = (int)(vParr.y*200+200);

g.setColor(Color.white);
g.fillRect(0, 0, 400, 400);
g.setColor(Color.black);
g.drawLine(200, 200, nx, ny);
g.drawLine(200, 200, vx, vy);
g.setColor(Color.red);
g.drawLine(200, 200, scX, scY);
g.drawLine(200-1, 200, scX-1, scY);
g.drawLine(200+1, 200, scX+1, scY);
g.drawLine(200, 200-1, scX, scY-1);
g.drawLine(200, 200+1, scX, scY+1);
g.setColor(Color.black);
g.fillOval(nx-2, ny-2, 4, 4);
g.fillOval(vx-3, vy-3, 6, 6);

g.drawString("N = ("+Double.toString(round(n.x))+", "+Double.toString(round(n.y))+")", nx+5, ny+5);
g.drawString("V = ("+Double.toString(round(v.x))+", "+Double.toString(round(v.y))+")", vx+5, vy+5);
g.drawString("N.V = ("+Double.toString(round(nDv))+")", 10, 20);
g.drawString("|N| = ("+Double.toString(round(nAbs))+")", 10, 40);
}

public double round(double val) {
int tmp = (int)(val*100);
return (double)tmp/100.0;
}

class ML extends MouseAdapter {
public void mousePressed(MouseEvent e) {
dragMode = 0;
if((Math.abs(e.getX()-nx) < 5) && (Math.abs(e.getY()-ny) < 5))
dragMode = 1;
else if((Math.abs(e.getX()-vx) < 5) && (Math.abs(e.getY()-vy) < 5))
dragMode = 2;
}
}

class MML extends MouseMotionAdapter {
public void mouseDragged(MouseEvent e) {
if(dragMode == 1) {
nx = e.getX();
ny = e.getY();
repaint();
}
else if(dragMode == 2) {
vx = e.getX();
vy = e.getY();
repaint();
}
}
}
}

class Vect2D {
double x, y;

public Vect2D(double x, double y) {
this.x = x;
this.y = y;
}

public Vect2D dup() {
return new Vect2D(x, y);
}

public void mult(double n) {
x *= n;
y *= n;
}

public double absSqrd() {
return x*x+y*y;
}

public double dot(Vect2D b) {
return x*b.x+y*b.y;
}
}

sealfin
2005.07.16, 06:10 AM
Thanks for the help everybody ;) With everybody's explanations I'm a lttle closer to understanding why the fornula might be usefui, and I was, at last, able to figure out where I was going wrong to get such odd results (which was caused by an error in an area in no way related to the formula :wacko:)

@unknown: if I understand you correctly: Vperpendicular = V - Vparallel

unknown
2005.07.16, 12:33 PM
Ok, its just mazilurik seemed to calculate it some way like this (2, 3) * ((3, 1).(2, 3))/|(2, 3)|^2 and i couldnt see (2, 3) in the diagram anywhere.

Mazilurik
2005.07.16, 12:47 PM
(2, 3) is the vector perpendicular to n; I found the "component" of v perpendicular to n by finding the "component" parallel to a vector perpendicular to n. If you're already finding v-parallel, it's easier to just subtract as Sealfin said.

unknown
2005.07.16, 12:55 PM
by component do you mean length
Itd be good finding the fasted way of calculating them independently because you probably wont need both.

Mazilurik
2005.07.16, 04:34 PM
by component do you mean length

Yes; I used "component" (in quotes; not a technically proper usage of the term) because I like to think of projections in the same sense as the x and y components of the vector, except based on an arbitrary axis.

unknown
2005.07.16, 06:19 PM
Yes, i know exactly what you mean.
The other "component" is 0