I want to make a Vector3 rotation in Unity 3D. However, the rotation axes do not make a correct rotation. This is because, I rotate two axes at the same time x and y. I have to separate two rotations. What can I do? Thank you for helping me.
Vector3 start = new Vector3(0,0,0)
Vector3 target = new Vector3(0,0,0)
transform.localEulerAngles = Vector3.Lerp(start,target,time)
Using Vector3 rotation through Vector3.Lerp is prone to gimbal lock problems which is what you might be experiencing.
Best way to lerp through rotation is to use the transform.Rotate(); function.
Alternatively you could use a Quaternion.Lerp(); and create the start and end Quaternions using Quaternion.Euler();. This will yield you the most reliable results since Quaterion rotation is more complex than Vector3 and cancels out any problems you would have in Vector3 rotations.
Edit: Please remember to post entire snippets of your code. Lerp stands for Linear Interpolation and it requires a t that goes from 0 to 1 where 0 is the starting point and 1 is the end point. Many people use this function wrong and come up with problem. Since i cant see your code however i assumed you did this correctly, but i don't know unless i'd see the actual code :)
Related
As the title suggests, I don't know where to start on this problem:
I have a a 2D plane defined by it's origin point in global coordinates(x,y,z) and its axis endpoints as well, but I don't know how to return the local coordinates of a point on the plane
I found this solution but it gave false results:
// given information
`Vector3 origin;
Vector3 planeXDir;
Vector3 planeYDir;
Vector3 pointOnPlane;
Vector3 v = pointOnPlane - origin;
Vector2 positionInPlane = new Vector2(Vector3.Dot(planeXDir, v), Vector3.Dot(planeYDir, v));`
I don't know where I went wrong, maybe a misconception of planeXDir and planeYDir? I'd be happy if someone could explain or give me an easier solution to implement.
That code is correct, so there're misconceptions or mistakes somewhere.
Check that planeXDir & planeDir are orthogonal, and unit (or if not unit that you really want a scaling difference between unit lengths in 3D vs the plane).
I just cannot figure out how to make an a point with a given velocity move around in cartesian space in my visualization while staying around a sphere (planet).
The input:
Many points with:
A Vector3 position in XYZ (lat/lon coordinates transformed with spherical function below).
A Vector3 velocity (eg. 1.0 m/s eastward, 0.0 m/s elevation change, 2.0 m/s northward).
Note these are not degrees, just meters/second which are similar to my world space units.
Just adding the velocities to the point location will make the points fly of the sphere, which makes sense. Therefore the velocities need to be transformed so stay around the sphere.
Goal: The goal is to create some flowlines around a sphere, for example like this:
Example image of vectors around a globe
So, I have been trying variations on the basic idea of: Taking the normal to center of my sphere, get a perpendicular vector and multiply that again to get a tangent:
// Sphere is always at (0,0,0); but just to indicate for completeness:
float3 normal = objectposition - float3(0,0,0);
// Get perpendicular vector of our velocity.
float3 tangent = cross(normal,velocity);
// Calculate final vector by multiplying this with our original normal
float3 newVector = cross(normal, tangent);
// And then multiplying this with length (magnitude) of the velocity such that the speed is part of the velocity again.
float final_velocity = normalize(newVector) * length(velocity);
However, this only works for an area of the data, it looks like it only works on the half of the western hemisphere (say, USA). To get it (partially) working at the east-southern area (say, South-Africa) I had to switch U and V components.
The XYZ coordinates of the sphere are created using spherical coordinates:
x = radius * Math.Cos(lat) * Math.Cos(lon);
y = radius * Math.Sin(lat);
z = radius * Math.Cos(lat) * Math.Sin(lon);
Of course I have also tried all kinds of variations with multiplying different "Up/Right" vectors like float3(0,1,0) or float3(0,0,1), switching around U/V/W components, etc. to transform the velocity in something that works well. But after about 30 hours of making no progress, I hope that someone can help me with this and point me in the right direction. The problem is basically that only a part of the sphere is correct.
Considering that a part of the data visualizes just fine, I think it should be possible by cross and dot products. As performance is really important here I am trying to stay away from 'expensive' trigonometry operations - if possible.
I have tried switching the velocity components, and in all cases one area/hemisphere works fine, and others don't. For example, switching U and V around (ignoring W for a while) makes both Africa and the US work well. But starting halfway the US, things go wrong again.
To illustrate the issue a bit better, a couple of images. The large purple image has been generated using QGIS3, and shows how it should be:
Unfortunately I have a new SO account and cannot post images yet. Therefore a link, sorry.
Correct: Good result
Incorrect: Bad result
Really hope that someone can shed some light on this issue. Do I need a rotation matrix to rotate the velocity vector? Or multiplying with (a correct) normal/tangent is enough? It looks like that to me, except for these strange oddities and somehow I have the feeling I am overlooking something trivial.
However, math is really not my thing and deciphering formula's are quite a challenge for me. So please bear with me and try to keep the language relative simple (Vector function names are much easier for me than scientific math notation). That I got this far is already quite an achievement for myself.
I tried to be as clear as possible, but if things are unclear, I am happy to elaborate them more.
After quite some frustration I managed to get it done, and just posting the key information that was needed to solve this, after weeks of reading and trying things.
The most important thing is to convert the velocity using rotation matrix no. 6 from ECEF to ENU coordinates. I tried to copy the matrix from the site; but it does not really paste well. So, some code instead:
Matrix3x3:
-sinLon, cosLon, 0,
-cosLon * sinLat, -sinLon * sinLat, cosLat,
cosLon * cosLat, sinLon * cosLat, sinLat
Lon/Lat has to be acquired through a Cartesian to polar coordinate conversion function for the given location where your velocity applies.
Would have preferred a method which required no sin/cos functions but I am not sure if that is possible after all.
Ray r = new Ray(this.transform.position, this.transform.eulerAngles);
RaycastHit hit;
if(Physics.Raycast(r, out hit, 3000, 256 /*layer 8*/ )){
That little bit of code won't give me a forward raycast, and I've searched for a number of solutions over multiple hours, to no avail.
So, the above won't give me a straight raycast out the front of the object and I don't know why. I figure it's probably an oversight.
The constructor for Ray takes an origin and a direction. transform.eulerAngles returns a vector of three angles around the x, y, and z axes. "Direction" might sound similar to angles, but it's not: the angles are rotation, not direction. The important distinction is that a direction vector "points" a certain way, but rotation describes how something is oriented. You could create a direction vector using the rotation information, but fortunately Unity can do this for you.
The easiest way to fix this is to use Unity's built-in way to get an object's forward direction vector (as seen in the Ray doc):
// Create a ray from the transform position along the transform's z-axis
Ray ray = new Ray(transform.position, transform.forward);
transform.forward gives you the forward direction vector of transform, meaning that the ray will be shot in the direction the object's facing.
I think my issue is similar to: Orient object's rotation to a spline point tangent in THREE.JS but I can't access the jsfiddle's properly and I struggled with the second part of the explanation.
Basically, I have created this jsfiddle: http://jsfiddle.net/jayfield1979/qGPTT/2/ which demonstrates a simple cube following the path created by a spline using SplineCurve3. Use standard TrackBall mouse interaction to navigate.
Positioning the cube along the path is simple. However I have two questions.
First, I am using the spline.getTanget( t ) where t is the position along the path in order to have the cube rotate (Y axis as UP only). I think I am missing something because even if I extract the .y property of the resulting tangent provided, the rotations still seem off. Is there some nomalizing that needs doing?
Second, the speed is very varied along the path, obviously a lot more points stacked in creating the tighter curves, but I was wondering is there a way to refactor the path to more evenly distribute the spaces between points? I came across the reparametrizeByArcLength function but struggled to find an explanation how to use it.
Any help or explanation for a bit of a maths dummy, would be gratefully received.
To maintain a constant speed, you use .getPointAt( t ) instead of .getPoint( t ).
To get the box to remain tangent to the curve, you follow the same logic as explained in the answer to Orient object's rotation to a spline point tangent in THREE.JS.
box.position.copy( spline.getPointAt( counter ) );
tangent = spline.getTangentAt( counter ).normalize();
axis.crossVectors( up, tangent ).normalize();
var radians = Math.acos( up.dot( tangent ) );
box.quaternion.setFromAxisAngle( axis, radians );
three.js r.144
I am using a 3D engine called Electro which is programmed using Lua. It's not a very good 3D engine, but I don't have any choice in the matter.
Anyway, I'm trying to take a flat quadrilateral and transform it to be in a specific location and orientation. I know exactly where it is supposed to go (i.e. I know the exact vertices where the corners should end up), but I'm hitting a snag in getting it rotated to the right place.
Electro does not allow you to apply transformation matrices. Instead, you must transform models by using built-in scale, position (that is, translate), and rotation functions. The rotation function takes an object and 3 angles (in degrees):
E.set_entity_rotation(entity, xangle, yangle, zangle)
The documentation does not speficy this, but after looking through Electro's source, I'm reasonably certain that the rotation is applied in order of X rotation -> Y rotation -> Z rotation.
My question is this: If my starting object is a flat quadrilateral lying on the X-Z plane centered at the origin, and the destination position is in a different location and orientation where the destination vertices are known, how could I use Electro's rotation function to rotate it into the correct orientation before I move it to the correct place?
I've been racking my brain for two days trying to figure this out, looking at math that I don't understand dealing with Euler angles and such, but I'm still lost. Can anyone help me out?
Can you tell us more about the problem? It sounds odd phrased in this way. What else do you know about the final orientation you have to hit? Is it completely arbitrary or user-specified or can you use more knowledge to help solve the problem? Is there any other Electro API you could use to help?
If you really must solve this general problem, then too bad, it's hard, and underspecified. Here's some guy's code that may work, from euclideanspace.com.
First do the translation to bring one corner of the quadrilateral to the point you'd like it to be, then apply the three rotational transformations in succession:
If you know where the quad is, and you know exactly where it needs to go, and you're certain that there are no distortions of the quad to fit it into the place where it needs to go, then you should be able to figure out the angles using the vector scalar product.
If you have two vectors, the angle between them can be calculated by taking the dot product.