I have two squares in 3D space. I want to find the x,y,z angles between them. I started by finding the normal vectors for both of the squares and I am trying to figure out how to get the angle between them.
I am using XNA (C#) Vector3 objects.
I have calculated the normal vectors as follows:
Vector3 normal1 = (Vector3.Cross(sq1.corners[0] - sq1.corners[1], sq1.corners[0] - sq1.corners[2]));
Vector3 normal2 = (Vector3.Cross(sq2.corners[0] - sq2.corners[1], sq2.corners[0] - sq2.corners[2]));
I want to find the euler rotation that will get normal1 facing the same way as normal2
First, you can calculate the axis and amount of rotation (assuming an arbitrary axis):
Vector3 axis = Vector3.Cross(normal1, normal2);
axis.Normalize();
double angle = Math.Acos(Vector3.Dot(normal1, normal2) / normal1.Length() / normal2.Length());
If the normals are normalized, then the calculation of the angle reduces to
double angle = Math.Acos(Vector3.Dot(normal1, normal2));
Then you can transform this to euler angles with the function from here
Related
I am currently working on a ray tracer implementation in c# and I am trying to rotate my ray invertly to the 3Dobject's rotatio for intersectionDetection, but I seem to be doing multiple things wrong here...
my code:
static internal Ray TranformRay(Ray r, Vector3 objectLocation, Vector3 objectRotation, float objectScale)
{
//reverse location tranformation
Vector3 newOrigin = r.origin - objectLocation;
//reverse rotation transformation
objectRotation = -1* objectRotation;
Matrix4x4 ReverseRotation = Matrix4x4.CreateFromYawPitchRoll(Computations.ToRadians(objectRotation.X), Computations.ToRadians(objectRotation.Y), Computations.ToRadians(objectRotation.Z));
newOrigin = Vector3.Transform(newOrigin, ReverseRotation);
Vector3 newDirection = Vector3.Normalize(Vector3.TransformNormal(r.direction, ReverseRotation));
//reverse scale
newDirection /= objectScale;
return new Ray(newOrigin, newDirection);
}
my Ray r is my current ray that needs to be transformed.
3D objects in my world have a location, rotation, scale.
Can anyone tell me what I am doing wrong here?
I assume you want to transform your ray from world-space to object space. You should then compute your object to world transform and call Matrix4x4.Invert to produce the inverse transform. Not all transforms are invertible, but normal affine transformations should be fine.
Edit:
You would typically produce the object to world transform by calling the Matrix4x4 Create Scale/rotation/translation methods and multiply the transforms together. I would also recommend using a quaternion for your rotation instead of euler angles. Quaternions should make it easier to apply multiple successive rotations.
Assuming your ray is origin and direction you would use Vector3.Transform to transform the origin and Vector3.TransformNormal to transform the direction. The later does not apply the translation portion of the matrix.
This assumes you are using System.Numerics library, but most vector libraries should have equivalent functions.
The simple way to get player front position at specific distance
Vectro3 forward = player.transform.forward * distance;
Vector3 newPlayerFronPosition= player.transform.position + new Vector3(forward.x, forward.y, forward.z);
newPlayerFronPosition= new Vector3(newPlayerFronPosition.x, newPlayerFronPosition.y - 4f, newPlayerFronPosition.z);
navigationCanvas.transform.position = newPlayerFronPosition;
navigationCanvas.transform.rotation = camRotationToWatch.transform.rotation;
its actually working fine but the problem is as my player move up or down the navCanvas become appear ver near to my player. How to mainitain spcific distance all the time.?? that no matter player look above or down the navcanvas display at specfic distance.(position)
disatnceUICam = Vector3.Distance(newPlayerFronPosition, player.transform.position);
I also logged the distance and surprisingly it the distance is changing when i am moving up or down. its changing from 6 to 12 as i am looking up to down.
If I've understood you correctly, and you want a point on in front of your player transform on the X Z Plane a set distance from the forward of your player, you should try something like this:
Vector3 horizontalForward = new Vector3(
player.transform.position.x + player.transform.forward.x,
player.transform.position.y,
player.transform.position.z + player.transform.forward.z
).normalized * distance;
I suspect what you're describing is occurring because the transform of your 'player' variable is connected to the direction of your game camera. As the camera looks up, the world position of your forward changes relative to the camera. Using just the X and Z will produce a varying distance as your camera transform rotates around the X Axis. Perhaps this diagram will illustrate what I mean a little better:
Sorry the hypotenuse is a little wonky but you get the idea right?
I am developing a game in XNA (C#), I am wondering how to use 2 versions of transformation. In my idea, the works of this functions are:
(Assume that vectors are originated from Matrix.Identity)
Vector2 resultVec = Vector2.Transform(sourceVector, destinationMatrix); is used for Position vectors transformation.
Vector2 resultVec = Vector2.TransformNormal(sourceVector, destinationMatrix); used for transforming Velocity vectors.
Is that true?. Who knows the explanation in detail, please help!
The simple answer is that -
Vector2.Transform() applies the entire Matrix to the vector while
Vector2.TransformNormal() only applies the Scale and Rotational parts of the Matrix to the vector.
With transformation, functions will multiply the source vector with the produced matrices.
Transform() is used for vectors representing the positions in 2D or 3D space. This will, in detail, take the Transpose (T operator) of the Invert matrix represents your Coordinate.
In Math: retVec = T(M ^ -1) x srcVec.
TransformNormal() used for direction, tangent vectors. This reserves the matrix.
In Math: retVect = srcVec x M.
To transform a vector from one matrix/coordinate to another (say M1 to M2): retVec = Transform by M1 -> then transform by invert of M2:
Vector2 retVec = Vector2.Transform(vectorInSource, M1);
Matrix invertDestMatrix = Matrix.Invert(M2);
outVect= Vector2.Transform(retVec , invertDestMatrix);
I have two objects in a game, which for this purpose can be considered points on a 2d plane, but I use Vector3s because the game itself is 3d.
I have a game camera which I want to align perpendicularly (also on the plane) to the two objects, so that they are both in view of the camera. Due to the nature of the game, the objects could be in any imaginable configuration of positions, so the directional vector between them could have any direction.
Part1: How do I get the perpendicular angle from the two positional vectors?
I have:
Vector3 object1Position; // x and z are relevant
Vector3 object2Position;
I need:
float cameraEulerAngleY;
Part2: Now, because of the way the game's assets are modelled, I want to only allow the camera to view within a 180 degree 'cone'. So if the camera passes a certain point, it should use the exact opposite position the above math might produce.
An image is attached of what I need, the circles are the objects, the box is the camera.
I hope this post is clear and you guys won't burn me alive for being total rubbish at vector math :P
greetings,
Draknir
You'll need to specify a distance from the object line, and an up vector:
Vector3 center = 0.5 * (object2position + object2position)
Vector3 vec12 = object2position - object1position
Vector3 normal = Cross(vec12, up)
normal.Normalize()
Vector3 offset = distance * normal
Vector3 cameraA = center + offset
Vector3 cameraB = center - offset
< choose which camera position you want >
Instead of using Euler angles, you should probably use something like LookAt() to orient your camera.
Assuming Y is always 0 (you mentioned "X and Z" are your relevant components), then you can use some 2-d math for this:
1.Find any perpendicular vector (there are two). You can get this by calculating the difference between the two vectors, swapping the components, and negating one of them.
Vector3 difference = (object1Position - object2Position);
Vector3 perpendicular = new Vector3(difference.z, 0, -difference.x);
2.Using your separating plane's normal, flip the direction of your new vector if it's pointing opposite of intended.
Vector3 separatingPlaneNormal = ...; // down?
if(Vector3.Dot(separatingPlaneNormal, perpendicular ) < 0)
{
perpendicular = -perpendicular ;
}
// done.
Well, for the first bit, if you have points (x1, y1) and (x2, y2) describing the positions of your objects, just think of it in terms of triangles. The angle you're looking for ought to be described by
arctan((y2-y1)/(x2-x1))+90
I don't completely understand what you want to do with the second part, though.
i am making 3D Simulation of Solar System
for every planet i have an instance of class Celestial Body. I am using the following code for revolution and rotation of sun, planets & their moons.
world = Matrix.CreateTranslation(0,0,0) * Matrix.CreateRotationY(rotation) * Matrix.CreateTranslation(position) * Matrix.CreateRotationY(revolution);
rotation is my float variable for rotation of planet around its own axis
revolution is my float variable for revolution of planet in orbit
position is to my vector3 variable to put the body in orbit or at its radius from center e.g postion = new Vector3(70,0,0)
Now it works really fine.
But the problem is i need to locate \ get the position of my planet, to where it has been translated after the Matrix multiplication literally in x,y,x co-ordinates.
How To ? get the current X , Y , Z coordinates of my planet
the other option for me would be to use some maths formula that calculates a 2D circle for me.
I think what you're looking for is Matrix.Translation. This gives you the x, y, z co-odinates of the matrix that it's called on in a Vector3.
So, to get the new position, you should use
Vector3 newPosition = world.Translation;
after your calculations.