Finding the endpoint of a vertex given startpoint of vertex and midpoint of shape - math

Given that:
The shape is a regular polygon in 3D space
The start point (the end of one arbitrary vertex of the shape) is known
the point in the middle of the shape (not on an edge - equidistant from all corners) is known
the angle at each corner (((numEdges-2)*PI)/numEdges), the radius of the shape (distance from a corner to the midpoint = sqrt(dx^2 + dy^2 + dz^2)), and the length of each edge (radius*2*sin(pi/numEdges)) can be calculated.
Given all this information, is it possible to fill in the blanks, if you like, and work out the rest of the start/endpoints for each vertex of the shape?
I can sort of see the beginnings of the logic in 2D, but in 3D i'm lost.

I'm thinking it can't be done, since your knowns do not uniquely identify your polygon. The points you do know define a unique line, but I can provide infinitely many congruent polygons with the same vertex and center, all rotations of one another about this line.

Related

Calculate field of view of simple polygon from a point

Given a non-self-intersecting polygon as a list of points (p1...pn), and a point (A) outside that polygon:
I want to calculate the total angular field of view covered by the polygon from the point, as well as the direction from the point towards the middle of that field of view (as either a vector or angle from horizontal).
Visually, I want the angle Θ and direction of the green vector:
Diagram
I tried finding the minimum and maximum angles from horizontal to each of the polygon points, but I don't know how to tell which is the start of the range and which is the end. Assuming the smaller angle is the start gives incorrect results from the left of a simple box.
I'm guessing the solution will have something to do with whether the polygon points are in clockwise or counterclockwise order.
Whether the polygon goes clockwise or counterclockwise doesn't matter. What matters is that the extent of any edge, as seen from the point, must be less than π radians. That will tell us whether the edge -- as seen from the point -- goes counterclockwise from A to B, or from B to A.
For example, suppose the bearings (in radians) from the point to the vertices are {0, 2π/5, 4π/5, 6π/5, 8π/5}. If the edges are represented by the (unordered) pairs (A,C), (A,E), (B,D), (B,E), (C,D). Then the edges run:
0->4π/5
2π/5->6π/5
4π/5->6π/5
8π/5->0
8π/5->2π/5
So the range of the polygon is [8π/5, 6π/5].

Dividing space outside of convex polygons into horizontally spanning quadrilaterals

I'm looking for an algorithm that can take an area containing a set of non-overlapping convex polygons as input, and break the space outside of the polygons into a set of non-overlapping convex quadrilaterals. The quadrilaterals need to have the property that they (individually) use as much horizontal space as possible.
Here's the input:
Here's the desired output:
I feel like I have seen some variation of this algorithm used to calculate regions to be flood-filled in very old paint programs. Is there a pleasant way to do this in better than O(n^2) time?
Edit: I realize there are some triangles in the output. I should probably state that quadrilaterals are the desired output, falling back to triangles only when it's physically impossible to use a quad.
I came up with a solution to this. In order to solve this efficiently, some sort of spatial data structure is needed in order to query which polygons are overlapped by a given rectangular area. I used a Quadtree. It's also necessary for the polygon data structure being used to be able to distinguish between internal and external edges. An edge is internal if it is common to two polygons.
The steps are as follows (assuming a coordinate system with the origin in the top-left corner):
Insert all polygons into whatever spatial data structure you're using.
Iterate over all polygons and build a list of all of the Y values upon
which vertices occur. This has the effect of conceptually dividing up
the scene into horizontal strips:
Iterate over the pairs of Y values from top to bottom. For each
pair (y0, y1) of Y values, declare a rectangular area a with
the the top left corner (0, y0) and bottom right corner
(width, y1). Determine the set of polygons S that are
overlapped by a by querying the spatial data structure. For
each polygon p in S, determine the set of edges E of p
that are overlapped by a. For best results, ignore any edge in
E with a normal that points directly up or down. For each
edge e in E, it's then necessary to determine the pair of
points at which e intersects the top and bottom edges of a.
This is achieved with a simple line intersection test,
treating the top and bottom edges of a as simple horizontal
line segments. Join the intersection points to create a set of
new line segments, shown in red:
Create vertical line segments L0 = (0, y0) → (0, y1) and
L1 = (width, y0) → (width, y1). Working from left to right,
gather any line segments created in the preceding step into pairs,
ignoring any line segments that were created from internal edges.
If there were no intersecting external edges, then the only two
edges will be L0 and L1. In this example strip, only four
edges remain:
Join the vertices in the remaining pairs of edges to create
polygons:
Repeating the above process for each horizontal strip achieves
the desired result. Assuming a set of convex, non-overlapping
polygons as input, the created polygons are guaranteed to be
either triangles or quadrilaterals. If a horizontal strip contains
no edges, the algorithm will create a single rectangle. If no
polygons exist in the scene, the algorithm will create a single
rectangle covering the whole scene.

What are barycentric calculations used for?

I've been looking at XNA's Barycentric method and the descriptions I find online are pretty opaque to me. An example would be nice. Just an explanation in English would be great... what is the purpose and how could it be used?
From Wikipedia:
In geometry, the barycentric coordinate system is a coordinate system in which the location of a point is specified as the center of mass, or barycenter, of masses placed at the vertices of a simplex (a triangle, tetrahedron, etc).
They are used, I believe, for raytracing in game development.
When a ray intersects a triangle in a normal mesh, you just record it as either a hit or a miss. But if you want to implement a subsurf modifier (image below), which makes meshes much smoother, you will need the distance the ray hit from the center of the triangle (which is much easier to work with in Barycentric coordinates).
Subsurf modifiers are not that hard to visualize:
The cube is the original shape, and the smooth mesh inside is the "subsurfed" cube, I think with a recursion depth of three or four.
Actually, that might not be correct. Don't take my exact word for it, but I do know that they are used for texture mapping on geometric shapes.
Here's a little set of slides you can look at: http://www8.cs.umu.se/kurser/TDBC07/HT04/handouts/HO-lecture11.pdf
In practice the barycentric coordinates of a point P in respect of a triangle ABC are just its weights (u,v,w) according to the triangle's vertices, such that P = u*A + v*B + w*C. If the point lies within the triangle, you got u,v,w in [0,1] and u+v+w = 1.
They are used for any task involving knowledge of a point's location in respect to the vertices of a triangle, like e.g. interpolation of attributes across a triangle. For example in raytracing you got a hitpoint inside the triangle. When you want to know that point's normal or other attributes, you compute its barycentric coordinates within the triangle. Then you can use these weights to sum up the attributes of the triangle's vertices and you got the interpolated attribute.
To compute a point P's barycentric coordinates (u,v,w) within a triangle ABC you can use:
u = [PBC] / [ABC]
v = [APC] / [ABC]
w = [ABP] / [ABC]
where [ABC] denotes the area of the triangle ABC.

How to compute a pair of closest points on two 3d circles?

I have two 2d circles in 3d space (defined by a center, normal, and radius) and I'm trying to come up with a pair of points that is one of the set of closest pairs of points. I know that there are anywhere from 1 to an infinite number of point pairs, I just need a single matching pair.
Is there a simple way to do that? Precision is not essential. The radius of both circles are the same, non-zero value.
In case the background is helpful, my overall algorithm takes in a NURBS curve in space and extrudes a 2d polygon along the curve, yielding a deformed cylinder. I just sample several points along the curve. The normal of each circle is the NURBS curve tangent, and I'm trying to figure out how to align adjacent samples, so I don't get weird twisting. It seems that the closest points on adjacent samples should be aligned.
Thanks for all the responses here.. this part of the project got a little delayed, which is why I haven't tested all the answers yet. I'll be sure to toss up some images here and mark an answer when I get to work on this again.
What you are really trying to compute is the pair of points that minimizes the distance between points that lie on 2 different circles in 3 dimensions. The method that you should be employing to find the exact solution (as in almost all optimization problems) is to represent the distance as a function of all possible points and to take its derivate with respect to the independent variables and set the resulting expressions to 0. Since you have 2 circles, you will have 2 independent variables (ie. the angle of a point on one circle and one on the other circle). Once you have solved the minimization equations you would have also found the points on the circles that will satisfy your constraint. (Basically you will find the angles on the circles for the pair of points you are looking for.)
I have found a paper online (at this site) that rigorously goes through with the calculations but the end result is solving an 8th order polynomial equation. You might try to simplify the equations and come up with a less exact solution that satisfies your needs.
There is also an paper that claims to have a much faster algorithm for finding the distance between two circles in 3d; however, I cannot view the contents and, thus, cannot tell if it also gives you the pair of points that satisfy that condition.
UPDATE: Having re-read your question, I see that even though you are asking for a way to find the closest pair of points on two circles in 3 dimensions, I think, you should pay more attention to the properties of the NURBS curve that you are trying to extrude the 2D polygon along. You mention that the orientation of the circle at a given point on the curve is specified by the tangent vector at that point. However, there is more to 3D curves than just the tangent vector; there is the normal (or curvature) vector that points towards the center of curvature of the curve at a given point and then there is the torsion vector that basically specifies the amount of "lift" of the curve from the plane given by the tangent and the normal vectors. All of these define a (what is called) Frenet frame. You can read up more on these at the Wikipedia article.
My suspicion is that you can achieve the effect you desire by joining the points of consecutive circles that each lie along the the normal vector direction of the underlying 3D curve. That way, you will have twisting only when the curve is actually twisting, ie when the torsion vector is non-zero and the normal vector is changing direction as well. In other circumstances, this should satisfy your actual need.
You probably don't need the overkill of finding closest points on consecutive circles.
For what you describe, it is sufficient to select a point on the perimeter of the first circle and find the point on the perimeter of each circle along that is closest to the one selected for the previous circle; this will completely constrain the polygonization, with no twisting, and should be much easier to solve than the general case - simply find the point on the plane containing the second circle that is closest to that selected in the first, and intersect the line passing through that point and the second circle's center with the second circle's perimeter.
However, this might not yield as pleasing a polygonisation for the extruded cylinder as keeping the polygon area constant as possible, and to do that will require some twisting between adjacent circles.
Yikes, unless the circles happen to be on the same plane or parallel planes I think the only way to do it is to find a minimum on the equation of the distance between two points on the circle.
http://www.physicsforums.com/showthread.php?t=123168
That link shows how to get the equation of each circle in 3D space, then minimize for the distance formula between those equations. Not pretty though, hopefully someone will come up with something more clever.
I think with the two closest points you might still get weird twisting... An extreme example: Let's assume both circles have the R=1. If the first circle's centre is O, and it is sitting on X-Y plane, and the second circle's centre is sitting at X=1,Y=0,Z=0.01, and it just slightly tilted in the growing direction of X, the closest points on the two circles will for sure get the "weird twist" you are trying to avoid. Since the closest points would not get you the weird twist in case the second circle is at X=0,Y=0,Z=0.01 and is equally tilted, then at some point the statements "aligned to two closest points on two circles" and "no weird twisting seen" no longer correspond to each other.
Assuming this can happen within the constraint of NURBS, here's another idea. In the start, take the three points on the NURBS curve - two that belong to the centers of your circles, and the third one precisely inbetween. Draw a plane between the three. This plane will cross the two circles at 4 points. Two of these points will be on the same "side" of the line that connects the centers of the circles - they are your alignment points.
For the next alignment points you would take the alignment point of the "previous circle", and draw the plane between the center of the "previous circle", this alignment point, and the center of the "new circle". From this you get the "next alignment point" based on the intersection with the other circle.
Next step - "previous circle" = "new circle", and the "new circle" - your next one according to the NURBS curve.
If the radii from the centers of the circles to the selected alignment points cross, you know you the picture will look a bit ugly - that's the scenario where with the "closest point" algorithm you'd still get the weird twisting.
I think the coordinates of the point on the circle that is intersection with the plane going via its center should be easy to calculate (it's a point on the line made by intersection of the two planes, one of the circle and the target plane; at the distance R from the center).
I don't have the rigorous proof to fully assert or deny the above - but hopefully it helps at all, and I think it should be quick enough to verify, compared to calculating the closet points on the two circles... (If there are any flaws in my logic, the corrections in the comments are very welcome).
The thread here, mentioned in another answer gives the parameterization formula for a 3D circle: P = R cos(t) u + R sin(t) nxu + c, where u is a unit vector from the centre of the circle to any point on the circumference; R is the radius; n is a unit vector perpendicular to the plane and c is the centre of the circle, t goes from 0 to 2pi, and by nxu I mean "n cross u". Parameterize one circle this way, and another similarly with a different parameter, say s. Then each point Pt on the first circle will have coordinates in the variable t, and each point Ps on the second circle will have coordinates in the variable s.
Write the distance function d(s,t) between Ps and Pt in the usual way (or better, the square of the Euclidean distance so you don't have to mess with the square root when you take derivatives). The graph of this function d of two variables is a surface over a 2pi by 2pi square in the s,t plane, and it's minimum is what you're after. You can determine it with the standard calculus methods, e.g. as explained here.
Extend the circles to planes (using the center points and normals). If the planes are parallel, then any points will do. If the planes are not parallel, then they intersect in a line. Construct the plane through the two centers of the circles perpendicular to the line. The two circles intersect this new plane in four points. These four points are the two nearest points and the two farthest points on the circles.
Isn't this just a matter of constructing the line between the two centers of the circles/spheres and finding the intersection of the line and the circles? The solutions that are closest are it (unless the circle intersect, then the answer depends on how you want to interpret that case).

How can a convex polygon be broken down into right triangles aligned on the X- and Y- axes?

Given a convex polygon represented by a set of vertices (we can assume they're in counter-clockwise order), how can this polygon be broken down into a set of right triangles whose legs are aligned with the X- and Y-axes?
Since I probably lack some math terminology, "legs" are what I'm calling those two lines that are not the hypotenuse (apologies in advance if I've stabbed math jargon in the face--brief corrections are extra credit).
I'm not sure about writing an algorithm to do this but it seems entirely possible to do this for any convex polygon on a piece of paper. For each vertex project a line vertically or horizontally from that vertex until it meets another of these vertical or horizontal lines. For vertices with small changes in angle, where adjacent sides are both travelling in the same direction in terms of x and y, you will need to add two lines from the vertex, one horizontal and one vetical.
Once you have done this, you should be left with a polygon in the centre of the origonal polygon but with sides that are either vertical or horizontal because the sides have been formed by the lines drawn from the vertices of the original polygon. Because these sides are either vertical or horizontal, this shape can easily be sub-divided into a number of triangles with one horizontal side, one vertical side and one hypotenuse.
I'm assuming you've already ordered the vertices as you describe above, and that they indeed define a convex polygon.
Each vertex defines a horizontal line. For V vertices, then, you will have a set of V lines. Discard any line that meets one of the following criteria:
The vertex or vertices defining that line has/have the highest or lowest Y component (if one vertex, that line intersects the polygon only at that point; if two, that line coincides with a polygon edge)
If two vertices have equal Y coordinates otherwise, keep only one of those lines (it's duplicated).
The result will resemble a "banding" of the polygon.
Each horizontal line intersects the polygon at two points. One is its defining vertex. The other is either another vertex, or a point on a segment defined by two vertices. You can determine which is the case easily enough - just simple comparison of Y coords. The coordinates of the intersection with a segment is also easy math, which I leave to you.
Each intersection defines a vertical segment. The segment is contained within the polygon (if it coincides with an edge, you can discard it), and the other end meets either another horizontal line, or the edge of the polygon if that edge is itself horizontal. Determining the case is again a matter of mere comparison of coords. Finally, there may be 0-2 additional vertical segments, defined by the vertices with the highest and/or lowest Y coords, if there is only one of either.
The resulting diagram now shows each band with a right triangle trimmed off each end if possible. Each triangle should meet your criteria. The leftover regions are rectangles; draw an arbitrary diagonal to split each into two more right triangles meeting your criteria.
You're done.
I'm not sure if this is possible. Think about a square that's already aligned with the sides on the X and Y axes. How do you draw triangles using the vertices that are also aligned to the X,Y axes?
Or are the actual sides of the polygon allowed to be along the x,y axis. Which means you could just draw a line down the diagonal of the square. If so, it might be difficult to do with a more complex polygon where some sides are aligned to the axes, while others are not.
I'm not convinced there is a general solution to the question as posed. The problem is the aligned with the X- and Y-axes bit. That means that each vertex needs to be projected to the opposite side of the polygon in both the X and Y directions, and new vertices created at those intersection points. But that process must continue on for each new vertex added that way. You might get lucky and have this process terminate (because there's already a vertex appropriately placed on the opposite side), but in the general case it's just going to go on and on.
If you throw out that restriction, then Neil N's suggestion seems good to me.
Neil N is right, I think. Unfortunate that he didn't provide any specific links.
If you have a trapezoid whose top and bottom are parallel to the X axis, you can easily render that with 4 right triangles. Call that shape a horizontal trapezoid.
If you have a triangle with one side parallel to the X axis, you can render that with 2 right triangles -- or you can consider a degenerate case of the trapezoid with the top of bottom having length zero.
Start at either the top or bottom of your convex hull (i.e. search for coordinate with min or max y) and split it into horizontal trapezoids.
It's not to hard to write the code so that it works just as well with non-convex polygons.
I think this is not possible in the general case.
Consider the polygon {(0, 1), (1, 0), (2, 0)}
.
..
This triangle can not be split into a finite number of triangles as you describe.

Resources