Find point perpendicular to 2 points - three.js

It seems I am bad at vectors and math or forgot my entire university studies...
I have A, B, C points coordinates (X, Y, Z) where Z = 0.
C is placed in a half distance between A, B points.
D, E points are in parallel to A,B line
Any idea how to find D and E positions with three.js?
A, B, C are Vector3 three.js objects.
Any help is appreciated.

If C is at half the distance between A and B, offset orthogonally, as your figure seems to indicate, then it is simple:
D = C - 0.5AB and
E = C + 0.5AB,
where AB is the vector from A to B.
In THREE.js, you could write it for example like this:
const abHalf = b.clone().sub(a).multiplyScalar(0.5);
const d = c.clone().sub(abHalf);
const e = c.clone().add(abHalf);
though as usual when working with vectors, there are many other ways to calculate it; you may pick your favourite approach.
Is this what you meant?

Related

Calculate if a bullet hits the balloon

I have this problem I can't figure out and need help.
The problem is about calculating how many balloons are hit by a pellet gun. Balloons positions are described by 3D coordinates (X,Y,Z) and radius R. The gunshot is defined by 3D location of the end of the barrel "p" (Px,Py,Pz) and vector "v" (Vx, Vy, Vz) describing the direction barrel is pointing to.
I've tried to implement the solution suggested here: https://math.stackexchange.com/questions/1939423/calculate-if-vector-intersects-sphere
// C = center of sphere
// r = radius of sphere
// P = point on line
// U = unit vector in direction of line
Q = P - C;
a = U*U; // should be = 1
b = 2*U*Q
c = Q*Q - r*r;
d = b*b - 4*a*c; // discriminant of quadratic
if d < 0 then solutions are complex, so no intersections
if d >= 0 then solutions are real, so there are intersections
But the problem with this is that I get intersection with balloons that are positioned behind the gun. How can I modify this algorithm in order to produce the correct result? Or is my approach maybe wrong?
You need to actually solve the quadratic equation defined by your variables a, b and c.
Often, there are math libraries to do this, something like:
(t1,t2) = QuadraticSolve(a, b, c);
You can also do it manually for each parameter:
t1 = (-b + sqrt(b*b - 4*a*c)) / (2*a)
t2 = (-b - sqrt(b*b - 4*a*c)) / (2*a)
If t1 or t2 is positive then that intersection is in front of your gun.

WebGL triangle layout for deformation

I am implementing simple deformation in WebGL by moving vertices up or down, but stumbled upon a problem with the way the triangles are laid out.
I am using the PlaneGeometry in three.js and it uses the following layout for the triangles:
indices.push( a, b, d )
indices.push( b, c, d )
The layout used by three.js is on the left. Mine alternates between both.
Moving vertices up or down results in the image on the left, where, after moving the vertex, the deformation looks off. The blue dot represents the center vertex.
I decided to alternate the triangles using the following code:
if ( ( ix + iy ) % 2 === 0 ) {
// Even segment
indices.push( a, b, d )
indices.push( b, c, d )
} else {
// Odd segment
indices.push( a, b, c )
indices.push( a, c, d )
}
As you can see on the right, it gives me a much better result.
The two questions I have are:
Is the layout I used valid and what is its name?
Is there a better better way to solve this problem?

Algorithm to find a vector parallel to a plane and perpendicular to another vector

I'm trying to derive a formula to extract vector u.
I'm given some initial data:
Plane F with the method to extract its normal n = F->normal().
vector c that does not lie within the plane F and passes through some point E that also does not lie within the plane F.
And some constrains to use:
The desired vector u is perpendicular to the vector c.
Vector u is also perpendicular to some vector r which is not given. The vector r is parallel to the plane F and also perpendicular to the vector c. Therefore, we can say the vectors c, r and u are orthogonal.
Let's denote * as dot product, and ^ operator is cross product between two 3d vectors.
The calculation of the vector u is easy by using cross product: vec3 u = c^r. So, my whole task is narrowed down to how to find the vector r which is parallel to a given plane F and at the same time perpendicular to the given vector c.
Because we know that r is parallel to F, we can use plane's normal and dot product: n*r = 0. Since r is unknown, an infinite number of lines can satisfy the aforementioned equation. So, we can also use the condition that r is perpendicular to c: r*c = 0.
To summarize, there are two dot-product equations that should help us to find the vector r:
r*c = 0;
r*n = 0;
However, I am having hard time trying to figure out how to obtain the vector r coordinates provided the two equations, in algorithmic way. Assuming r = (x, y, z) and we want to find x, y and z; it does not seem possible from only two equations:
x*c.x + y*c.y + z*c.z = 0;
x*n.x + y*n.y + z*n.z = 0;
I feel like I'm missing something, e.g., I need a third constrain. Is there anything else needed to extract x, y and z? Or do I have a flaw in my logic?
You can find the vector r by computing the cross product of n and c.
This will be automatically satisfy r.c=r.n=0
You are right that your two equations will have multiple solutions. The other solutions are given by any scalar multiple of r.

Test if point inside angle

In 2D plane there are four points: O, A, B, P.
O, A, B define an "angle", i.e. two rays, both originating at O, and one passing though A, while the other goes through B. How to tell on which "side" of the angle the point P lies, i.e. whether it is inside the space marked by the two rays?
Note that the points are placed arbitrarily, i.e. the angle might have larger size than π.
This is similar problem to determining which side of line a point lies, as discussed e.g. in comp.graphics.algorithms FAQ (Subject 1.02: How do I find the distance from a point to a line?), but here it is about two rays, instead of one line.
Edit: Apologies for not stating it more explicitly: the angle is oriented, i.e. given P, it might lay on the right of O, A, B, but then it is on the left of O, B, A. Let's say the triangle O, A, B has clock-wise orientation. Again, it is similar to the "which side of line" problem: there it also matters whether the line passes though A, B, or B, A.
An example:
\ \
A B
\ right \ left
left \ right \
O------B---- O------A----
When looking from O, we can split the plane into two regions or "sides".
A region that sweeps ray OA towards ray OB while rotating counterclockwise.
And the rest, i.e. ray OB sweeps counterclockwise to OA.
To check if the point is in which region, you can use
// if isInRegion(O, A, B) is true, P is in the first region.
// otherwise, isInRegion(O, B, A) will be true.
bool isInRegion(O, A, B, P) {
return isCCW(O, A, P) && !isCCW(O, B, P)
}
// ref: http://www.cs.cmu.edu/%7Equake/robust.html
// For more robust methods, see the link.
bool isCCW(a, b, c) {
return ((a.x - c.x)*(b.y - c.y) - (a.y - c.y)*(b.x - c.x)) > 0;
}
I tried it here.
The discussion that follows is meant to detect points inside the hatched area.
There are two cases to be considered:
the angle AOB is smaller than a flat, then the point P must be to the right of AO and to the right of OB (intersection of the two half planes),
the angle AOB is larger than a flat, then the point P must be to the right of AO or to the right of OB (union of the two half planes).
The complete boolean expression is
AO|B . (AO|P . OB|P) + ¬ AO|B . (AO|P + OB|P),
where XY|Z expresses that Z lies on the right of XY, which is equivalent to "XYZ is clockwise" and is determined by the sign of the triangle area.
I don't think it is possible to make the expression simpler, unless you have several P for the same AOB.

Euler's angle rotation

From a three dimensional cartesian coordinate, object A's coordinate can be expressed as xyzwpr (green arrow). And from object A's coordinate world, object B can be also expressed as xyzwpr (blue arrow).
Then can anyone write down the C# code for calculating xyzwpr of object B relative to the original coordinate system (red arrow)?
Say A's coordinate is (30,50,70, -15,44,-80) B (60,90,110, 33,150,-90).
And say the order of the rotation is yaw(z)-> pitch(x) -> roll(y)
--- EDIT ---
Can anyone validate below assumptions?
Assumption for xyz of point B.
xyz of point B, the smaller airplane, can be calculated by adding xyz of point A, the first airplane, and the xyz of B and then applying the 3d rotation of A's wpr on the A's xyz.
The order of doing this is;
1) translate the A point to the origin (subtract A which is translate by -Ax,-Ay,-Az)
2) rotate about the origin (can use 3×3 matrix R0 of A)
3) then translate back. (add A which is translate by +Ax,+Ay,+Az)
Assumption for wpr of point B
is simply succession of rotations of two points. AwApArBwBpBr.
--- SOLVED. A few references with detailed explanation and codes ---
Global frame-of-reference VS Local frame-of-reference
3D matrix rotation about an arbitrary point
Euler to matrix conversion
This question has some issues.
First, I think it's not good practice to request directly for code. Instead, show code you tried, ask for errors in your code, or a better approach, or libraries that may help you.
I would suggest rephrasing your question. Now it looks like "Can anyone do my homework, please?".
What problems are you facing? Maybe you don't want to implement matrix multiplication and you would like to know libraries that already do it, or you don't know how to make the call to atan2.
Once you get matrix multiplication, translation matrix build up, rotation matrix build up and atan2 (made by yourself or by a library), you just have to (pseudocode):
Matrix c = a;
Matrix yaw, pitch, roll;
Matrix pos;
buildTranslationMatrix(pos, x, y, z);
buildRotationZMatrix(yaw, w);
buildRotationXMatrix(pitch, p);
buildRotationYMatrix(roll, r);
mult (c, c, pos); //c = c*pos
mult (c, c, yaw); //c = c*yaw
mult (c, c, pitch);
mult (c, c, roll);
decomposePos(c, x, y, z); // obtain final xyz from c
decomposeAngles(c, w, p, r); // obtain final wpr from c
Note the post-multiplication.
Hope I made a constructive criticism. :)
EDIT
Second assumption is correct.
Maybe I misunderstood the first one, but I think it's wrong. As I am more used to transformation matrices than to euler angles (and you pointed that link), I understand it this way:
To obtain xyz (as well as wpr) I would compute the transformation matrix, which contains all the values. The final transformation matrix of the second plane, in the original coordinate system, is computed as:
M = TA * RA * TB * RB
(TA is A translation matrix of plane A and RA is its rotation matrix)
Transformation matrices can be understood this way:
r r r t
r r r t
M = r r r t
s s s w
We only care about rotation and translation. If you multiply TA*RA:
1 0 0 x r r r 0 r r r x
0 1 0 y r r r 0 r r r y
0 0 1 z * r r r 0 = r r r z
0 0 0 1 0 0 0 1 0 0 0 1
which is how we understand the coordinate system of A. Remember that this means first rotating, as if it were at the origin, and then translating to position x, y, z. Post-multiplicating means intern transformation, transformation in the mobile coordinate system. So, if we continue post-multiplicating, we will composite the final transformation matrix.
Also, matrices are associative, so
M = (TA * RA) * (TB * RB)
is the same as
M = ((TA * RA) * TB) * RB
Recapitulation
xyz will be in the last column of M and wpr will have to be decomposed from 3*3 submatrix of M.

Resources