Rotate line around center - rotation

I have to use a propriertary graphics-engine for drawing a line. I can rotate the whole drawing by its origin point (P1). What I want, is to rotate it around its center point(M). So basically that it looks like L_correct instead of L_wrong.
I think, it should be possible to correct it, by moving it from P1 to P2. But I cannot figure out what formula could be used, to determine the distance. It must probably involve the angle, width and height...
So basically my question is, if there is a function to determine x2 and y2 based on my available data?

Let's assume you have a primitive method that rotates a drawing by any given angle phi. What you want is to use that primitive to rotate a drawing D around a point M instead. Here is a sketch of how to proceed.
Translate you drawing by -M, i.e., apply the transformation T(P) = P - M to all points P in your drawing. Let T(D) be the translation of D.
Now use the primitive to rotate T(D) by the desired angle phi. Let R(T(D)) be the result.
Now translate the previous result by M and get the rotated drawing. In other words, use the transformation T'(P) = P + M.
Note that in step 1 above M is mapped to the origin 0, where the rotation primitive is known to work. After rotating in step 2, the opposite translation of step 3 puts back the drawing on its original location as this time 0 is mapped to M.

Related

Algorithm for bending a series of vertices at an arbitrary angle?

I am looking for some information on how to "bend" an arbitrary list of points/vertices similar to the bend modifier you can find in typical 3D modelling programs.
I want to provide a list of points, a rotation focal point, and a "final angle." For my purposes, I will always be saying "points at minimum y of the set will not change, points at maximum y will be rotated at the maximum angle, everything in between is interpolated."
Example Image of starting configuration and desired result, given a 90 degree rotation:
Can anyone suggest a resource that would explain how to go about this? I'm prepared to code it (C++) but I'm wracking my brain on a concept that would make this work. It would be easy to generate the vertices, but the application I'm writing this for takes in user-created content and needs to bend it.
(Edited to add: I don't need a miracle matrix or deep equation solution... if you say something like "for each vertex, do this" that's good enough to get the green checkmark)
Thanks!
You seem to be transforming a straight line to a circular arc, preserving distances between adjacent points.
So, if the point A is the one you want to hold constant, pick another point B to be the center of that circle. (The nearer B is to A, the more severe the bending.) Now for any point C you want to transform, break the vector C-B into the component parallel to A-B (call that component R) and the component perpendicular to it (call that k). The magnitude of R will be the radius of the circle you map C to, and you can transform the magnitude of 'k' into distance along that circle:
theta = |k|/|R|
C` = B + R cos(theta) + k|R|/|k| sin(theta)

Pose from essential matrix, the order of transform

From I've understood, the transform order (rotate first or translate first) yield different [R|t].
So I want to know what's the order of the 4 possible poses you got from essential matrix SVD.
I've read a code implementation of Pose From Essential Matrix(Hartley and Zisserman's multiple view geometry (page 259)). And the author seems to interpret it as rotate first then translate, where he retrieve camera position by using p = -R^T * t.
Also, opencv seems to use trasnlate first then rotate rule. Because the t vector I got from calibrating camera is the position of camera.
Or maybe I have been wrong and the order doesn't matter?
You shouldn't use SVD to decompose a transformation into rotation and translation components. Viewed as x' = M*x = T*R*x, the translation is just the fourth column of M, and the rotation is in the upper-left 3x3 submatrix.
If you feed the whole 4x4 matrix into SVD, I'm not sure what you'll get out, but it won't be useful. (If nothing else, U and V will not be affine.)

What is the general approach of rotating an object towards another object?

In a 2D plane, I have 2 objects (A and B) with 2 coordinates. Their centers are A(xA, yA) and B(xB, yB) (and C(xC, yC)=C(xB, yA) as AC parallel to the OX line and BC is perpendicular on AC). I can manipulate the rotation of an object and I have access to all usual math operations and can use degrees and radians.
I researched but I couldn't find anything explained in detail.
I also tried using the math formula with arccos formula as follows:
I tried to calculate the distance from A to B (AB) using the Pythagoras theorem, then calculate A to C (AC), then calculate cos(angle)=AC/AB, so the final angle to which I would need to rotate object A towards B is arccos(AC/AB).
Problem is this sounds insanely buggy as you can probably get a lot of digits and ruin everything.
So how can I do this? Please explain mathematically. Thanks!
The simplest way to find the angle between two points is to take their arctangent (a.k.a. inverse tangent). You were on the right track with using cosine, but tangent simplifies the process by not requiring the distance between the points to be known.
As such, you'll want to use an atan2 function in your choice of language. The C# Math.Atan2, for example:
double angle = Math.Atan2(B.Y - A.Y, B.X - A.X);
Note: This particular function returns the angle in radians.
Do you want to rotate object A towards B with C like center of the rotation ?
If it's the case you have only to rotate with an angle of 90 degrees because your triangle is special. But if you want to apply a rotation with a specific angle around a specific center you have to use a transformation TRT.
You will find more explanation here.

How do I calculate the up vector in a flight simulator?

I am writing 3D app for OpenGL ES 2.0 where the user sets a path and flies over some terrain. It's basically a flight simulator on rails.
The path is defined by a series of points created from a spline. Every timeslice I advance the current position using interpolation i.e. I interpolate between p0 to p1, then when I reach p1 I interpolate between p1 and p2, then finally back from pN to p0.
I create a view matrix with something analogous to gluLookAt. The eye coord is the current position, the look at is the next position along the path and an up (0, 0, 1). So the camera looks towards where it is flying to next and Z points towards the sky.
But now I want to "bank" as I turn. i.e. the up vector is not necessarily directly straight up but a changes based on the rate of turn. I know my current direction and my last direction so I could increment or decrement the bank by some amount. The dot product would tell me the angle of turn, and the a cross product would tell me if its to the left or right. I could maintain a bank angle and keep it within the range -/+70 degrees, incrementing or decrementing appropriately.
I assume this is the correct approach but I could spend a long time implementing it to find out it isn't.
Am I on the right track and are there samples which demonstrate what I'm attempting to do?
Since you seem to have a nice smooth plane flying in normal conditions you don't need much... You are almost right in your approach and it will look totally natural. All you need is a cross product between 3 sequential points A, B, C: cross = cross(A-B, C-B). Now cross is the vector you need to turn the plane around the "forward" vector: Naturally the plane's up vector is (-gravitation) usually (0,0,1) and forward vector in point B is C-B (if no interpolation is needed) now "side" vector is side = normalized(cross(forward, up)) here is where you use the banking: side = side + cross*planeCorrectionParameter and then up = cross(normalized(side), normalized(forward)). "planeCorrectionParameter" is a parameter you should play with, in reality it would represent some combination of parameters such as dimensions of wings and hull, air density, gravity, speed, mass...
Note that some cross operations above might need swap in parameter order (cross(a,b) should be cross(b,a)) so play around a bit with that.
Your approach sounds correct but it will look unnatural. Take for example a path that looks like a sin function: The plane might be "going" to the left when it's actually going to the right.
I can mention two solutions to your problem. First, you can take the derivative of the spline. I'm assuming your spline is a f(t) function that returns a point (x, y, z). The derivative of a parametric curve is a vector that points to the rotation center: it'll point to the center of a circular path.
A couple of things to note with the above method: the derivative of a straight line is 0, and the vector will also be 0, so you have to fix the up vector manually. Also, you might want to fix this vector so it won't turn upside down.
That works and will look better than your method. But it will still look unnatural for some curves. The best method I can mention is quaternion interpolation, such as Slerp.
At each point of the curve, you also have a "right" vector: the vector that points to the right of the plane. From the curve and this vector, you can calculate the up vector at this point. Then, you use quaternion interpolation to interpolate the up vectors along the curve.
If position and rotation depends only on spline curvature the easiest way will be Numerical differentiation of 3D spline (you will have 2 derivatives one for vertical and one for horizontal components). Your UP and side will be normals to the tangent.

Rotation of Point in 3D Space

I have one problem related to rotation of point in 3D-space.
Suppose I have one point with X, Y and Z coordinates.
And now I want to rotate it, by specifying the rotation in one of these three ways:
By user-defined degree
By user-defined axis of rotation
Around (relative to) user-defined point
I found good link over here, but it doesn't address point 3. Can anyone help me solve that?
All rotations will go around the origin. So you translate to the origin, rotate, then translate back.
T = translate from global coordinates to user-coordinates
R = rotate around the origin (like in your link)
(T^-1) = translate back
point X
X_rotated = (T^-1)*R*T*X
If you have multiple points to rotate then multiply the matrices together:
A = (T^-1)*R*T
X_rotated = A*X

Resources