Point of intersection between bezier curve and circle - processing

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.

Related

Creating a circular arc tangent to two curves with specified radius

The operation mentioned in the title is common in many Computer Aided Design (CAD) softwares such as AutoCAD, where it is called fillet. However, I found it is really difficult to implement this function in my own program.
The method I thought of is to use the condition that the distances of the arc center to the tangent lines of the curves are equal to the specified radius. Considering that actual curves are defined with piece-wise nonlinear functions, and the contact points could be anywhere on the curves, it is not easy to get the solution. Anyone good ideas?
Given that you don't describe in enough details the characteristics of the curves, it's hard to come with a specific/specified algo, but let's try a descriptive approach:
take a circle of the given radius and roll it on one curve until the circle touches the other one.
I assume you can parametrize you curves.
To "roll the circle" along the curve you need the tangent (or better said the normal, which of course is normal to the tangent) in the point "rolling track curve"-to-circle tangent point. You have this normal, you know the radius, you can compute your circle. You have the circle, you can see if/where it intersects the other curve.
The idea of "rolling" is to bracket your solution (parameter of the tangent-point on one curve) between a point when the circle does not intersect the other curve and another point where it intersects (possible in more than 1 point).
Once you have the bracket, go with a bisection method (binary search) between the two positions until your circle becomes "tangent enough" to the other curve (i.e the intersection points with the other curve are so close that they fall below your acceptable epsilon).
You will now have two points (one on each curves) and the circle that realizes the solution: just keep the arc on this circle corresponding what make sense (based on the convergence or divergence of the two tangents).
To find the arc center you need two robust and strategic algorithms:
Curve offset
Curve intersection
What AutoCAD does to find the arc center is to offset the two curves of the arc radius distance and intersect them. Depending on the curve offset direction you can easily switch between all possible solutions to the problem.
At this point, trimming the curves at tangent points will be trivial.

collision prediction using minkowski sum

I want to use the minkowski sum to predict the exact point of collision between two convex shapes. By my understanding the point where the velocity vector intersects with the minkowski sum is the amount I have to move my object along the vector so they just touch (I already know they will collide). Here's an example of what I mean (for simplicity reasons I just used rectangles):
I mean I could just calculate the intersection with every line of the convex hull and just use the closest but that seems horribly inefficient. My idea was to calculate the simplex closest to the vector but I have no idea how best to do it. I found a algorithm which calculates the smallest distance between to objects or to be more precise the smallest distance from the minkowski sum to the origin (http://www.codezealot.org/archives/153). One part of the algorithm tries to find the simplex closest to origin which is kinda what I want to do. I tried to change it to my needs but I wasn't successful. To me it sounds like there should be a very simple solution but I am not that good with vector math.
I hope I could make my problem clear since my english is not so good :D
You can transform the problem as follows:
1) rotate the plane so that the velocity vector becomes horizontal
2) consider the portions of the polygon outlines facing each other (these are two convex polylines); now you have to find the shortest horizontal distance between these two polylines
3) through every vertex of one of the polylines, draw an horizontal line; this will parition the plane into a set of horizontal slices
4) transform every slice using a shear transformation that brings the two vertices defining it onto the Y axis by horizontal moves; this transform preserves horizontal distances
5) while the first polyline is transformed into a straight line (the Y axis), the other polyline is transformed into another polyline; find the vertex(es) closest to the Y axis. This gives you the length of the collision vector.
As a by-product, step 2) will tell you if the polygons do collide, if the ranges of Y values overlap.

Algorithm for bisecting a set of points using a circle of fixed radius

Suppose I have a set of points in the Cartesian plane, defined by an array/vector of (X,Y) coordinates. This set of points will be "contiguous" in the coordinate plane, if any set of discontinuous points can be contiguous. That is, these points originated as a rectangular grid in which regions of points were eliminated by a prior algorithm. The shape outlined by the points is arbitrary, but it will tend to have arcs for edges.
Suppose further that I can create circles of fixed radius r.
I would like an algorithm that will find me the center X,Y for a circle that will enclose as close to exactly half of the given points as possible.
OK, try this (sorry if I have very bad wording: I didn't learn my Maths in english)
Step 1: Find axis
For all pairs of points, that are less than 2r apart calculate how many points lie on either side of the connecting line
Chose the pair with the worst balance
Calculate the line, that bisects these two points as an axis ("Axis of biggest concavity")
Step 2: Find center
Start on the axis far (>2r) away on the side, that had the lower point count in step 1 (The concave side)
Move the center on the axis, until you reach the desired point. This can be done by moving up with a step of sqrt(delta), where delta is the smallest distance between 2 points in the set, if overreaching move back halfing the step, etc.
You might want to look into the algorithm for smallest enclosing circle of a point set.
A somewhat greedy algorithm would be to simply remove points 1 at a time until the circle radius is less or equal to r.

Area of Intersection of Two Rotated Rectangles

I have two 2D rectangles, defined as an origin (x,y) a size (height, width) and an angle of rotation (0-360°). I can guarantee that both rectangles are the same size.
I need to calculate the approximate area of intersection of these two rectangles.
The calculation does not need to be exact, although it can be. I will be comparing the result with other areas of intersection to determine the largest area of intersection in a set of rectangles, so it only needs to be accurate relative to other computations of the same algorithm.
I thought about using the area of the bounding box of the intersected region, but I'm having trouble getting the vertices of the intersected region because of all of the different possible cases:
I'm writing this program in Objective-C in the Cocoa framework, for what it's worth, so if anyone knows any shortcuts using NSBezierPath or something you're welcome to suggest that too.
To supplement the other answers, your problem is an instance of line clipping, a topic heavily studied in computer graphics, and for which there are many algorithms available.
If you rotate your coordinate system so that one rectangle has a horizontal edge, then the problem is exactly line clipping from there on.
You could start at the Wikipedia article on the topic, and investigate from there.
A simple algorithm that will give an approximate answer is sampling.
Divide one of your rectangles up into grids of small squares. For each intersection point, check if that point is inside the other rectangle. The number of points that lie inside the other rectangle will be a fairly good approximation to the area of the overlapping region. Increasing the density of points will increase the accuracy of the calculation, at the cost of performance.
In any case, computing the exact intersection polygon of two convex polygons is an easy task, since any convex polygon can be seen as an intersection of half-planes. "Sequential cutting" does the job.
Choose one rectangle (any) as the cutting rectangle. Iterate through the sides of the cutting rectangle, one by one. Cut the second rectangle by the line that contains the current side of the cutting rectangle and discard everything that lies in the "outer" half-plane.
Once you finish iterating through all cutting sides, what remains of the other rectangle is the result.
You can actually compute the exact area.
Make one polygon out of the two rectangles. See this question (especially this answer), or use the gpc library.
Find the area of this polygon. See here.
The shared area is
area of rectangle 1 + area of rectangle 2 - area of aggregated polygon
Take each line segment of each rectangle and see if they intersect. There will be several possibilities:
If none intersect - shared area is zero - unless all points of one are inside the other. In that case the shared area is the area of the smaller one.
a If two consecutive edges of one rectactangle intersect with a single edge of another rectangle, this forms a triangle. Compute its area.
b. If the edges are not consequtive, this forms a quadrilateral. Compute a line from two opposite corners of the quadrilateral, this makes two triangles. Compute the area of each and sum.
If two edges of one intersect with two edges of another, then you will have a quadrilateral. Compute as in 2b.
If each edge of one intersects with each edge of the other, you will have an octagon. Break it up into triangles ( e.g. draw a ray from one vertex to each other vertex to make 4 triangles )
#edit: I have a more general solution.
Check the special case in 1.
Then start with any intersecting vertex, and follow the edges from there to any other intersection point until you are back to the first intersecting vertex. This forms a convex polygon. draw a ray from the first vertex to each opposite vetex ( e.g. skip the vertex to the left and right. ) This will divide it into a bunch of triangles. compute the area for each and sum.
A brute-force-ish way:
take all points from the set of [corners of
rectangles] + [points of intersection of edges]
remove the points that are not inside or on the edge of both rectangles.
Now You have corners of intersection. Note that the intersection is convex.
sort the remaining points by angle between arbitrary point from the set, arbitrary other point, and the given point.
Now You have the points of intersection in order.
calculate area the usual way (by cross product)
.

Finding a stable placement of an irregular (non-convex) shape

Given an image of a 2-dimensional irregular (non-convex) shape, how would I able to compute all the ways in which it could lie stable on a flat surface? For example, if the shape is a perfect square rectangle, then it will surely have 4 ways in which it is stable. A circle on the other hand either has no stable orientation or every point is a stable orientation.
EDIT: There's this nice little game called Splitter (Beware, addictive game ahead) that seems close to what I want. Noticed that you cut a piece of the wood out it would fall to the ground and lay in a stable manner.
EDIT: In the end, the approach I took is to compute center of mass (of the shape) and compute the convex hull (using OpenCV), and then loop through every pair of vertices. If the center of mass falls on top of the line formed by the 2 vertices, it is deemed stable, else, no.
First find its center of mass (CM). A stable position is one in which the CM will be higher if you make a slight rotation. Now look at the hull, the smallest convex region that encloses the shape:
(source: walkytalky.net)
If the hull is a polygon, then a stable position is one in which the shape is resting on one of the sides, and the CM is directly over that side (not necessarily over the midpoint of the side, just somewhere over it.
If the hull has curves (that is, if the shape has curves which touch the hull), they must be give special treatment. The shape will be stable when resting on a curved edge iff the CM is directly above the lowest point of the curve, and the radius of the curve at that point is greater than the height of the CM.
Examples:
A rectangle. The hull is simply the rectangle, and the CM is at the center. The shape is stable on each of the four sides.
A rectangle with the sides hollowed, but the corners still intact. The hull is still the original rectangle, and the CM is close to where it used to be. All four sides of the hull are still stable (that is, you can still rest the shape on any two corners).
A circle. The CM is in the center, the hull is the circle. There are no stable positions, since the radius of the curve is always equal to the height of the CM. Give it a slight touch, and it will roll.
An ellipse. The CM is at the center, the hull is the shape. Now there are two stable positions.
A semicircle. The CM is somewhere on the axis of symmetry, the hull is the shape. Two stable positions.
A narrow semicircular crescent. The hull is a semicircle, the CM is outside the shape (but inside the hull). Two stable positions.
(source: walkytalky.net)
(The ellipse position marked with an X is unstable, because the curvature is smaller than the distance to the centre of mass.)
note: this answer assumes your shape is a proper polygon.
For our purposes, we'll define an equilibrium position as one where the Center of Mass is directly above a point that is between the leftmost and rightmost ground-contact points of the object (assuming the ground is a flat surface perpendicular to the force of gravity). This will work in all cases, for all shapes.
Note that, this is actually the physical definition of rotational equilibrium, as a consequence of Newtonian Rotational Kinematics.
For a proper polygon, if we eliminate cases where they stand on a sole vertex, this definition is equivalent to a stable position.
So, if you have a straight downward gravity, first find the left-most and right-most parts of it that are touching the ground.
Then, calculate your Center of Mass. For a polygon with known vertices and uniform density, this problem is reduced to finding the Centroid (relevant section).
Afterwards, drop a line from your CoM; if the intersection of the CoM and the ground is between those two x values, it's at equilibrium.
If your leftmost point and rightmost point match (ie, in a round object), this will still hold; just remember to be careful with your floating point comparisms.
Note that this can also be used to measure "how stable" an object is -- this measure is the maximum y-distance the Center of Mass can move before it is no longer within the range of the two contact points.
EDIT: nifty diagram made hastily
So, how can you use this to find all the ways it can sit on a table? See:
EDIT
The programmable approach
Instead of the computationally expensive task of rotating the shape, try this instead.
Your shape's representation in your program should probably have a list of all vertices.
Find the vertices of your shape's convex hull (basically, your shape, but with all concave vertices -- vertices that are "pushed in" -- eliminated).
Then Iterate through each of pair of adjacent vertices on your convex hull (ie, if I had vertices A, B, C, D, I'd iterate through AB, BC, CD, DA)
Do this test:
Draw a line A through the two vertices being tested
Draw a line perpendicular to A, going through CoM C.
Find the intersection of the two lines (simple algebra)
If the intersection's y value is in between the y value of the two vertices, it stable. If the y values are all equal, compare the x values.
That should do the trick.
Here is an example of the test being running on one pair of vertices:
If your shape is not represented by its vertices in your data structure, then you should try to convert them. If it's something like a circle or an ellipse, you may use heuristics to guess the answer (a circle has infinite equilibrium positions; an ellipse 4, albeit only two "stable" points). If it's a curved wobbly irregular shape, you're going to have to supply your data structure for me be able to help in a program-related way, instead of just providing case-by-case heuristics.
I'm sure this is not the most efficient algorithm, but it's an idea.
If you can order the verticles of the polygon (assuming it has a finite number of vertices), then just iterate over adjacent pairs of vertices and record the angle it rests at through some form of simulation. There will be duplicate orientations for it to sit on in the case of weird shapes, like stars, but you can accomodate for that by keeping track of the resting rotation.

Resources