Rotating a polygon to get min height, with fixed max width - rotation

I was going through computational geometry problems and encountered the following problem, and couldn't come up with an answer.
What I want is: Given a fixed width W, I need to rotate a simple 2D polygon with n points such that it width won't exceed W, and to get a minimum height polygon.
A picture for illustration:
I can start rotating the polygon and check for its height and width each time, but obviously this will be very expensive and inaccurate..
I found this answer, but it's for convex polygons and without the width limitations and couldn't figure how(if possible) to do the necessary adjustments
Any suggestions?

When a convex polygon is rotated, the plot of its width and of its height* as functions of the angle are piecewise sinusoidal functions. You can establish this by considering antipodal pairs (https://en.wikipedia.org/wiki/Rotating_calipers). By simple geometric considerations, you can find the amplitude and phase of the sinusoids, and the angles where they intersect.
Now if you construct the width function, you can find the angles at which it is exactly the specified W (by solving A.sin(Θ-Φ) = W in the relevant intervals), and from the angle obtain the corresponding value of the height.
If your polygon is concave, you can obtain its convex hull in linear time (in the size of the polygon) by the Melkman's algorithm (https://en.wikipedia.org/wiki/Convex_hull_of_a_simple_polygon). Then rotating calipers and the resolution of the sinusoid equations also take linear time (in the size of the hull).
*The plot of the height is that of the width with a 90° shift.

Related

Point of intersection between bezier curve and circle

I am aiming to create the following (a directed arrow that connects two nodes) :
At the moment I have this (a quadratic bezier curve drawn from the center point of one node to the center of another):
(Note I have drawn the bezier above the nodes to show where it begins and ends)
I need a method - heuristic or otherwise - to calculate the point of intersection (circled in red, above) between the bezier curve and the node's (ellipse) circumference.
With this, I could calculate the angle between the node center and the point of intersection to draw the arrow head lines at the correct location and angle.
As a last resort, I could use the quadratic Bézier formula to generate a list of points that lie along the curve and also generate a list of points that lie on the circumference of the circle and use one of the two coordinates that have the least euclidian distance between each other as my intersection point. I'm hoping any answers can leverage geometry or whatever else to better solve it.
The general problem is uneasy as the intersection equation is quartic ((X(t)-Xc)² + (Y(t)-Yc)²=R²), where X and Y are quadratic polynomials). If you have a quartic solver handy you can use it but you'll have to select the right root.
A more reasonable approach is just to intersect the circle with the line segment between the control points. This is approximate but probably unnoticeable if the circle radius is small.
If you want more accuracy, perform one or two Newton's iterations from this point.

How to approximate a 3D shape to a grid?

Given a 3D object, how do I convert it into an approximated shape in which all the sides of the object are parallel to either of the co-ordinate planes, and all the vertices have integer co-ordinates?
For example, a sphere with center at origin and a radius of 1.5 will be approximated to a cube with center at origin and side length of 2.
For another example, the line given by x = y = 0.5 will have an approximated shape as a rectangular parallelepiped with infinite length, and width and breadth as 1, and positioned such that one of its edge is along z-axis, while all the faces are along or parallel to either of x-z or y-z co-ordinate planes.
I am working with finite objects only, the above example is only meant to explain my needs.
I want an algorithm which can do this for me for any shape.
In general case you need to determine maximum and minimum shape coordinates along every axis and define minimum axis aligned integer bounding box with values rounded to larger (using Ceil) for max and rounded to smaller (using Floor) for min coordinates. For example:
XMin_Box = Floor(XMin_Shape)
XMax_Box = Ceil(XMax_Shape)
Edit:
If you need to approximate a shape with more precision, consider some kind of voxelization (3d analog of 2d rasterization)

How to convert a regular height grid to a triangular irregular network?

I'm looking for an algorithm that converts a regular grid of heights (e.g. 1024x1024) to a triangular irregular network. Here is an image showing an example of a triangular irregular network:
I've looked in the internet for an algorithms to convert it, but I just couldn't find one. Basically the triangle density depends on the roughness and/or pixel error (when rasterized), or something like that.
Here's an idea for a two-step algorithm: Do a Delaunay triangulation based on a rough mesh first, then smoothe out the triangles recursively until a certain error criterion is met.
For the first step, identify a set of vertices for the Delaunay triangulation. These vertices coincide with pixel coordinates. Extreme points that are either higher or lower than all four neighbouring pixels should be in the set as should ridge points on the borders where the adjacent pixels along the border are either lower or higher. This should give a coarse triangular mesh. You can get a finer mesh by also including pixels that have a high curvature.
In the second step, iterate through all triangles. Scan through the triangle along the pixel grid and accumulate an error square for each pixel inside the triangle and also identify the points of maximum and minimum signed error. If the average error per pixel does not meet your criterion, add the points of lowest and highest error to your triangulation. Verify the new triangles and re-triangulate as necessary.
Notes:
The coarse triangulation in step one should be reasonably fast. If the height map is ragged, you might end up with too many vertices in the ragged area. In that case, the hight map might be smoothed with a Gaussian filter before applying the algorithm.
The recursive re-triangulation is probably not so fast, because determining the error requires scanning the triangles over and over. (The process should get faster as the triangle size decreases, but still.) A good criterion for finding vertices in step 1 might speed up step 2.
You can scan a triangle by finding the bounding box of pixels. Find the barycentric coordinates s, t of the lower left point of the bounding box and also the barycentric increments (dsx, dtx) and (dsy, dty) that correspond to a pixel move in the x and y directions. You can then scan the bounding box in two loops over the included pixels (x, y), calculate the barycentric coordinates (s, t) from your delta vectors and accumulate the error if you are inside the triangle, i.e. when s > 0, t > 0 and s + t < 1.
I haven't implemented this algorithm (yet - it is an interesting task), but I imagine that finding a good balance between speed and mesh quality is a matter of tailoring error criteria and vertex selection to the current height map.

How to find collision center of two rectangles? Rects can be rotated

I've just implemented collision detection using SAT and this article as reference to my implementation. The detection is working as expected but I need to know where both rectangles are colliding.
I need to find the center of the intersection, the black point on the image above (but I don't have the intersection area neither). I've found some articles about this but they all involve avoiding the overlap or some kind of velocity, I don't need this.
The information I've about the rectangles are the four points that represents them, the upper right, upper left, lower right and lower left coordinates. I'm trying to find an algorithm that can give me the intersection of these points.
I just need to put a image on top of it. Like two cars crashed so I put an image on top of the collision center. Any ideas?
There is another way of doing this: finding the center of mass of the collision area by sampling points.
Create the following function:
bool IsPointInsideRectangle(Rectangle r, Point p);
Define a search rectangle as:
TopLeft = (MIN(x), MAX(y))
TopRight = (MAX(x), MAX(y))
LowerLeft = (MIN(x), MIN(y))
LowerRight = (MAX(x), MIN(y))
Where x and y are the coordinates of both rectangles.
You will now define a step for dividing the search area like a mesh. I suggest you use AVG(W,H)/2 where W and H are the width and height of the search area.
Then, you iterate on the mesh points finding for each one if it is inside the collition area:
IsPointInsideRectangle(rectangle1, point) AND IsPointInsideRectangle(rectangle2, point)
Define:
Xi : the ith partition of the mesh in X axis.
CXi: the count of mesh points that are inside the collision area for Xi.
Then:
And you can do the same thing with Y off course. Here is an ilustrative example of this approach:
You need to do the intersection of the boundaries of the boxes using the line to line intersection equation/algorithm.
http://en.wikipedia.org/wiki/Line-line_intersection
Once you have the points that cross you might be ok with the average of those points or the center given a particular direction possibly. The middle is a little vague in the question.
Edit: also in addition to this you need to work out if any of the corners of either of the two rectangles are inside the other (this should be easy enough to work out, even from the intersections). This should be added in with the intersections when calculating the "average" center point.
This one's tricky because irregular polygons have no defined center. Since your polygons are (in the case of rectangles) guaranteed to be convex, you can probably find the corners of the polygon that comprises the collision (which can include corners of the original shapes or intersections of the edges) and average them to get ... something. It will probably be vaguely close to where you would expect the "center" to be, and for regular polygons it would probably match exactly, but whether it would mean anything mathematically is a bit of a different story.
I've been fiddling mathematically and come up with the following, which solves the smoothness problem when points appear and disappear (as can happen when the movement of a hitbox causes a rectangle to become a triangle or vice versa). Without this bit of extra, adding and removing corners will cause the centroid to jump.
Here, take this fooplot.
The plot illustrates 2 rectangles, R and B (for Red and Blue). The intersection sweeps out an area G (for Green). The Unweighted and Weighted Centers (both Purple) are calculated via the following methods:
(0.225, -0.45): Average of corners of G
(0.2077, -0.473): Average of weighted corners of G
A weighted corner of a polygon is defined as the coordinates of the corner, weighted by the sin of the angle of the corner.
This polygon has two 90 degree angles, one 59.03 degree angle, and one 120.96 degree angle. (Both of the non-right angles have the same sine, sin(Ɵ) = 0.8574929...
The coordinates of the weighted center are thus:
( (sin(Ɵ) * (0.3 + 0.6) + 1 - 1) / (2 + 2 * sin(Ɵ)), // x
(sin(Ɵ) * (1.3 - 1.6) + 0 - 1.5) / (2 + 2 * sin(Ɵ)) ) // y
= (0.2077, -0.473)
With the provided example, the difference isn't very noticeable, but if the 4gon were much closer to a 3gon, there would be a significant deviation.
If you don't need to know the actual coordinates of the region, you could make two CALayers whose frames are the rectangles, and use one to mask the other. Then, if you set an image in the one being masked, it will only show up in the area where they overlap.

drawing arc points

Can someone provide me an algorithm to draw points on arc? I know the start-point, end-point and radius. I need to show points on the arc made by this information(start-point, end-point and radius).
See the image for more details
I have Start-Point (x,y), End-Point(a,b). I have to calculate equally distance 5 points on arc. Is it possible?
The standard algorithm for this is the Midpoint circle algorithm (sometimes called Breshenham's circle algorithm).
Note that your arc specification is incomplete. There are generally two arcs of the same radius joining two given points, one for the center on each side of the line joining the points. Also, as #In silico points out, the radius can be no smaller than half the distance between the points.
The means of specifying an arc is similar to that used in SVG, which has some detailed implementation notes which are too long to copy here. For circular arcs, the x and y radii are equal so the x axis angle is not important. As Ted Hopp noted, you need a flag to indicate which direction the arc is drawn in ( in SVG called large-arc-flag ).
Once you have the centre and angles of start and end of the arc, divide the angle into six and use the sin/cos of this angle to plot the five intermediate points.

Resources