How to normalize an angle between two limits? - math

Using Fmod, I am able to restrict the calculated angle between [0, maxLimit].
But how do we limit the same angle between [minLimit, maxLimit] ?

Normalize to [0, abs(maxLimit - minLimit)] and then subtract minLimit.

Found the solution,
[0, abs(maxLimit - minLimit)] and add the minLimit.

Related

How to determine if Quadrilateral is convex or not by given points

Is there any way to determine whether quadrilateral is convex or not? (meaning each of its angles are less than 180 degree) by using points. For example A(0,0) B(2,0) C(2,2) D(-1,3). How can we determine that all of the angles in ABCD quadrilateral are less than 180 degrees.
I believe this link answers your question, for any polygon.
In summary, given a list of points [[0, 0], [2, 0], [2, 2], [-1, 3]], check if the direction of the cross product of any two adjacent sides are the same (if so, the polygon is convex).

How to calculate direction vectors from axis-angle rotation?

I'm representing rotations for actors in my rendering engine using a vec4 with axis-angle notation. The first 3 components (x, y, z) represent the (normalized) axis of rotation, and the last component (w) represents the angle (in radians) we have rotated about this axis.
For example,
With axis (0, 1, 0) and angle 0, up is (0, 1, 0) and forward is (0, 0, -1).
With axis (0, 0, 1) and angle 180, up is (0, 0, 1) and forward is (0, -1, 0).
My current solution (which doesn't work), looks like this:
// glm::vec4 Movable::getOrientation();
// glm::vec3 FORWARD(0.0f, 0.0f, -1.0f);
glm::vec3 Movable::getForward() {
return glm::vec3(glm::rotate(
this->getOrientation().w, glm::vec3(this->getOrientation())) *
glm::vec4(FORWARD, 1.0f));
}
I've defined the up direction to be the same as the rotational axis, but I'm having trouble calculating the forward directional vector for an arbitrary axis. What is the easiest way to do this? I'd like to take advantage of glm functions wherever possible.
One thing to keep in mind about axis-angle is that "up" should mean the same thing for all rotations with an angle of 0, as that represents no rotation no matter which direction the axis is pointed ... you can't just say up is in the direction of the axis. The proper way to calculate forward and up is to start with two vectors which represent them, say (1,0,0) for forward and (0,1,0) for up, and then apply the rotation to both those vectors to obtain the new forward and up.

Signed Rotation between two normals in 3D

Given a plane(in my case a triangle) normal N_T and a reference Normal N_R, both have the length 1.
I calculated the rotation_normal
N = N_T x N_R
and now i need to calculate the angle around this rotation_normal, which i get with the following calculation:
angle = acos(<N_T, N_R>), with <x,y> is the dotproduct of x and y
This angle is in the interval of [0°, 180°] and is the smallest angle between both normals.
So my problem is that if i want to rotate my triangle in a manner that its normal is equal to the reference normal, i need to know in which direction (positive or negative) the calculated angle is.
Does anybody know how to get this direction or how to solve this problem in general?
you need to use atan2 (4-quadrant arc tangens)
create reference plane basis vectors u,v
must be perpendicular to each other and lie inside plane
preferably unit vectors (or else you need to account for its size)
so let N=N_T x N_R; ... reference plane normal where the rotation will take place
U=N_T;
V= N x U; ... x means cross product
make them unit U/=|U|; V/=|V|; if they are not already
compute plane coordinates of N_R
u=(N_R.U); ... . means dot product
v=(N_R.V);
compute angle
ang=atan2(v,u);
if you do not have atan2 then use ang=atanxy(u,v);
this will give you angle in range ang=<0,2*M_PI>
if you want signed angle instead then add
if (ang>M_PI) ang-=2.0*M_PI; ... M_PI is well known constant Pi=3.1415...
now if you want the opposite sign direction then just use -ang

How can I calculate a multi-axis SCNVector4 rotation for a SCNNode?

The SCNNode take a rotation using a SCNVector4, which has an angle (w) and a magnitude how that angle applies to each axis (x, y, z). For example, to rotate 45 degrees around the x-axis I'd create a SCNVector4 like this:
SCNVector4Make(1.0f, 0, 0, DEG2RAD(45))
What I'd like to do is rotate it across all three axis, for example: 45 degrees on the x-axis, 15 degrees on the y-axis and -135 degress across the z-axis. Does anyone know the math to calculate the final SCNVector4?
Instead of rotation property, use eulerAngles and specify angle for each axis
You'll need to generate an SCNVector4 for each of the rotations, and then multiply them. Note that the order of operations matters!
http://www.cprogramming.com/tutorial/3d/rotationMatrices.html has a pretty good writeup of the math. Any OpenGL reference that deals with rotation matrices is worth a look too.
If you're not animating the rotation, it might be cleaner to just set the transform matrix directly, like:
node.transform = CATransform3DRotate(CATransform3DRotate(CATransform3DRotate(node.transform, xAngle, 1, 0, 0), yAngle, 0, 1, 0), zAngle, 0, 0, 1);
Do you ask for rotation matrix or how to simply rotate in general? If the second is correct then for example:
[node runAction:[SCNAction rotateByX:0 y:M_PI z:0 duration:0]];

How can I calculate the distance between two points in Cartesian space while respecting Asteroids style wrap around?

I have two points (x1, y1) and (x2,y2) which represent the location of two entities in my space. I calculate the Euclidian distance between them using Pythagoras' theorem and everything is wonderful. However, if my space becomes finite, I want to define a new shortest distance between the points that "wraps around" the seams of the map. For example, if I have point A as (10, 10) and point B as (90,10), and my map is 100 units wide, I'd like to calculate the distance between A and B as 20 (out the right edge of the map and back into the left edge), instead of 80, which is the normal Euclidian distance.
I think my issue is that I'm using a coordinate system that isn't quite right for what I'm trying to do, and that really my flat square map is more of a seamless doughnut shape. Any suggestions for how to implement a system of this nature and convert back and forth from Cartesian coordinates would be appreciated too!
Toroidal plane? Okay, I'll bite.
var raw_dx = Math.abs(x2 - x1);
var raw_dy = Math.abs(y2 - y1);
var dx = (raw_dx < (xmax / 2)) ? raw_dx : xmax - raw_dx;
var dy = (raw_dy < (ymax / 2)) ? raw_dy : ymax - raw_dy;
var l2dist = Math.sqrt((dx * dx) + (dy * dy));
There's a correspondence here between the rollover behavior of your x and y coordinates and the rollover behavior of signed integers represented using the base's complement representation in the method of complements.
If your coordinate bounds map exactly to the bounds of a binary integer type supported by your language, you can take advantage of the two's complement representation used by nearly all current machines by simply performing the subtraction directly, ignoring overflow and reinterpreting the result as a signed value of the same size as the original coordinate. In the general case, you're not going to be that lucky, so the above dance with abs, compare and subtract is required.

Resources