I have a line from (a, b) to (x, y), and I would like to draw a line starting at (x, y), with length ℓ, that makes an angle of θ with the original line.
How do I compute the coordinates of the endpoint of this new line? See the diagram:
It's nearly always simpler to use vector algebra for this kind of thing, rather than Cartesian coordinates. Let's start by labelling the points:
Let R(θ) be the matrix that rotates by θ radians counter-clockwise:
Then compute:
v = B − A (the vector from A to B)
v̂ = v / |v| (the unit vector in the direction of v)
ŵ = R(−θ) v̂ (the unit vector in the direction of BC; your rotation is clockwise, so we need R(−θ) here, not R(θ))
w = ℓ ŵ (the vector of length ℓ in the direction of BC)
C = B + w
This approach avoids the need to compute an arctangent, which would need some care (if done naïvely, it runs into trouble when B is vertically above or below A; but most languages have a function like atan2 for handling this case).
In any sensible programming language with a vector library you should be able to write this as a one-liner, perhaps like this:
C = B + (B - A).unit().rotate(-theta) * l
OK, so after a lot of scribbling, I came up with this:
The dashed lines represent lines parallel to the x- and y-axes.
m = x − a
n = y − b
α = tan−1 (n / m)
β = α − θ
p = ℓ cos β
q = ℓ sin β
c = x + p
d = y + q
Related
At the chapter 3 of "Eric Lengyel, Foundations Of Game Engine Development, Volume 1: Mathematics" i can not understand, how to solve exercise 10 ( on the "3.5 Plucker Coordinates" theme).
"Let {v|m1} and {v|m2} be parallel lines having the same direction but different moments. Find a formula for the distance d between theese two lines by considering the triangle formed by the origin and the closest point to the origin on each line"
It seemed simple to me at first, but after many attempts I can't figure out where to start. I've tried different ways, but couldn't get the right answer:
d = (| (v x (m2 - m1) |) / (sqr(v))
maybe someone know, what's the problem.
Thanks!
Table in that chapter (line G) shows "homogeneous point closest to the origin" as
p = (v x m) / v^2
Difference between such points for two lines with m1 and m2 moments is vector
diff = p1-p2 = (v x m1) / v^2 - (v x m2) / v^2 = (v x (m1-m2)) / v^2
Length of this vector is needed distance, because Op1 and Op2 vectors are perpendicular to direction v, points O, p1 and p2 belongs to a plane, perpendicular to lines, and diff=p1-p2 belonging that plane is perpendicular to the lines too, hence it's length is the distance between lines.
P.S. Op1p2 is triangle mentioned in the problem statement
P.P.S
Point p lies on Pluecker line if
p x v = m
multiply both parts by v
v x (p x v) = v x m
transform the left part by Lagrange identity
p * (v.dot.v) - v * (p.dot.v) = p * v^2
(because (p.dot.v)== 0 for perpendicular to the line)
p * v^2 = v x m
p = (v x m) / v^2
As show in the image below, given the point O, A, B and the α, how to get the position of point P in the 3D-space?
Thanks advance!
Let's vectors
b = B - O
a = A - O
p = P - O
It seems that the simplest way is using of SLERP interpolation between vectors b and a.
At first find angle Omega between vectors b and a (for example, through dot product), then apply SLERP
p = Sin(Omega - Alpha) * b / Sin(Omega) + Sin(Alpha) * a / Sin(Omega)
Alternative way - you can find vector of rotation axis (normal to the circle plane) as
k = b x a //vector product
k = k.Normalized //unit vector
and then use Rodrigues' rotation formula to get p=P-O vector
I have a normalized direction vector (from a 3d position to a light position) and I would like this vector to be rotated by some angle so I can create a "cone".
Id like to simulate cone tracing by using the direction vector as the center of the cone and create an X number of samples to create more rays to sample from.
What I would like to know is basically the math behind:
https://docs.unrealengine.com/latest/INT/BlueprintAPI/Math/Random/RandomUnitVectorinCone/index.html
Which seems to do exactly what Im looking for.
1) Make arbitrary vector P, perpendicular to your direction vector D.
You can choose component with max magnitude, exchange it with middle-magnitude component, negate it, and make min magnitude component zero.
For example, if z- component is maximal and y-component is minimal, you may make such P:
D = (dx, dy, dz)
p = (-dz, 0, dx)
P = Normalize(p) //unit vector
2) Make vector Q perpendicular both D and P through vector product:
Q = D x P //unit vector
3) Generate random point in the PQ plane disk
RMax = Tan(Phi) //where Phi is cone angle
Theta = Random(0..2*Pi)
r = RMax * Sqrt(Random(0..1))
V = r * (P * Cos(Theta) + Q * Sin(Theta))
4) Normalize vector V
Note that distribution of vectors is slightly non-uniform on the sphere segment.(it is uniform on the plane disk). There are methods to generate uniform distribution on the sphere but some work needed to apply them to segment (my first attempt before edit was wrong).
Edit: Modification to make sphere-uniform distribution (not checked thoroughly)
RMax = Tan(Phi) //where Phi is cone angle
Theta = Random(0..2*Pi)
u = Random(Cos(Phi)..1)
r = RMax * Sqrt(1 - u^2)
V = r * (P * Cos(Theta) + Q * Sin(Theta))
So I was reading over something on this page (http://gamedeveloperjourney.blogspot.com/2009/04/point-plane-collision-detection.html)
The author mentioned
d = - D3DXVec3Dot(&vP1, &vNormal);
where vP1 is a point on the plane and vNormal is the normal to the plane. I'm curious as to how this gets you the distance from the world origin since the result will always be 0. In addition, just to be clear (since I'm still kind of hazy on the d part of a plane equation), is d in a plane equation the distance from a line through the world origin to the plane's origin?
In the generic case the distance between a point p and a plane can be computed by
<p - p0, normal>
where <a, b> is the dot product operation
<a, b> = ax*bx + ay*by + az*bz
and where p0 is a point on the plane.
When n is of unity length the dot product between a vector and it is the (signed) length of the projection of the vector on the normal
The formula you are reporting is just the special case when the point p is the origin. In this case
distance = <origin - p0, normal> = - <p0, normal>
This equality is formally wrong because the dot product is about vectors, not points... but still holds numerically. Writing down the explicit formula you get that
(0 - p0.x)*n.x + (0 - p0.y)*n.y + (0 - p0.z)*n.z
is the same as
- (p0.x*n.x + p0.y*n.y + p0.z*n.z)
Indeed a nice way to store a plane is to save the normal n and the value of k = <p0, n> where p0 is any point on the plane (the value of k is independent on which point you choose of the plane).
The result is not always zero. The result will only be zero if the plane goes through the origin. (Here let's assume the plane doesn't go through the origin.)
Basically, you are given a line from the origin to some point on the plane. (I.e. you have a vector from the origin to vP1). The problem with this vector is that most likely it's slanted and going to some far away place on the plane rather than to the closest point on the plane. So, if you simply took the length of vP1 you will get a distance that is too big.
What you need to do is get the projection of vP1 onto some vector that you know is perpendicular to the plane. That of course is vNormal. So take the dot product of vP1 and vNormal, and divide by the length of vNormal and you have the answer. (If they are kind enough to give you a vNormal that already is magnitude one, then no need to divide.)
You can work this out with Lagrange multipliers:
You know that the closest point on the plane must be of the form:
c = p + v
Where c is the closest point and v is a vector along the plane (which is thus orthogonal to n, the normal). You are trying for find the c with the smallest norm (or norm squared). So you are trying to minimized dot(c,c) subject to v being orthogonal to n (thus dot(v,n) = 0).
Thus, set up Lagrangian:
L = dot(c,c) + lambda * ( dot(v,n) )
L = dot(p+v,p+v) + lambda * ( dot(v,n) )
L = dot(p,p) + 2*dot(p,v) + dot(v,v) * lambda * ( dot(v,n) )
And take the derivative with respect to v (and set to 0) to get:
2 * p + 2 * v + lambda * n = 0
You can solve for lambda by in the equation above by dot producting both sides by n to get
2 * dot(p,n) + 2 * dot(v,n) + lambda * dot(n,n) = 0
2 * dot(p,n) + lambda = 0
lambda = - 2 * dot(p,n)
Note again that dot(n,n) = 1 and dot(v,n) = 0 (since v is in the plane and n is orthogonal to it). Then subtitute lambda back in to get:
2 * p + 2 * v - 2 * dot(p,n) * n = 0
and solve for v to get:
v = dot(p,n) * n - p
Then plug this back into c = p + v to get:
c = dot(p,n) * n
The length of this vector is |dot(p,n)| and the sign tells you whether the point is in the direction of the normal vector from the origin, or the reverse direction from the origin.
I have a 3D Plane defined by two 3D Vectors:
P = a Point which lies on the Plane
N = The Plane's surface Normal
And I want to calculate any vector that lies on the plane.
Take any vector, v, not parallel to N, its vector cross product with N ( w1 = v x N ) is a vector that is parallel to the plane.
You can also take w2 = v - N (v.N)/(N.N) which is the projection of v into plane.
A point in the plane can then be given by x = P + a w, In fact all points in the plane can be expressed as
x = P + a w2 + b ( w2 x N )
So long as the v from which w2 is "suitable".. cant remember the exact conditions and too lazy to work it out ;)
If you want to determine if a point lies in the plane rather than find a point in the plane, you can use
x.N = P.N
for all x in the plane.
If N = (xn, yn, zn) and P = (xp, yp, zp), then the plane's equation is given by:
(x-xp, y-yp, z-zp) * (xn, yn, zn) = 0
where (x, y, z) is any point of the plane and * denotes the inner product.
And I want to calculate any vector
that lies on the plane.
If I understand correctly You need to check if point belongs to the plane?
http://en.wikipedia.org/wiki/Plane_%28geometry%29
You mast check if this equation: nx(x − x0) + ny(y − y0) + nz(z − z0) = 0 is true for your point.
where: [nx,ny,nz] is normal vector,[x0,y0,z0] is given point, [x,y,z] is point you are checking.
//edit
Now I'm understand Your question. You need two linearly independent vectors that are the planes base. Sow You need to fallow Michael Anderson answerer but you must add second vector and use combination of that vectors. More: http://en.wikipedia.org/wiki/Basis_%28linear_algebra%29