How to find corners given a set of points - shapes

Say I have shapes represented by a set of points on the edges. A hexagon and a circle, with the points defining them in green
Some points may be collinear or continuous (as in the circle).
How can I write an algorithm detect the corners of the shapes?
In this case it should be that the corners of the hexagon are returned. However, if the shape has a smooth curve it should not return any corners
Thanks

If the points are ordered, you can compute the turning angle between vec{P(i-m),P(i)} and vec{P(i),P(i+m)} for each point P(i). If the turning angle is greater than a pre-defined threshold, then P(i) can be considered as a "corner point". You will have to experiment a bit to find out the proper value for m and the threshold.

Related

Finding the relative shift and rotation that gives the maximum overlap for two point-clouds

I have two pointclouds in a 3D euclidean space, and I want to find the relative rotation and translation between the two pointclouds that gives the most overlap (or in other words, that minimizes the Wasserstein Distance, or any other optimal-transport metric, between the pointclouds).
I know that for translation one would simply shift the "center of mass". However rotation doesn't seem very intuitive to me.
What I have tried:
My approach was to compute the inertia tensor and rotate the point clouds to align their principal axes. However this is numerically unstable for pointclouds with high degrees of symmetry.

How to choose control point distance for 3D cubic Bézier curves to optimize 'roundness'?

Say I want to construct a 3D cubic Bézier curve, and I already have both end-points, and the direction (normal vector) for both control points. How can I choose the distance of both control points to their respective end-points in order to make the curve as 'nicely rounded' as possible?
To formalize 'nicely rounded': I think that means maximizing the smallest angle between any two segments in the curve. For example, having end-points (10, 0, 0) and (0, 10, 0) with respective normal vectors (0, 1, 0) and (1, 0, 0) should result in a 90° circular arc. For the specific case of 2D circular arcs, I've found articles like this one. But I haven't been able to find anything for my more general case.
(Note that these images are just to illustrate the 'roundness' concept. My curves are not guaranteed to be plane-aligned. I may replace the images later to better illustrate that point.)
This is a question of aesthetics, and if the real solution is unknown or too complicated, I would be happy with a reasonable approximation. My current approximation is too simplistic: choosing half the distance between the two end-points for both control point distances. Someone more familiar with the math will probably be able to come up with something better.
(PS: This is for open-source software, and I would be happy to give credit on GitHub.)
Edit: Here are some other images to illustrate a 3D case (jsfiddle):
Edit 2: Here's a screenshot of an unstable version of ApiNATOMY to give you an idea of what I'm trying to do. I'm creating 3D tubes to represent blood-vessels, connecting different parts of an anatomical schematic:
(They won't let me put in a jsfiddle link if I don't include code...)
What you are basically asking is to have curvature over the spline as constant as possible.
A curve with constant curvature is just a circular arc, so it makes sense to try to fit such an arc to your input parameters. In 2D, this is easy: construct the line which goes through your starting point and is orthogonal to the desired direction vector. Do the same for the ending point. Now intersect these two lines: the result is the center of the circle which passes through the two points with the desired direction vectors.
In your example, this intersection point would just be (0,0), and the desired circular arc lies on the unit circle.
So this gives you a circular arc, which you can either use directly or use the approximation algorithm which you have already cited.
This breaks down when the two direction vectors are collinear, so you'd have to fudge it a bit if this ever comes up. If they point at each other, you can simply use a straight line.
In 3D, the same construction gives you two planes passing through the end points. Intersect these, and you get a line; on this line, choose the point which minimizes the sum of squared distances to the two points. This gives you the center of a sphere which touches both end points, and now you can simply work in the plane spanned by these three points and proceed as in 2D.
For the special case where your two end points and the two known normal vector for the control points happen to make the Bezier curve a planar one, then basically you are looking for a cubic Bezier curve that can well approximate a circular arc. For this special case, you can set the distance (denoted as L) between the control point and their respective end point as L = (4/3)*tan(A/4) where A is the angle of the circular arc.
For the general 3D case, perhaps you can apply the same formula as:
compute the angle between the two normal vectors.
use L=(4/3)*tan(A/4) to decide the location of your control points.
if your normals are aligned in a plane
What you're basically doing here is creating an elliptical arc, in 3D, where the "it's in 3D" part is completely irrelevant, since it's just a 2D curve, rotated/translated to sit in your 3D space. So let's just solve the 2D case, and then the RT is entirely up to you.
Creating the "perfect" cubic Bezier between two points on an arc comes with limitations. You basically can't create good looking arcs that span more than a quarter circle. So, with that said: your start and end point normals give you a 2D angle between your normal vectors, which is the same angle as between your start and end tangents (since normals are perpendicular to tangents). So, let's:
align our curve so that the tangent at the start is 0
plug the angle between tangents into the formula given in the section on Circle approximation in the Primer on Bezier curves. This is basically just dumb "implementing the formula for c1x/c1y/c2x/c2y as a function that takes an angle as argument, and spits out four values as c1(x,y) and c2(x,y) coordinats".
There is no step 3, we're done.
After step 2, you have your control points in 2D to create the most circular arc between a start and end point. Now you just need to scale/rotate/translate it in 3D so that it lines up with where you needed your start and end point to begin with.
if your normals are not aligned in a plane
Now we have a problem, although one that we can deal with by treating the dimensions as separate things entirely. Instead of creating a single 2D curve, we're going to create three: one that's the X/Y projection, one that's the X/Z projection, and one that's the Y/Z projection. For all three of these, we're going to abstract the control points in exactly the same way as before, and then we simply take the projective control points (three for each control point), and then go "okay, we now have X, Y, and Z projective coordinates. That means we have (X,Y,Z) coordinates", and done again.

Computing Minkowski Difference For Circles and Convex Polygons

I'm needing to implement a Minkowski sum function that can return the Minkowski sum of either 2 circles, 2 convex polygons or a circle and a convex polygon. I found this thread that explained how to do this for convex polygons, but I'm not sure how to do this for a circle and polygon. Also, how would I even represent the answer?! I'd like the algorithm to run in O(n) time but beggars can't be choosers.
Circle is trivial -- just add the center points, and add the radii. Circle + ConvexPoly is nearly as simple: move each segment perpendicularly outward by the circle radius, and connect adjacent segments with circular arcs centered at the original poly vertices. Translate the whole by the circle center point.
As for how you represent the answer: Well, it depends on what you want to do with it. You could convert it to a NURBS if you just want to draw it with a vector drawing library. You could approximate the circular arcs with polylines if you just want a polygonal approximation. Or you might store it as is -- "this polygon, expanded by such-and-such a radius". That would be the best choice for things like raycasting, for instance. Or as a compromise, you could connect adjacent segments linearly instead of with circular arcs, and store it as the union of the (new) convex polygon and a list of circles at the vertices.
Oh, about ConvexPoly + ConvexPoly. That's the trickiest one, but still straightforward. The basic idea is that you take the list of segment vectors for each polygon (starting from some particular extremal point, like the point on each poly with the lowest X coordinate), then merge the two lists together, keeping it sorted by angle. Sum the two points you started with, then apply each vector from the merged vector list to produce the other points.

Reflecting a circle off another circle

Working with iPhone and Objective C.
I am working on a game and I need to correctly reflect a ball off a circle object. I am trying to do it as a line and circle intersection. I have my ball position outside the circle and I have the new ball position that would be inside the circle at the next draw update. I know the intersect point of the line (ball path) and the circle. Now I want to rotate the ending point of the ball path about the intersection point to get the correct angle of reflection off the tangent.
The following are known:
ball current x,y
ball end x,y
ball radius
circle center x,y
circle radius
intersection point of ball path and circle x and y
I know I need to find the angle of incidence between the tangent line and the incoming ball path which will also equal my angle of reflection. I think once I know those two angles I can subtract them from 180 to get my rotation angle then rotate my end point about the angle of intersection by that amount. I just don't know how.
First, you should note that the center of the ball doesn't have to be inside of the circle to indicate that there's a reflection or bounce. As long as the distance between ball center and circle is less than the radius of the ball, there will be a bounce.
If the radius of the circle is R and the radius of the ball is r, things are simplified if you convert to the case where the circle has radius R+r and the ball has radius 0. For the purposes of collision detection and reflection/bouncing, this is equivalent.
If you have the point of intersection between the (enlarged) circle and the ball's path, you can easily compute the normal N to the circle at that point (it is the unit vector in the direction from the center of the circle to the collision point).
For an incoming vector V the reflected vector is V-2(N⋅V) N, where (N⋅V) is the dot product. For this problem, the incoming vector V is the vector from the intersection point to the point inside the circle.
As for the reflection formula given above, it is relatively easy to derive using vector math, but you can also Google search terms like "calculate reflection vector". The signs in the formula will vary with the assumed directions of V and N. Mathworld has a derivation although, as noted, the signs are different.
I only know the solution to the geometry part.
Let:
r1 => Radius of ball
r2 => Radius of circle
You can calculate the distance between the two circles by using Pythagoras theorem.
If the distance is less than the r1+r2 then do the collision.
For the collision,I would refer you Here. It's in python but I think it should give you an idea of what to do. Hopefully, even implement it in Objective C. The Tutorial By PeterCollingRidge.

Calculating collision for a moving circle, without overlapping the boundaries

Let's say I have circle bouncing around inside a rectangular area. At some point this circle will collide with one of the surfaces of the rectangle and reflect back. The usual way I'd do this would be to let the circle overlap that boundary and then reflect the velocity vector. The fact that the circle actually overlaps the boundary isn't usually a problem, nor really noticeable at low velocity. At high velocity it becomes quite clear that the circle is doing something it shouldn't.
What I'd like to do is to programmatically take reflection into account and place the circle at it's proper position before displaying it on the screen. This means that I have to calculate the point where it hits the boundary between it's current position and it's future position -- rather than calculating it's new position and then checking if it has hit the boundary.
This is a little bit more complicated than the usual circle/rectangle collision problem. I have a vague idea of how I should do it -- basically create a bounding rectangle between the current position and the new position, which brings up a slew of problems of it's own (Since the rectangle is rotated according to the direction of the circle's velocity). However, I'm thinking that this is a common problem, and that a common solution already exists.
Is there a common solution to this kind of problem? Perhaps some basic theories which I should look into?
Since you just have a circle and a rectangle, it's actually pretty simple. A circle of radius r bouncing around inside a rectangle of dimensions w, h can be treated the same as a point p at the circle's center, inside a rectangle (w-r), (h-r).
Now position update becomes simple. Given your point at position x, y and a per-frame velocity of dx, dy, the updated position is x+dx, y+dy - except when you cross a boundary. If, say, you end up with x+dx > W (letting W = w-r), then you do the following:
crossover = (x+dx) - W // this is how far "past" the edge your ball went
x = W - crossover // so you bring it back the same amount on the correct side
dx = -dx // and flip the velocity to the opposite direction
And similarly for y. You'll have to set up a similar (reflected) check for the opposite boundaries in each dimension.
At each step, you can calculate the projected/expected position of the circle for the next frame.
If this lies outside the rectangle, then you can then use the distance from the old circle position to the rectangle's edge and the amount "past" the rectangle's edge that the next position lies at (the interpenetration) to linearly interpolate and determine the precise time when the circle "hits" the rectangle edge.
For example, if the circle is 10 pixels away from the rectangle's edge, then is predicted to move to 5 pixels beyond it, you know that for 2/3rds of the timestep (10/15ths) it moves on its orginal path, then is reflected and continues on its new path for the remaining 1/3rd of the timestep (5/15ths). By calculating these two parts of the motion and "adding" the translations together, you can find the correct new position.
(Of course, it gets more complicated if you hit near a corner, as there may be several collisions during the timestep, off different edges. And if you have more than one circle moving, things get a lot more complex. But that's where you can start for the case you've asked about)
Reflection across a rectangular boundary is incredibly simple. Just take the amount that the object passed the boundary and subtract it from the boundary position. If the position without reflecting would be (-0.8,-0.2) for example and the upper left corner is at (0,0), the reflected position would be (0.8,0.2).