Rectangle Coordinate Rotation - math

I want to rotate rectangles on a centre point rectangle.
For example I have grid of rectangles size 41 x 21
So my centre rectangle is 20 x 10
Now I wanna rotate 22 x 14 to 90 degree along centre rectangle.
What will be formula to rotate 22 x 14.
any help will be great.

Generally, project the cells onto a plane, then use a rotation matrix, then project them cells back into the grid. For this example, its overkill, but works nonetheless.
You need to set your origin to be (21,11) not (0,0) so first translate your points
[x'] := [x - 21]
[y'] [y - 11]
Then apply the rotation matrix transform (note that I'm assuming traditional direction of axes)
[x''] := [ cos(-Pi/2) -sin(-Pi/2) ][x'] = [ y']
[y''] [ sin(-Pi/2) cos(-Pi/2) ][y'] [-x']
Then un-translate the origin. Because your plane wasn't square, the resultant rotated plane is a different shape (it measures 21x41 with origin 11,21). I've assumed this is what you wanted, and you didn't want points to be able to "fall off" the plane.
[x'''] := [x'' + 11]
[y'''] [y'' + 21]
Simplifying the algebra, this boils down to the map
[x] -> [ y ]
[y] [42-x]
Answer
(22,14) rotates to (14,20)
Note: Counting from 1, I make the centre of 41x21 as 21x11, not 20x10?

Related

Rotation in 3D world using an arbitrary coordinate system made out of 3D Vectors

I have a 3D world, and three points. The points are connected by Vectors, and one side of the "triangle" is selected to be the X axis. The other two axes are computed by (v1.y, -v1.x, 0) and the third being v1 x v2 (cross product).
I have an offset vector, U(u1, u2, u3) which is moving an object on the X, Y, Z axis in the alternate coordinate system (the one made out of vectors).
I want to rotate an in-game object (x,y,z axes) in this arbitrary coordinate system. For example (90, 0, 0) would rotate 90 degrees on the X axis in this alternate system, not in the world.
I also do not want to use Quaternions, as I am not using Unity Engine.

Rotate normal vector onto axis plane in 4D

The problem I need to solve is to rotate a 4-simplex given in 4D on the hyperplane with normal vector (1, 1, 1, 1) so that I can draw it in 3D. For instance I need to know the rotation for the regular one having vertices e_i (that is the coordinate vectors), and all its sub-simplices after division.
In order to understand the problem, let's go one dimension back. If you have a 3-simplex in 3D on the hyperplane with normal vector (1, 1, 1) like here (http://upload.wikimedia.org/wikipedia/commons/thumb/3/38/2D-simplex.svg/150px-2D-simplex.svg.png), one can follow the idea of Nosredna to the question
Rotate normal vector onto axis plane
It works fine in 3D, but in 4D there is no cross products, so I cannot extend this answer to my question. On the other hand using rotation matrices I managed to rotate the simplex around the x axes by -45 degree, then rotating around the y axes by around 35 degree (atan(sqrt(2)/2) using the coordinate rotation matrices (http:// upload.wikimedia.org/math/2/8/5/2851c9dc2031127e6dacfb84b96446d8.png).
I also tried to calculate a rotation matrix from axes rotations like in http://ken-soft.com/2009/01/08/graph4d-rotation4d-project-to-2d/ but I could not find out what should be the angles to use. So I used R=rotXU*rotYU*rotZU with the angles pi/4, -atan(sqrt(2)/2, and -pi/6, which looked good, but somehow the result wasn't ok.
Sorry, I could not put the images directly as I'm a newbie...
Thank you for any answer!
There are no rotation axes in 4D, for the same reason there is no cross product: the group of 4D rotations is 6-dimentional, and the space you are rotating is 4-dimentional. Imagine, for example, a simultaneous rotation in XY plane and ZT plane: it has no non-zero stationary vectors, and therefore no axes.
The most appropriate thing to do is to work with the usual transormation matrix, which is applicable in any dimention N:
[ a11 ... a1N d1 ]
...
[ aN1 ... aNN dN ]
[ 0 ... 0 1 ]
Here d1 ... dN represent translations, and the NxN submatrix aIJ represent rotations, dilations, projections, and mirroring. To limit to rotations only make this matrix orthogonal: its product with its own transpose should be the unit matrix. This is a common practice for N=2 and N=3, you just do the same for N=4.
To find the appropriate rotation matrix in your case write down add the requirement that the entire 4th row of an orthogonal 4x4 matrix is zero, and that would give you a bunch of solutions, each being an acceptable answer to your question.

What is the best way to calculate an element's angle when multiple rotates are applied to it

If you do a rotateX(180deg) rotateY(180deg) it's upside down now. So if the mouse is set to move a child element up on drag that child element will now be moving down (depending on how you have things set up).
-webkit-transform: rotateX(?deg) rotateY(?deg) rotateZ(?deg); // where does it point?
ONLY SETUP FOR WEBKIT
Take a look at the fiddle (code is a mess, stripped down). Draw 360 tic marks, arranged in a circle, on your computer monitor. How can you tell what tic mark the arrow is pointing to (assuming the box is at the exact center of the circle)?
A tutorial that covers the basics is here, here.
*edit - the transform-origin being used is at the center of the cube
Note: Everything that follows assumes you are using a vector that passes through the origin, as in this example. In your original example the vector is additionally offset from the origin by the vector [0, 0, 60]. This complicates calculations slightly, so I have used the simplified version in my explanation.
Your vector is currently defined by spherical coordinates Euler angles consecutively applied rotations to a predefined vector. Here is how you can use your rotations to determine the cartesian coordinates of the final vector:
Let us say your vector is [0, 1, 0] (assuming the arrow is 1 unit long and starts at the origin)
Apply x, y and z rotations by multiplying your vector by the rotation matrices described here in any order, replacing θ with the corresponding angle in each case:
                                             
The resulting vector is your original vector transformed by the specified x, y and z rotations
Once you have obtained the rotated vector, finding the projection of the vector on the x-y plane becomes easy.
For example, considering the vector [10, 20, 30] (cartesian coordinates), the projection on the x-y plane is the vector [10, 20, 0]. The angle of this vector from the horizontal can be calculated as:
tan-1(20/10) = 1.107 rad (counter clockwise from the positive x axis)
                    = 63.43 deg (counter clockwise from the positive x axis)
This means the arrow points between the 63rd and 64th "tick marks" counting counter clockwise from the one pointing directly to the right.

Indexing in equilateral triangle grid given simple 2D Cartesian coordinates

I have an equilateral triangle grid constructed like this:
Now, given that 2D coordinate origin point is red dot at very bottom left of image, i need to find index into this triangle grid.
Given Input: X and Y coordinates of point (floating point) of interest, triangle side length and height
Need Output: X and Y index of triangle. (sample indexes seen in image)
Getting Y (row) coordinate of triangle is simple as it is just integer part of (GivenY / TRIANGLE_HEIGHT), but i cant get around to calculate Needed X coordinate without doing to much of operations.
Here is a more explicit answer, for people having issues (or too lazy) to figure out the geometry.
First scale your coordinates to a convenient basis
vec2 pos=(input-origin)/vec2(edge/2,median);
Split your coordinates in integer and fractional part
int x=pos.x, y=pos.y; float u=pos.x-x, v=pos.y-y;
Test for the diagonal (x,y of different parity) or anti-diagonal edge (x,y of same parity)
if(x%2 ^ y%2) { if(v+u<1) x--; } else { if(v-u>0) x--; }
That's it (x,y) is now your face index.
Finding vertex index for each face is a bit more involved.
You have four cases, Here is a list of CCW vertex indices for each face:
face vertices
xy xy xy xy
00 -> 00 10 01
10 -> 11 01 10
01 -> 01 12 02
11 -> 12 01 11
It's easier to see the pattern if you don't add 1 to the y vertex indices, So your final table is:
00 -> 00 10 01
10 -> 11 01 10
01 -> 00 11 01
11 -> 11 00 10
Each column is respectively: x, x, !x, x^y, x, !x. Alternatively, you can simply use a lookup table.
It works with arbitrary face indices, you just need to add (x/2, y) and do your lookup on (x%2, y%2).
In the end, the triangle vertex indices are:
x/2 + x%2, y + x%2; x/2 + !(x%2), y + (x%2^y%2); x/2 + (x%2), y + !(x%2)
with vertex coordinates in your original cartesian space:
origin+vec2(2*x+y%2),y)*vec2(edge/2,median)
More triangles
If you draw a line from the bottom left of 0,0, to the top right of 1,0, the shaded are of the two triangles is now made up of four right angled triangles. Drop a line down from the top right of 1,0 you end up with another right angled triangle and a triangle composed of three right angled triangles height is your original triangle height, width is 1.5 * triangle length, hypotenuse I leave for an exercise for the class.
So then whether it's in the left or right triangle is where your point intercepts that line.
You can precaclc most of this based on triangle length.
Another option is to work out the parallelogram, calc it's centre, move that to the origin, rotatee 30 degrees clockwise, move back, Precalc the transform, you have a diamond with a width of the above hypotenuse, Which side of the middle is which triangle, height of the diamond is triangle length, you'll still need to work or the parallegram as 1.0 and 2,0 will overlap.

How can I find the rotation of a quad in 3D?

I have coordinates for 4 vectors defining a quad and another one for it's normal. I am trying to get the rotation of the quad. I get good results for rotation on X and Y just using the normal, but I got stuck getting the Z, since I've used just 1 vector.
Here's my basic test using Processing and toxiclibs(Vec3D and heading methods):
import toxi.geom.*;
Vec3D[] face = {new Vec3D(1.1920928955078125e-07, 0.0, 1.4142135381698608),new Vec3D(-1.4142134189605713, 0.0, 5.3644180297851562e-07),new Vec3D(-2.384185791015625e-07, 0.0, -1.4142135381698608),new Vec3D(1.4142136573791504, 0.0, 0.0),};
Vec3D n = new Vec3D(0.0, 1.0, 0.0);
print("xy: " + degrees(n.headingXY())+"\t");
print("xz: " + degrees(n.headingXZ())+"\t");
print("yz: " + degrees(n.headingYZ())+"\n");
println("angleBetween x: " + degrees(n.angleBetween(Vec3D.X_AXIS)));
println("angleBetween y: " + degrees(n.angleBetween(Vec3D.X_AXIS)));
println("angleBetween z: " + degrees(n.angleBetween(Vec3D.X_AXIS)));
println("atan2 x: " + degrees(atan2(n.z,n.y)));
println("atan2 y: " + degrees(atan2(n.z,n.x)));
println("atan2 z: " + degrees(atan2(n.y,n.x)));
And here is the output:
xy: 90.0 xz: 0.0 yz: 90.0
angleBetween x: 90.0
angleBetween y: 90.0
angleBetween z: 90.0
atan2 x: 0.0
atan2 y: 0.0
atan2 z: 90.0
How can I get the rotation(around it's centre/normal) for Z of my quad ?
OK. I am frankly still not really clear on what it is you're looking for, but let me try to clarify the problem and then address my best guess as to what you really want and see if that helps.
As mentioned in the comment thread, a rotation is a transformation that maps one set of stuff (eg, vectors A, B, C...) to a different set of stuff (A', B', C'...). We can fully define this transformation in terms of an angle (call it θ) and an axis of rotation we'll call R.
Note that R is not a vector, it is a line. That means it has a location as well as a direction -- it is anchored somewhere in space -- and so you need either two points or a point and a direction vector to define it. For simplicity we might assume that the anchor point is the origin (0,0,0), since the question talks about the major axes X, Y and Z. In general, however, this need not be the case - if you want to determine rotation about arbitrary lines you will usually need to translate everything first so that the axis passes through the origin. (If all you care about is the orientation of your objects, rather than its position, then you can probably gloss over this issue.)
Given a start position A, end position A' and an axis R, it is conceptually straightforward to determine the angle θ (or an angle θ, since rotation is periodic and there are infinitely many θs that will take A to A'), though it can be a little fiddly for general R. In the simplest case, where R is one of the major axes, you can do something like this (for R = Z):
theta0 = atan2(A.x, A.y);
theta1 = atan2(A_prime.x, A_prime.y);
theta = theta1 - theta0;
In any case, it looks from your code as if you have the tools to do this already -- I'm not familiar with toxiclibs, but I would imagine the Vec3D angleBetween method ought to take you most of the way to the answer you want.
However, that presupposes that you know A, A' and R, and it seems like this is the real sticking point with your question. In the first place, you mention only a single set of points, defining an arbitrary quad. In the second, you talk about the normal as defining the centre of rotation. Both of these indicate that you haven't properly specified the problem.
As I have repeated tediously several times, a rotation is from one thing to another. A single set of quad vertices may define either the first state or the second, but not both (unless θ is 0, in which case the question is trivial). If you want to determine "the rotation of the quad", you need also to say "from an earlier position P" or "to a subsequent position Q", which you have not done.
Given that the particular quad in question is a square, you might think that there's an intuitive other position involved, to wit: with the sides axis-aligned. And we can indeed rather easily determine the angle of rotation required to get to that orientation, if we can assume that the quad is a rectangle:
// A and B are adjacent corners of the square
// B - A is the direction of the edge joining them
// theta is the angle between that side and the X axis
// (rotating by -theta around Z should align the square)
theta = atan2(B.x - A.x, B.y - A.y);
But, you made a point of stating that you might be looking at any arbitrary quad, for which there would be no "natural" base position to compare against. And even in the square case it is frankly not good practice to presume a baseline without explicitly declaring it.
Which brings us back to my original question: what do you mean? If you can actually pin that down properly I suspect you will find the problem itself relatively easy to solve.
EDIT: Based on your comments below, what you really want to do is to find a rotation that aligns your quad with one of the major planes. This is equivalent to rotating the quad's normal to align with the axis perpendicular to that plane: eg, to get the quad parallel to the XY plane, align its normal with the Z axis.
This can notionally be done with a single rotation about some calculated axis, but in practice you will decompose it into two rotations about major axes. The first rotates about the target axis until the vector is in the plane containing that axis and one of the others; then rotate around the third axis to get the normal to its final alignment. A verbal description is inevitably clunky, so let's formalise a bit:
Let's say you have a planar object Q, with vertices {v1, v2, v3, ...} (in your quad case there will be four of these, but it could be any number as long as all the points are coplanar), with unit normal n = (x y z)T. For the sake of explanation, let's arbitrarily assume that we want to align the object with the XY plane, and hence to rotate n to the Z axis -- the process would be essentially the same for XZ/Y or YZ/X.
Rotate around Z to get n into the XZ plane. We can calculate the angle required like this:
theta1 = -atan2(x,y);
However, we only need the sine and cosine to build a rotation matrix, and we can calculate these directly without knowing the angle:
hypoXY = sqrt(x*x + y*y);
c1 = x/hypoXY;
s1 = y/hypoXY;
(Obviously, if hypoXY is 0 this fails, but in that case n is already aligned with Z.)
Our first rotation matrix R1 looks like this:
[ c1 s1 0 ]
[ -s1 c1 0 ]
[ 0 0 1 ]
Next, rotate around Y to get n parallel to Z. Note that the previous rotation has moved x to a new position x' = sqrt(x2 + y2), so we need to account for this in calculating our second angle:
theta2 = -atan2(z, sqrt(x*x + y*y));
Again, we don't actually need theta2. And because we defined n to be a unit vector, our next calculations are easy:
c2 = z;
s2 = hypoXY;
Our second rotation matrix R2 looks like this:
[ c2 0 -s2 ]
[ 0 1 0 ]
[ s2 0 c2 ]
Compose the two together to get R = R2.R1:
[ c2c1 c2s1 -s2 ]
[ -s1 c1 0 ]
[ s2c1 s2s1 c2 ]
If you apply this matrix to n, you should get the normal aligned with the Z axis. (If not, check the signs first -- this is all a bit back of an envelope and I could easily have got some of the directions wrong. I don't have time to code it up and check right now, but will try to give it a go later. I'll also try to look over your sketch code then.)
Once that works, apply the same transformation to all the points in your object Q and it should become parallel to (although likely offset from) the XY plane.
Here is the rotation matrix for the z axis
cos(theta) sin(theta) 0
-sin(theta) cos(theta) 0
0 0 1
your vector
the result is the rotated vector

Resources