I have a vector v = <0,0,-1> and four other vectors that form a "square" at z-index of -1 with side length 2*s, such that the four vectors are:
OA = <-s, s, -1>
OB = < s, s, -1>
OC = <-s,-s, -1>
OD = < s,-s, -1>
Now, consider point P anywhere in the 3D space.
I want to rotate v in such a way that it aligns with the position vector OP of point P, and then apply rotations to the other four vectors such that all four vectors stick together in the same relative position from v.
In other words, the whole "pyramid" of vectors needs to be rotated so that v and OP align.
Screenshot of scenario.
The point P is arbitrary and can be any point in the 3D space. Any help is greatly appreciated!
I don't know if this is to late to answer since you are moving the question, but your question is quite heavily used in 3D graphics work. You should look at the wikipedia article for Rotation Matrix and a good article Rotation About an Arbitrary Axis in 3D. Both of those should give you the understanding of how to manipulate a vector or matrix in 3D.
If I understood the question correctly, you want to rotate your shape ABCD around the point O with the constraint that (OP) and (OV) are aligned.
I think of one way to simply do that algorithmitically without the need to compute any transformations or rotations. Let V',A',B',C',D' be your new points.
1/
Place a point V' such that :
--> ||VO|| -->
V'O = ------ . OP
||OP||
This should not be hard since you know O, P, and V.
2/
Vectors V'O or OP are normal to the plane A',B',C',D'. So you can place the latter points on this plane so that they form a square and include V' as a middle. Some maths are needed here (if interested I can deepen the explanations).
Hope you are allowed to do it this way.
As commented before you better ask maybe http://scicomp.stackexchange.com for nice mathematical solutions.
Related
I do not know how to approach this math problem. Any hint would be much appreciated. Before I could solve such problem using Atan2 method to get two vector angles, when axes c and a are orthogonal.
Problem: there are two non orthogonal to each other vectors c and a. I need to rotate one time around vector c then around vector a to obtain vector v orientation.
Question: how can I get c and a vector rotations, when I only know vector v orientation?
In the image below, c and a vector rotations are both 0.
I was using atan2 for orthogonal system to get two rotations, but in this cases axis A is not perpendicular to C.
double RotationC = Math.Atan2(V_.X, V_.Y);
double RotationA = Math.Atan2(Math.Sqrt(V_.X * V_.X + V_.Y * V_.Y), V_.Z);
I got a vector with n rows with xy coordinates of points. These points form a conture of an given CAD model. Now I want to restore the conture of the model. So I tried to sort the point with the atan2 function.
This is the code I use to sort the points.
std::sort(matrix.begin(), matrix.end(), sort1);
matrix.erase(std::unique(matrix.begin(), matrix.end(), compare2),matrix.end());
matrix.push_back(std::vector<double>(3, 0));
So first I sort the points in the vector matrix. As compare function i use this code
bool sort1(vector<double> const& s1, vector<double> const& s2)
{
return atan2(s1[1],s1[0])<atan2(s2[1],s2[0]);
}
After the vector has been sorted, I just delete duplicates to reduce the size of the vector. The last step is to push back the first point to the end of the vector to close the conture.
For standard models like a cube, or a ball this works fine, but for more complicate models the atan2 function is note working fine.
So this image show the unsorted points.
When I sort the vector I get this conture as result
My first approach was to check the atan2 function but it's working fine. The problem seem to be the result of the atan2 function. So this list shows the actual coordinates and the result of the atan2 function
x y z atan2
-5.44283 -1.94995 0 -2.79758
-5.36969 -1.93228 0 -2.79617
-5.33637 -1.92454 0 -2.79547
-13.15 -4.76500 0 -2.79395
-5.26308 -1.90750 0 -2.79389
-5.22970 -1.90005 0 -2.7931
-5.15626 -1.88364 0 -2.79134
As you can see while the x and y coordinate change the atan2 stays in the same range as the other values. For me that's the problem, why my conture isn't correct. Do I have to add something to my sort function to get the correct results?
One idea i had was to sort the coordinates not just by the atan2, but also by the length of the vector between the point, with the lowest atan2, and all other points. But here's my problem. I would first sort by atan2, and then sort again by the length. But the second sort process would destroy the hole result of the first sort function.
atan2 obviously won't help in generic case. It is mostly good for convex figures. Consider a narrow rectangle with (0,0) inside and an adjacent rectangle and try to sort their points by their atan2.
Have you tried painting a point in the set and then looking for the closest not yet painted point as an iteration step?
If you're dealing with curves only then I'd suggest to use following algorithm:
Define angle range R
Take initial point A, mark it as visited
Find closest to A point B, mark it as visited
Calculate the direction formed by vector [A, B]
Find closest to B unvisited point C in angle range R and mark it visited
Go to step 4 with B as A and C as B
This is not an ultimate solution but it should be able to find basic curves and some polygons. With wider angle range R you can approximate more curved lines.
I am in a lost. I have been trying to implement this code at:http://www.blackpawn.com/texts/pointinpoly/default.html
However, I don't know how is it possible that the cross-product present there between two 2D vectors can result also in a 2D vector. It does not make sense to me. That is also present in some examples of intersection between polygons and lines, in the fine book "Realtime Collision Detection" - where even scalar triples between 2D vectors appear in the codes (see page 189, for instance).
The issue is that, as far as I can think of it, the pseudo cross-product of two 2D vectors can only result in a scalar (v1.xv2.y-v1.yv2.x) or at most in a 3D vector if one adds two zeros, since that scalar represents the Z dimension. But how can it result in a 2D vector?
I am not the first one to ask this and, coincidently, when trying to use the same code example: Cross product of 2 2D vectors However, as can be easily seen, the answer, the original question when updated and the comments in that thread ended up being quite a mess, if I dare say so.
Does anyone know how should I get these 2D vectors from the cross-product of two 2D vectors? If code is to be provided, I can handle C#, JavaScript and some C++.
EDIT - here is a piece of the code in the book as I mentioned above:
int IntersectLineQuad(Point p, Point q, Point a, Point b, Point c, Point d, Point &r)
{
Vector pq = q - p;
Vector pa = a - p;
Vector pb = b - p;
Vector pc = c - p;
// Determine which triangle to test against by testing against diagonal first
Vector m = Cross(pc, pq);
float v = Dot(pa, m); // ScalarTriple(pq, pa, pc);
if (v >= 0.0f) {
// Test intersection against triangle abc
float u = -Dot(pb, m); // ScalarTriple(pq, pc, pb);
if (u < 0.0f) return 0;
float w = ScalarTriple(pq, pb, pa);
....
For the page you linked, it seems that they talk about a triangle in a 3d space:
Because the triangle can be oriented in any way in 3d-space, ...
Hence all the vectors they talk about are 3d vectors, and all the text and code makes perfect sense. Note that even for a 2d vectors everything also makes sense, if you consider a cross product to be a 3d vector pointing out of screen. And they mention it on the page too:
If you take the cross product of [B-A] and [p-A], you'll get a vector pointing out of the screen.
Their code is correct too, both for 2d and 3d cases:
function SameSide(p1,p2, a,b)
cp1 = CrossProduct(b-a, p1-a)
cp2 = CrossProduct(b-a, p2-a)
if DotProduct(cp1, cp2) >= 0 then return true
else return false
For 2d, both cp1 and cp2 are vectors pointing out of screen, and the (3d) dot product is exactly what you need to check; checking just the product of corresponding Z components is the same. If everything is 3d, this is also correct. (Though I would write simply return DotProduct(cp1, cp2) >= 0.)
For int IntersectLineQuad(), I can guess that the situation is the same: the Quad, whatever it is, is a 3d object, as well as Vector and Point in code. However, if you add more details about what is this function supposed to do, this will help.
In fact, it is obvious that any problem stated in 2d can be extended to 3d, and so any approach which is valid in 3d will also be valid for 2d case too, you just need to imagine a third axis pointing out of screen. So I think this is a valid (though confusing) technique to describe a 2d problem completely in 3d terms. You might yourself doing some extra work, because some values will always be zero in such an approach, but in turn the (almost) same code will work in a general 3d case too.
I am coding Tetris in Qt C++ at the moment. The game is almost completed and the only thing I need to add is the rotation. Now what I am struggling with, is the theory behind the rotation. Tetris has 7 different kind of stones ( I, S, Z, L, J, T, O ). Is there any algorithm or anything similar with the rotations from the different shapes ?
What I prefer not to do is having a switch case for 7 different shapes to handle the rotations. Also if a shape like L is rotated it has 4 different positions, which have to be handled different.
So the only thing I have thought of yet is to ask for the shape and then for the position. This would grant me some switches or else if's in a switch... Means a lot to type and a lot to check for the compiler.
P.S. My Stone structure looks like this:( Steine = german for stone, Art = shape )
struct position
{
int X;
int Y;
};
struct Steine
{
struct position* Position;
int Art;
};
You could use a 2D array of bool representation for each shape. Then when you rotate some specific array, you rotate that shape (maybe have the code at the initialization generate all the rotations) and check if any pixel is outside the Tetris borders or if the rotated shape should not be rotated because some of it's pixel would be on the same position as some already existing pixel from previous shapes.
Edit: Yeah, like you said yourself, best is to try on paper/paint to check it out (about the middle point for the rotation). For every shape you then end up with a 3x3 or 4x4. for 3x3 you rotate around it's middle point, for 4x4 around 1x1 for example (where index goes from 0 to 3). That is somewhat how I went for my Tetris 9 years ago or so.
I have been working on Unigine and been trying to code a flight program for weeks, I need to find the direction between two dummy nodes so I can use this direction to rotate the wings of the aircraft. Any explanation would be appreciated.
First you have to calculate the length of the distance between P1 and P2.
distance = abs(P2(y) - P1(y))
Then you can use the angular functions to calculate the angle.
a = sin(distance / length(P12))
As already stated in the comments, the vector from P1 to P2 is given by P = P2 - P1.
The direction can be attained in two ways.
1. Directly compute angle = tan_inverse( P.y() / P.x() ).
In this method however, 1st quadrant and 3rd quadrant are treated in the same way as the signs cancel out.
2.You can normalize this vector to get a unit vector. This is the preferred way since it alleviates the quadrant issues.
P(normalized) = P / (mod(p))
Now you can get the projection of any vector in this direction by just calculating the dot-product by this unit vector.
I just randomly came across this question and therefore it might be useful for someone else to read some more useful information here, regardless of the fact that this question has been asked years ago.
Currently, there is no accepted answer, which could mean that it wasn't very clear what the OP was asking so I'll confront two problems here.
Finding the direction of a vector
I am not very fluent in C++ so I'll
go one abstraction below and write C. Consider the following function
double get_vector_direction (vector v)
{
return atan2(v.q.y - v.p.y, v.q.x - v.p.x); /* atan(ratio) */
}
As simple as this! Also, I like to define vectors this way:
typedef struct POINT { double x, y; } point;
typedef struct VECTOR { point p, q; } vector;
the atan family of functions returns the inverse tangent and this function returns the direction of a vector, which is the measure of the angle it makes with a horizontal line (in radians).
There is a diagram in the answers here that shows the horizontal line as the x component of a vector. It's a simplistic implementation of a Cartesian to Polar coordinates conversion.
Finding the distance between the initial and terminal point
You may also want to know the magnitude of the vector, which could be obtained using the distance formula: sqrt(pow(v.q.x-v.p.x, 2)+pow(v.q.y-v.p.y, 2));
The two functions make up direction() and distance() which are the two most essential functions when dealing with algebra during game development. I would also recommend vectoradd and maybe even vectorsub and of course, radtodeg to convert radians to degrees if the angle is to be showed to the player.
If under the direction you mean angle w.r.t. an arbitrary vector (let it be (p1,p3)), then you can calculate the angle using:
angle = arcos( (p1,p2) * (p1,p3) / (modulus((p1,p2)) * modulus((p1,p3)) ))
where * is the dot product. The angle will be in radians. To change it to degrees you can multiply it by 180/PI (PI=3.1415926...). Modulus is length of vector:
modulus((p1,p2))=square root((p1,p2) * (p1,p2)).
The answer is rather about math than C++ but the implementation of the simple formula is straightforward.