How to convert 3D coordinates to 2d coordinates? [duplicate] - math

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Mapping coordinates from plane given by normal vector to XY plane
How is it possible to get the screen position of a dot, which is located in the 3D space?
The position of the camera is 0,0,0 and it isn't rotated.

Depends on your type of projection.
A standard perspective projection is:
x' = (centre of viewport) - (half width of viewport) * x/z
y' = (centre of viewport) - (half height of viewport) * y/z
That'll give your a 90 degree field of view in both directions and assume you're looking from (0, 0, 0) along z.
It's normal to scale the geometry prior to projection to deal with the fact that the viewport isn't often square. You'll also notice that the results are undefined when z is 0 and will become problematic as z tends towards 0. It also maps both positive and negative z to screen when one of them should be behind the camera. Normally you'd trim geometry (or discard points) with z less than a certain threshold.
In terms of dots, also notice that (assuming you're keeping positive z) if abs(x) > z or abs(y) > z then the dot is offscreen. If you move on to full geometry then you can use that observation to clip it at the screen edges, saving per-pixel tests.

Related

C#/Unity: Rotating triangles in 3D space to form a 2D polygon

I have some triangles in 3D space, which originate from 0,0,0 and extend towards two points p1= -x0, 0, z0 and p2= +x0, 0, z0. This is in Unity, such that +z is the forward axis (i.e. they lie flat). Each triangle is its own mesh, pivot is at 0,0,0.
Now, I would like to rotate these (using Quaternion.LookRotation) such that their ends form a continuous polygon, in case of three triangles a triangle, in case of four triangles a square, etc.
My approach is to calculate the incircle radius of the resulting polygon based on the length of each triangle (which is 2*x0). If I now calculate n points on this circle (where n is the number of triangles I have), I get x/y coordinates which I can directly use to set the "up" axis of each triangle correctly, i.e. Quaternion.LookRotation(Vector3.forward, new Vector3(x,y,0)). This orients the triangle correctly around the z axis, i.e. the center is still on 0,0,1.
However, and this has me stumped, I still need to change the forward axis of the triangles such that they tilt to form the final polygon. I tried using new Vector3(x,y,z0) which gives an almost correct result, but leads to an overlap at the edges. I suspect this is somehow due to the fact that rotation of the triangles effectively changes z0, but I am not sure how to proceed.
My question is, how to calculate the new forward axis such that the triangles align properly?
The problem is setting the forward axis to (x,y,z0), which is wrong since the length of the vector (x,y,z0) does not equal the original length (which is just z0). The z value thus needs to be adjusted such that new Vector(x,y,z1).magnitude == z0. This can be done by calculating
Mathf.Sqrt(Mathf.Pow(z0, 2) - Mathf.Pow(x, 2) - Mathf.Pow(y, 2))
Problem solved.

Rectangle rotation around clipping rectangle center

I have two rectangles where one is a clipping for the other one.
Now I want to rotate the bigger rectangle around the center of the clipping rectangle and adjust x/y values.
How can I calculate the new x/y values after rotation?
I actually just want to rotate the x/y of the bigger box around the center of the smaller box. So the x/y point of the bigger box is relative to the top/left point of the smaller box. I have the width and height of the smaller box so I can calculate x/y point of the big box relative to the center of small box. The angle to rotate is in degrees. The rotation can be any degree, for example 10.
You can do as follows:
determine the angle by which you want to rotate, make sure it suitable for the trigonometric functions (sin(), cos(), ...), i.e. right angle is usually Pi/2
in case of rotating counterclockwise, it is negative
determine the coordinates of c, as cx,cy
process each of the corners of the rectanlge, one by one, for a total of four
for each corner P, currently at coordinates px,py and to move to px2,py2
determine angle between current P and C, using atan2(py-cy, px-cx)
to get from degrees to radians (for use with trigonometry) calculate radians=(pi*degrees)/180.0
add the desired rotation angle to that current angle, to get newangle
determine the distance of current P to C, sqrt((px-cx)(px-cx) + (py-cy)(py-cy))
multiply the distance (which is not changing by rotation), with the appropriate trigonometric function
px2 = distance * cos(newangle)
py2 = distance * sin(newangle)
If you want to rotate a given point P around a point C, which are defined in the same coordinate system you can use a simple rotation matrix. Calculate the P coordinates with respect to C (subtraction), then apply rotation with the matrix and go back to original coordinates by adding C again.
All that matters is the coordinates of the rotation center and the angle.
The most compact formulation is by means of complex numbers (of which I hope you have some understanding; you actually don't need a complex data type, you can expand the formulas).
Let C be the center and α the angle. Then for any point P, the image Q is given by
Q = (P - C) cis(α) + C
where cis(α) = cos(α) + i sin(α).
The inverse rotation is simply given by
P = (Q - C) cis(-α) + C.

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.

Translation coordinates for a circle under a certain angle

I have 2 circles that collide in a certain collision point and under a certain collision angle which I calculate using this formula :
C1(x1,y1) C2(x2,y2)
and the angle between the line uniting their centre and the x axis is
X = arctg (|y2 - y1| / |x2 - x1|)
and what I want is to translate the circle on top under the same angle that collided with the other circle. I mean with the angle X and I don't know what translation coordinates should I give for a proper and a straight translation!
For what I think you mean, here's how to do it cleanly.
Think in vectors.
Suppose the centre of the bottom circle has coordinates (x1,y1), and the centre of the top circle has coordinates (x2,y2). Then define two vectors
support = (x1,y1)
direction = (x2,y2) - (x1,y1)
now, the line between the two centres is fully described by the parametric representation
line = support + k*direction
with k any value in (-inf,+inf). At the initial time, substituting k=1 in the equation above indeed give the coordinates of the top circle. On some later time t, the value of k will have increased, and substituting that new value of k in the equation will give the new coordinates of the centre of the top circle.
How much k increases at value t is equal to the speed of the circle, and I leave that entirely up to you :)
Doing it this way, you never need to mess around with any angles and/or coordinate transformations etc. It even works in 3D (provided you add in z-coordinates everywhere).

How to transform a co-ordinate value in 45 deg-135 deg co-ordinate system to earth co-ordinate system?

I get a series of square binary images as in the picture below,
I want to find the red point, which is the point of intersection of four blocks (2 black and 2 white). For doing so, I use to get the sum of all pixel values along the diagonal directions of the square image, which is 45 deg and 135 deg respectively. The intersection of maximum pixel sum 45 deg line and minimum pixel sum 135 deg line is where my red point is.
Now that I get the co-ordinate of the red point in 45 deg-135 deg co-ordinate system, how to I transform them to earth co-ordinates?
In other words, say I have a point in 45deg-135deg co-ordinate system; How do I find the corresponding co-ordinate values in x-y co-ordinate system? What is the transformation matrix?
some more information that might help:
1) if the image is a 60x60 image, I get 120 values in 45deg-135deg system, since i scan each row followed by column to add the pixels.
I don't know much about matlab, but in general all you need to do is rotate your grid by 45 degrees.
Here's a helpful link; shows you the rotation matrix you need
wikipedia rotation matrix article
The new coordinates for a point after 2D rotation look like this:
x' = x \cos \theta - y \sin \theta.
y' = x \sin \theta + y \cos \theta.
replace theta with 45 (or maybe -45) and you should be all set.
If your red dot starts out at (x,y), then after the -45 degree rotation it will have the new coordinates (x',y'), which are defined as follows:
x' = x cos(-45) - y sin (-45)
y' = x sin (-45) + y cos (-45)
Sorry when I misunderstood your question but why do you rotate the image? The x-value of your red point is just the point where the derivative in x-direction has the maximum absolute value. And for the y-direction it is the same with the derivative in y-direction.
Assume you have the following image
If you take the first row of the image it has at the beginning all 1 and the for most of the width zeroes. The plot of the first column looks like this.
Now you convolve this line with the kernel {-1,1} which is only one nested loop over your line and you get
Going now through this result and extracting the position of the point with the highest value gets you 72. Therefore the x-position of the red point is 73 (since the kernel of the convolution finds the derivative one point too soon).
Therefore, if data is the image matrix of the above binary image then extracting your red point position is near to one line in Mathematica
Last[Transpose[Position[ListConvolve[{-1, 1}, #] & /#
{data[[1]],Transpose[data][[1]]}, 1 | -1]]] + 1
Here you get {73, 86} which is the correct position if y=0 is the top row. This method should be implemented in a few minutes in any language.
Remarks:
The approximated derivative which is the result of the convolution can either be negative or positive. This depends whether it is a change from 0 to 1 or vice versa. If you want to search for the highest value, you have to take the absolute value of the convolution result.
Remember that the first row in the image matrix is not always in top position of the displayed image. This depends on the software you are using. If you get wrong y values be aware of that.

Resources