Calculate x,y position of rotated offset position? - math

I'm looking for a non matrix solution (basic geometry) for how to calculate an absolute x,y position C(x,y) of a rotated offset position. I know the parent position A, the amount of x,y offset B, and the rotation T. In the image axis B is offset from A and rotated from A by T degrees. I need to know C x and y.

(I consider Bx, By as positive values, distances)
Let's find corner point at first:
Px = Ax + By * Sin(T)
Py = Ay - By * Cos(T)
Then find C point
Cx = Px + Bx * Cos(T)
Cy = Py + Bx * Sin(T)
And combine them:
Cx = Ax + By * Sin(T) + Bx * Cos(T)
Cy = Ay - By * Cos(T) + Bx * Sin(T);

Related

Point positioning inside rectangle with only two known vertexes

I'm working on a js widget, and I've come across a positioning problem, which I can't seem to solve with my limited geometry knowledge or by help of Wikipedia/google.
I have a quadrilateral rectangle, which is positioned at an angle. I know its two opposite vertexes and width/height ratio. And there's a point on it, which coordinates I also know.
I need to find how far (in %s of width/height) is that point from rectangle's sides. Is it possible to do so?
Having two corners P1 = (x1,y1) and P2 = (x2,y2) and point Q, you can find diagonal length
dx = (x2 - x1)
dy = (y2 - y1)
dlen = sqrt(dx^2 + dy^2)
and unit direction vector
dx = dx / dlen
dy = dy / dlen
and center of rectangle
cx = x1 + dx/2
cy = y1 + dy/2
Width and height (with known r = w/h ratio)
w = dlen / sqrt(1 + r^2)
h = w / r
Now we need direction of side of length w. Note that given information does not allow to choose exact rectangle orientation from two possible cases.
Angle between diagonal and side
sina = r / sqrt(1 + r^2)
cosa = 1 / sqrt(1 + r^2)
Side direction vector
wx = dx * cosa - dy * sina
wy = dx * sina + dy * cosa
and for the second orientation
wx' = dx * cosa + dy * sina
wy' = -dx * sina + dy * cosa
The second side vector
hx = -wy
hy = wx
Now we can find length of projection of point p onto sides W and H using dot product
qx = q.x - x1
qy = q.y - y1
qw = qx * wx + qy * wy
qh = qx * hx + qy * hy
The last values are coordinates in W-H basis, so value qw varies from 0 for points at the "left" to w for points at the "right" side. You can divide these values by w and h to get percent values.
Note again - there are two possible rectangles and correspondingly two positions of point Q

Rotation About an Arbitrary Axis in 3 Dimensions Using Matrix

I come accross a math problem about Interactive Computer Graphics.
I summarize and abstract this problem as follows:
I'm going to rotation a 3d coordinate P(x1,y1,z1) around a point O(x0,y0,z0)
and there are 2 vectors u and v which we already know.
u is the direction to O before transformation.
v is the direction to O after transformation.
I want to know how to conduct the calculation and get the coordinate of Q
Thanks a lot.
Solution:
Rotation About an Arbitrary Axis in 3 Dimensions using the following matrix:
rotation axis vector (normalized): (u,v,w)
position coordinate of the rotation center: (a,b,c)
rotation angel: theta
Reference:
https://docs.google.com/viewer?a=v&pid=sites&srcid=ZGVmYXVsdGRvbWFpbnxnbGVubm11cnJheXxneDoyMTJiZTZlNzVlMjFiZTFi
for just single point no rotations is needed ... so knowns are:
u,v,O,P
so we now the distance is not changing:
|P-O| = |Q-O|
and directions are parallel to u,v so:
Q = O + v*(|P-O|/|v|)
But I suspect you want to construct rotation (transform matrix) such that more points (mesh perhaps) are transformed. If that is true then you need at least one known to get this right. Because there is infinite possible rotations transforming P -> Q but the rest of the mesh will be different for each ... so you need to know at least 2 non trivial points pair P0,P1 -> Q0,Q1 or axis of rotation or plane parallel to rotation or any other data known ...
Anyway in current state you can use as rotation axis vector perpendicular to u,v and angle obtained from dot product:
axis = cross (u,v)
ang = +/-acos(dot(u,v))
You just need to find out the sign of angle so try both and use the one for which the resultinq Q is where it should be so dot(Q-O,v) is max. To rotate around arbitrary axis and point use:
Rodrigues_rotation_formula
Also this might be helpfull:
Understanding 4x4 homogenous transform matrices
By computing dot product between v and u get the angle l between the vectors. Do a cross product of v and u (normalized) to produce axis of rotation vector a. Let w be a vector along vector u from O to P. To rotate point P into Q apply the following actions (in pseudo code) having axis a and angle l computed above:
float4 Rotate(float4 w, float l, float4 a)
{
float4x4 Mr = IDENTITY;
quat_t quat = IDENTITY;
float4 t = ZERO;
float xx, yy, zz, xy, xz, yz, wx, wy, wz;
quat[X] = a[X] * sin((-l / 2.0f));
quat[Y] = a[Y] * sin((-l / 2.0f));
quat[Z] = a[Z] * sin((-l / 2.0f));
quat[W] = cos((-l / 2.0f));
xx = quat[X] * quat[X];
yy = quat[Y] * quat[Y];
zz = quat[Z] * quat[Z];
xy = quat[X] * quat[Y];
xz = quat[X] * quat[Z];
yz = quat[Y] * quat[Z];
wx = quat[W] * quat[X];
wy = quat[W] * quat[Y];
wz = quat[W] * quat[Z];
Mr[0][0] = 1.0f - 2.0f * (yy + zz);
Mr[0][1] = 2.0f * (xy + wz);
Mr[0][2] = 2.0f * (xz - wy);
Mr[0][3] = 0.0f;
Mr[1][0] = 2.0f * (xy - wz);
Mr[1][1] = 1.0f - 2.0f * (xx + zz);
Mr[1][2] = 2.0f * (yz + wx);
Mr[1][3] = 0.0f;
Mr[2][0] = 2.0f * (xz + wy);
Mr[2][1] = 2.0f * (yz - wx);
Mr[2][2] = 1.0f - 2.0f * (xx + yy);
Mr[2][3] = 0.0f;
Mr[3][0] = 0.0f;
Mr[3][1] = 0.0f;
Mr[3][2] = 0.0f;
Mr[3][3] = 1.0f;
w = Mr * w;
return w;
}
Point Q is at the end of the rotated vector w. Algorithm used in the pseudo code is quaternion rotation.
If you know u, v, P, and O then I would suggest that you compute |OP| which should be preserved under rotations. Then multiply this length by the unit vector -v (I assumed u, v are unit vectors: if not - normalize them) and translate the origin by this -|OP|v vector. The negative sign in front of v comes from the description given in your question:"v is the direction to O after transformation".
P and Q are at the same distance R to O
R = sqrt( (x1-x0)^2 + (y1-y0)^2 + (z1-z0)^2 )
and OQ is collinear to v, so OQ = v * R / ||v|| where ||v|| is the norm of v
||v|| = sqrt( xv^2 + yv^2 + zv^2 )
So the coordinates of Q(xq,yq,zq) are:
xq= xo + xv * R / ||v||
yq= yo + yv * R / ||v||
zq= zo + zv * R / ||v||

How to find position of point that is x unit distant from AB line segment and y unit distant from BC line segment?

I am trying to calculate coordinates of point P, which is x units distant from AB line segment and y units distant from BC line segment.
Edit:
I am trying to write code for general solution.
As parameters, I have three points (coordinates) A, B and C and also two values for distance x and y.
Let's translate all points A,B,C by (-BX, -BY) to set coordinate origin to B, new points are a, 0, c, and I would rename you distances to dc and da.
New coordinates
cy = CY - BY
cx = CX - BX
ay = AY - BY
ax = AX - BX
Then line 0c will have equation
(-cy * x + cx * y) / Sqrt(cx*cx +cy*cy) = 0
line 0a will have equation
(-ay * x + ax * y) / Sqrt(ax*ax +ay*ay) = 0
Let's lc = Sqrt(cx*cx +cy*cy) and la = Sqrt(ax*ax +ay*ay) (lengths of BC and BA segments)
If point p=(px, py) lies at dc distance from line 0c, and at da distance from line 0a, then
Abs(-cy * px + cx * py) = dc * lc
Abs(-ay * px + ax * py) = da * la
If your points always form counterclockwise order of BC, BP, BA rays, you may use this sign combination only and find single solution:
-cy * px + cx * py = dc * lc
-ay * px + ax * py = - da * la
Solve this linear system for px and py, in the end shift coordinates back by BX, BY
PX = px + BX
PY = py + BY
P.S. In extra case angle ABC=180 system has no solution for da<>dc or infinite number of solutions for da=dc

computing tangent and bitangent vectors via partial derivatives

I'm trying to implement a simple water simulation, with theory from GPU Gems 1 chapter 1.
if you imagine a 3D plane (flat in the xz plane, with y denoting height at any point), the height field function is given as:
where:
Wavelength (w): the crest-to-crest distance between waves in world space.
Amplitude (A): the height from the water plane to the wave crest.
Speed (S): the distance the crest moves forward per second.
Direction (D): the horizontal vector perpendicular to the wave front along which the
crest travels.
This is straightforward to implement.
Please note the article in GPUGems uses the z direction for height, but this isn't standard for graphics (normally, x is width, y is height, z is depth). So I'll refer to the xz direction meaning the flat/horizontal plane directions.
So, having computed the height (y) value at any given point, I need to compute the bitangent and tangent vectors to that point, in order that I can compute a normal vector, which I need for lighting equations.
The bitangent and tangent vectors are partial derivatives in the x and z directions (y is the heightfield value).
So my question is, how can I take a partial derivative in the x and then the z directions for the height field function?
The article says that the partial derivative for the x direction is given by
I understand the concept of taking a partial derivative from this video:, but I don't know how to take the partial derivative of my heightfield function.
Can someone explain it (like I'm 5) - My grasp of maths isn't great!
You want to derive the following equation:
W(x) = A * sin(w * (D.x * x + D.y * z) + t * phi)
= A * sin(w * D.x * x + w * D.y * z + t * phi)
which is the above formula with the expanded dot product. Because we want to find the derivative with respect to x, all other variables (except x) are considered constant. So we can substitute the constants:
c1 = A
c2 = w * D.x
c3 = w * D.y * z + t * phi
W(x) = c1 * sin(c2 * x + c3)
The derivative is:
W'(x) = c1 * c2 * cos(c2 * x + c3)
Reverting the substitution we get:
W'(x) = A * w * D.x * cos(w * D.x * x + w * D.y * z + t * phi)
which describes the y-component of the tangent at a given position.
Similarly, the bitangent (derivative with respect to z) can be described by
W'(z) = A * w * D.y * cos(w * D.y * z + w * D.x * x + t * phi)
Therefore:
tangent = (1, W'(x), 0)
= (1, A * w * D.x * cos(w * D.x * x + w * D.y * z + t * phi), 0)
bitangent = (0, W'(z), 1)
= (0, A * w * D.y * cos(w * D.y * z + w * D.x * x + t * phi), 1)

Are my equations correct? Rotate on sphere from lat/long points A to B, where will point C be?

I’ve written the below python script. The idea is to calculate the new location of point C after you rotate the globe from point A to point B. I first calculate point P, which is the rotation pole. With calculating point P already something goes wrong. With the following input f.e. I would assume point P to be having latitude 90 or –90.
I asked this question before here: Rotate a sphere from coord1 to coord2, where will coord3 be?
But I figured it's better to ask again with the script included ;)
# GreatCircle can be downloaded from: http://www.koders.com/python/fid0A930D7924AE856342437CA1F5A9A3EC0CAEACE2.aspx?s=coastline
from GreatCircle import *
from math import *
# Points A and B defining the rotation:
LonA = radians(0)
LatA = radians(1)
LonB = radians(45)
LatB = radians(1)
# Point C which will be translated:
LonC = radians(90)
LatC = radians(1)
# The following equation is described here: http://articles.adsabs.harvard.edu//full/1953Metic...1...39L/0000040.000.html
# It calculates the rotation pole at point P of the Great Circle defined by point A and B.
# According to http://www.tutorialspoint.com/python/number_atan2.htm
# atan2(x, y) = atan(y / x)
LonP = atan2(((sin(LonB) * tan(LatA)) - (sin(LonA) * tan(LatB))), ((cos(LonA) * tan(LatB)) - (cos(LonB) * tan(LatA))))
LatP = atan2(-tan(LatA),(cos(LonP - LonA)))
print degrees(LonP), degrees(LatP)
# The equations to calculate the translated point C location were found here: http://www.uwgb.edu/dutchs/mathalgo/sphere0.htm
# The Rotation Angle in radians:
gcAP = GreatCircle(1,1,degrees(LonA),degrees(LatA),degrees(LonP),degrees(LatP))
gcBP = GreatCircle(1,1,degrees(LonB),degrees(LatB),degrees(LonP),degrees(LatP))
RotAngle = abs(gcAP.azimuth12 - gcBP.azimuth12)
# The rotation pole P in Cartesian coordinates:
Px = cos(LatP) * cos(LonP)
Py = cos(LatP) * sin(LonP)
Pz = sin(LatP)
# Point C in Cartesian coordinates:
Cx = cos(radians(LatC)) * cos(radians(LonC))
Cy = cos(radians(LatC)) * sin(radians(LonC))
Cz = sin(radians(LatC))
# The translated point P in Cartesian coordinates:
NewCx = (Cx * cos(RotAngle)) + (1 - cos(RotAngle)) * (Px * Px * Cx + Px * Py * Cy + Px * Pz * Cz) + (Py * Cz - Pz * Cy) * sin(RotAngle)
NewCy = (Cy * cos(RotAngle)) + (1 - cos(RotAngle)) * (Py * Px * Cx + Py * Py * Cy + Py * Pz * Cz) + (Pz * Cx - Px * Cz) * sin(RotAngle)
NewCz = (Cz * cos(RotAngle)) + (1 - cos(RotAngle)) * (Pz * Px * Cx + Pz * Py * Cy + Pz * Pz * Cz) + (Px * Cy - Py * Cx) * sin(RotAngle)
# The following equation I got from http://rbrundritt.wordpress.com/2008/10/14/conversion-between-spherical-and-cartesian-coordinates-systems/
# The translated point P in lat/long:
Cr = sqrt((NewCx*NewCx) + (NewCy*NewCy) + (NewCz*NewCz))
NewCLat = degrees(asin(NewCz/Cr))
NewCLon = degrees(atan2(NewCy, NewCx))
# Output:
print str(NewCLon) + "," + str(NewCLat)

Resources