Direction that is perpendicular to a collection of 3D points? - algorithm

I have a collection of 3D points which form an imperfect circle and are stored in the order in which they appear in the circle. I'm positioning an object in the centre of the ring by calculating the mean position of all of the points, which works fine. Now, what I want is for the object in the centre to be facing up/down relative to the rest of the points (i.e perpendicular to the ring).
I've included an image to help clarify what I mean. Does anyone know of an algorithm that would be suitable for this?

You have to compute the plane that your points form and get its normal.
If the points are perfectly coplanar, just get three of them, a, b, and c, and compute two vectors. The normal vector n is the cross product of them:
v1 = b - a;
v2 = c - a;
n = v1 x v2;
If the points are not perfectly coplanar, you can get the plane that best fits the points and then, its normal. You can get the plane by solving a linear equation system of the form Ax=0. Since the general equation of a plane is Ax + By + Cz + D = 0, you get one equation per 3D point, obtaining this system:
| x1 y1 z1 1 | | A | | 0 |
| x2 y2 z2 1 | x | B | = | 0 |
| x3 y3 z3 1 | | C | | 0 |
| ... | | D | | ... |
| xn yn zn 1 | | 0 |
The normal vector is (A, B, C).

Elaborating on a previous answer, you get a system of n equations in 4 unknowns when you solve for the best hyperplane normal vector with n points. You need to set one of the unknown coefficients (say D) to a constant like 1 and move the corresponding data column to the right hand side so that you don't get the trivial solution A=B=C=D=0. You can safely set one coefficient to 1 if it is non-zero because the solution A,B,C,D is still a solution if you scale it. So you get a system of n equations in 3 unknowns where the right hand side is a vector of all -1 instead of the zero vector, and your data matrix is simply your matrix of points and your unknown coefficients are A,B,C. In general such a system is overdetermined if you have more than 3 points so you need to solve it using linear regression. See http://en.wikipedia.org/wiki/Linear_regression to get the matrix formula for solving for the 3 coefficients using least squares best fit.

Related

Calculating the angles of the rotation giving the vertices

I have 4 points (black A, black B, black C and black D) which are the vertices of the rotated red square.
Is it possible to determine what were the three angles (x angle, y angle and z angle) used to rotate the red square into the black square?
In this case, the angles were:
X = 1rad
Y = 0.2rad
Z = 0.3rad
EDIT: I just have the four black points, not the red ones.
The only thing I know about the red square is that it is a square
There is method to find affine matrix needed to transform point set into another one.
Having natrix, you can find angles.
Description for 2D case is here, 3D case is similar.
M * A = B
where
| xa xb xc xd|
A =| ya yb yc yd|
| za zb zc zd|
| 1 1 1 1 |
| xa' xb' xc' xd'|
B =| ya' yb' yc' yd'|
| za' zb' zc' zd'|
| 1 1 1 1 |
To find unknown M, we can multiply both sides of the expression by inverse of A matrix
M * A * Inv(A) = B * Inv(A)
M = B * Inv(A)
But solution is unique for non-complanar point quadruplet - in your case points lie in the same plane, so if solution exists, it is really a family of solutions and you have to choose arbitrary one. (Perhaps angles will be defined unambiguously)

Finding all the rectangles within a given rectangle that do not intersect with an arbitrary shape

I need to find an algorithm to find the least number of overlapping rectangles within a given rectangle R that do not intersect with the union of a set of other rectangles contained within R. These inner rectangles can overlap. Here's a terrible ASCII drawing of an example R:
A-----------------B-------------------------+
| |
| |
| |
| |
| +--------+ |
| |........| |
| |........| |
C +---D........| |
| |.........+--+ |
| |.........| |
| ++........+------+ |
| |...............| |
G +---H...........| |
| |...........| |
| |...........| |
| |...........| |
| +-----------+ |
| |
| |
| |
E-------------I----F------------------------+
The rectangles here would include (A, D), (A, I), (G, F). This seems like a problem for which the solution is well-understood, but for which I simply lack the vocabulary. Any answers, pointers, RTFMs cheerfully and gratefully accepted. Thanks!
EDIT: As per #Paul's observation below, what I'm trying to do is find a set of rectangles that cover the space in R without covering any of polygon comprised of the union of the inner set. If that makes sense.
I believe this is one possible way to solve.
I will refer to the overlapping rectangles as "white", and the ones in the solution as "black"
First of all, let's assume we have a data structure suitable for search on intersection. One possible data structure is an Interval Tree, using points on one of the coordinates as intervals (for example, if a rectangle is defined by two points (x0,y0) and (x1, y1), use (x0, y1) as interval. The link also explain how to extend to higher dimensions (in your case you need 2).
I won't go in the detail of an implementation of such data structure, but let's assume we have one called Rectangles, with the following API defined:
void add(Rectangle r)
void remove(Rectangle r)
Rectangle[] getIntersecting(Rectangle r)
Rectangle[] getAdjacent(Rectangle r)
Ok, now create two instances of Rectangles called black and white. Initialize white with all the white rectangles. Initializie black with the R rectangle (the whole domain).
For each rectangle rw in white get the array arr of intersecting rectangles from black.
For each rectangle rb in black, determine the result of rw-rb. This is a set set of 0, 1, 2, 3 or 4 rectangles, depending on how the two rectangles intersect.
remove rw from white, and add the content of set to it. This may require merging rectangles from set with rectangle already in white, if such rectangles together form a larger rectangle (they're adjacent sharing one side)
remove rb from black
repeat from 1 until there are no more rectangles in black
Using some basic math, we could say the solution to your problem would be the decomposition of the rectilinear polygon R \ union(rs), where union(rs) represents the polygon inside R. Calculating R \ union(rs) can be done using the Greiner-Hormann-algorithm. Note that this step will result in a polygon with holes and - only if the inner polygon contains holes - multiple other polygons. The decomposition is described here (this is only an approximation, but i wasn't able to find a precise algorithm so far).

Applying different transformations to a polygon given a describing transformation matrix

I have a 2D polygon and a 2D transformation matrix M that I use to transform the vertices of the polygon. The matrix may describe...
rotation around z axis,
scaling along x and y,
sheering along x and y axis,
translation along x and y axis.
Since we are in 2D the transformation matrix is of type 3x3. Here as an example a translation matrix by vector t and a rotation by angle a:
M_t = |1 0 t2| M_r = | cos(a) sin(a) 0|
|0 1 t1| |-sin(a) cos(a) 0|
|0 0 1 | | 0 0 1|
In my custom framework I don't have any access to the matrix values but can apply other matrixes in a row:
vertice = ( M_r * M_t ) * vertice
The above formula rotates the vertice around (0, 0) by angle a and then translates it by vector t. I know that matrix multiplications aren't commutative. So the order of multiplications is important.
My problem is now that I want to get a transformation matrix N that reflects a rotation R around the new center of the polygon, followed by a translation T, after applying an unknown transformation matrix M. Or in other words: I want to rotate and translate the polygon relative to its position and rotation given by M.
I can imagine this way of doing it, incorporating an unknown rotation and translation as part of M:
N = R * M * T
My questions are:
Is that mathematically correct?
What about an unknown sheering and scaling as part of M?
Is there a better way of doing this?

Given 2 of 3 vertices that define a tetrahedron and all 3 angles between them, find 3rd vertex

Suppose one of a tetrahedron's four vertices is at the origin and the other three are at the end of vectors u, v, and w. If vectors u and v are known, and the angles between u and v, v and w, and w and u are also known, it seems there is a closed form solution for w: the intersection of the two cones formed by rotating a vector at the u and w angle about the u axis, and by rotating a vector at the v and w angle about the v axis.
Although I haven't been able to come up with a closed form solution in a couple days, I'm hoping it is due to my lack of experience with 3d geometry and that someone with more experience might have a helpful suggestion.
I had the same problem, and found MBo's answer very useful. But I think we can say a bit more about the value of w, because we're free to pick the coordinate system to work in. In particular, if we choose the x-axis to be in the direction of u, and the xy-plane to contain the vector v, then MBo's system of equations becomes:
wx = cos(uw)
vx*wx + vy*wy = cos(vw)
||w|| = 1
and this coordinate system gives
vx = cos(uv), vy = sin(uv)
so immediately we get that
_____________________
( cos(vw) - cos(uv) * cos(uw) + / 2 )
w = ( cos(uw), ----------------------------- , - / 1 - cos (uw) - wy*wy )
( sin(uv) \/ )
The +- on the square root gives the two possible solutions, unless of course 1 - cos^2(uw) - wy^2 <= 0. The division by sin(uv) also highlights a degenerate case when u and v are linearly dependent (point in the same direction).
Another check we can make is that if the vectors u and v are orthogonal, it's known that wy = cos(vw) (see https://math.stackexchange.com/questions/726782/find-a-3d-vector-given-the-angles-of-the-axes-and-a-magnitude). This is what falls out of the expression above (because cos(uv) = 0 and sin(uv) = 1).
There are not enough data to calculate vertice w position. But it is possible to find unit vector w (if it exists). Just use scalar product properties and solve equation system
(I've used (vx,vy,vz) as components of unit (normalized) vector v)
vx*wx+vy*wy+vz*wz=Cos(v,w angle)
ux*wx+uy*wy+uz*wz=Cos(u,w angle)
wx^2+wy^2+wz^2=1 //unit vector
This system can give us: no solutions (cones don't overlap); one solution (cones touching); two solutions (two rays as cones' surfaces intersection)

In a triangulated isometric grid, what triangle is a given point in?

I have a triangulated isometric grid, like this:
(source: mathforum.org)
In my code, triangles are grouped by columns.
As I hover the mouse, I want to calculate what triangle the mouse coordinates are in. Is there a simple algorithm to do that?
What you want to do is turn this into a grid as much as possible because grids are far easier to work with.
The first thing you do is work out what column it's in. You say you store that so it should be easier by doing a simple integer division on the x coordinate by the column width offset by the box start. Easy.
After that you want to work out what triangle it's in (obviously). How you partially turn this into a grid is you pretend that you have a stack of right angle triangles instead of a stack of isometric triangles.
The triangles have a length along the y axis (the side of the column). Divide that number in two and work out how many steps down you are. Based on the number of steps down and if the column is even or odd will tell you if you're looking at:
+--------+
|-_ |
| -_ |
| -_ |
| -_|
+--------+
or the reverse. At this point you only need to determine which side of the line it's on to determine which right triangle it's in, which also tells you which isometric triangle it's in.
You have a couple of options for this.
You could use something like Bresenham's line algorithm to rasterize the hypotenuse and when you hit the column you're in work out if you're above or below that line;
Because you only have two possible grids here (one being the reverse of the other so it's really only one). You could store a array of row values, saying that for column 3, the hypotenuse is at offset 2, whereas for 6 it's at 4 and so on.
You could even use (1) to generate (2) as a fast lookup.
The only other thing to consider is what happens if the mouse cursor is on an edge?
This is similar to what cletus said, but a different way to look at it I suppose.
I am assuming the triangle side is 1.
Suppose you have the grid as below:
y'
/
/__/__/__/__/__/__/
/__/__/__/__/__/__/
/__/__/__/__/__/__/____ x'
(0,0)
If you consider the grid in a co-ordinate system in which the x & y axes are at an angle of 60 degrees, a point whose co-ordinate in the angled system (x',y') will correspond to the coordinate in the orthogonal system (with same origin an general direction of axes) to (x,y).
In your problem, you are given (x,y), we need to find (x',y') and then figure out the triangle.
If i is the unit vector along x and j the orthogonal along y, then we have that
x'* i + y'( i/2 + sqrt(3) * j /2) = xi + yj.
(Basically the unit vector along the 'angled' y axis is i/2 + sqrt(3)/2 * j. The unit vector along the x axis is the same as the normal x-axis, i.e. i).
Thus
x' + y'/2 = x
y' * sqrt(3)/2 = y
Solving gives:
y' = 2*y/sqrt(3)
x' = x - y/sqrt(3)
Assume for now that x' and y' are positive.
Now if c = [x'], the integer part of x'
and r = [y'], the integer part of y'
then in the (angular) grid, the point lies in the cth column and the rth row. (Counting right and up and start counting at 0).
Thus we have narrowed down your point to a parallelogram
____
/\ * /
/___\/
(c,r)
Now in order to find out which triangle it is in you can consider the fractional parts of x' and y'.
{x} = x' - [x'] = x' - c.
{y} = y' - [y'] = y' - r.
Now,
if {x} + {y} > 1, then the point lies in the triangle marked with *.
if {x} + {y} < 1, then the point lies in the other triangle.
if {x} + {y} = 1, then the point lies on the line common to the two triangles.
Hope that helps too.

Resources