I know two common algorithms by Greiner-Hormann and Vatti. They work with polygons. I want to implement boolean operations on bezier paths. I want to extend these algorithms to work with bezier paths. But this is numerical problem. What is the best way to bezier path clipping? ( and what is the best modification of Greiner-Hormann algorithm for arbitrary polygons (with self intersections) )
Here is a suggested algorithm.
use the four control points to determine a polygon enclosing the bezier curve.
test polygon overlapping to see if two bezier curves may have an intersection point. If not overlapping, we are done, no clipping required.
if polygon overlap, split the two bezier curve in two using one casteljau iteration. Stop the recursion if the size of the bezier curve is too small regarding the required precision. Otherwise resume recursively with step 2.
In the process of dividing the bezier curve, keep track of where you are (value t) so that you can easily determine the 4 control point of the clipped bezier curve.
Note that at some point a bezier curve may be approximated to a straight line. In this case the overlapping test and splitting will be faster.
With this process you should end with a bezier curve cut in pieces by the clipping bezier curve. You still need to determine which piece is on which side of the clipping.
Related
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.
I want to find & draw contour lines like this.
Data is just List of (x,y,z) and only a few points (about 40~60) in there.
(x and y are position and z is height)
How can i find this contour line and point?
As a first approximation, you can admit that your function is piecewise planar over a triangulation of the data points.
The Delaunay triangulation technique can be used, but in this case, given the regular polar arrangement, I guess that a simple rule based on the polar arguments could do.
Interpolating inside the triangles and obtaining the horizontal sections is a simple matter. Unfortunately, this will produce a gross approximation and you will probably notice artifacts due to the coarseness of the polylines.
A possible cure is to smooth the polylines as a postprocessing step, for instance turning them to polyBeziers.
Another method, which I prefer, is to use a higher order interpolation method. For C1 continuity, you can compute estimates of the gradient at the given points and fit quadratic functions on the triangles. Then subdivide the triangles in sub-triangles, interpolate the function at the sub-vertices, and switch to the planar model in these sub-triangles.
As that looks like an irregular grid, you should first build a mesh around it (for instance, from a Voronoi tesellation).
For every triangle, take the maximum and minimum heights of its vertices and find out the heights of the contour lines in that range (for instance, if you are drawing contour lines every 10 units and the heights of a triangle go from 11.5 to 34.2, the contour lines passing through that triangle are at heights 20 and 30).
Then approximating the height function inside the triangle as a linear function, find out where those contour lines lay and draw them.
The data for the contour plot could be generated with a two-dimensional simplification of the marching cubes algorith, which is described here. In the simplification, squares are used instead of cubes and four sampled values are used for the interpolation instead of the the eight corners of the cubes.
The simplification is also termed marching squares.
I want to fit a bezier curve with known end points (p0 and p3) to noisy 2d data. This seems like an easier problem than traditional 4-point bezier curve fitting but still too hard for me to figure out.
Can someone point me to existing code or an algorithm to find the best values for the control points p1 and p2?
edit: The points that I'm trying to fit with a bezier curve comes from curves drawn with a mouse (imagine drawing something with a brush in Paint, there could be hundreds of recorded points in one long stroke). The anchor points p0 and p3 are created in advance but the control points p1 and p2 should be calculated so that the bezier fits the shape of the curve sketched out with the mouse.
I stumbled on a paper called "Approximation of data using cubic Bezier curve least square fitting" by "M.Khan" which describes an algorithm to calculate the exact thing I'm looking for.
Implementation in javascript was easy. It works quite good and is fast but the resulting bezier curves are not perfect. Could be a bug in my code but I suspect that better curves could be obtained by iteratively adjusting the matching points on the bezier curve to better fit the data .
edit: It turns out you can use newton-raphson to optimize each individual t-value for the bezier curve. After doing that the curve fits great, atleast for curves with only few points that don't self intersect but I have to do some more testing.
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.
I am trying to find the intersection point of a curve and a 3D surface with no luck. The surface is in the shape of a cone, and the curve is hyperbolic, as are shown in the figure.
CONE AND THE CURVE
This simulates a ray hits a certain surface. I tried to use bisection method, but it doesn't seem to work. then I tried newton's algorithm, but the results are still not good.
Is there any other good algorithms out there which are suitable for solving this kind of problem?
With the curve given in parametric form
x = fx(t)
y = fy(t)
z = fz(t)
and the surface by one equation of the form
g(x,y,z) = 0
just plug in the curve functions and bisection should work:
g(fx(t), fy(t), fz(t)) = 0
The only problem is to find suitable starting points t1 and t2 where g has opposite sign.
Problem
You are searching for a curve-surface intersection algorithm. Note that both curves and surfaces can be represented in either implicit form or in parametric form. Surface in implicit form is defined by equation F(x, y, z) = 0, which is a quadratic polynomial of x, y, z in case of conic surface. Surface in parametric form is defined by point-valued function S(u, v) of its parameters (e.g. you can use distance along cone axis and polar angle as parameters of conical surface). Curve is usually described only in parametric form, as a function C(t) with parameter t, which could be quadratic for a hyperbolic curve.
Implicit surface
The simplest cases of all is to treat your problem as an intersection of parametric curve against implicit surface. In this case you can write down a single equation q(t) = F(C(t)) = 0 with single variable t. Of course, Newton's iteration is not guaranteed to find all solutions in general case, bisection can only surely find one solution if you find two points with different sign of q(t).
In your case q(t) is a quartic polynomial (after putting quadratic curve parametrization into quadratic surface equation). It can be theoretically solved with Ferrari's analytic formula, but I strongly advise against it, because it is quite unstable numerically. You can apply any popular polynomial solver here, like Jenkins-Traub algorithm or eigenvalues algorithm for companion matrix (also see this question). You can also use methods of interval mathematics: for example, you can recursively subdivide the domain interval of parameter t into smaller pieces, while pruning all the pieces that surely do not contain zeros (interval arithmetic would help you to detect such pieces).
Parametric surface
Now we can move on to the case when both the curve and the surface are represented parametrically. I do not know any solutions that could benefit from the fact the your surface is conical and your curve is hyperbolic, so you have to apply the general curve-surface intersection algorithm. Alternatively, you can fit an implicitly-defined cone into your parametric surface, then use the solution above for quartic polynomial roots.
A lot of reliable general intersection algorithms are based on the subdivision method (which is actually interval mathematics again). The general idea is to continiously divide the curve and the surface into smaller and smaller pieces. The pairs of pieces which surely do not intersect are dropped as soon as possible. At the end you'll have a set of small piece pairs, tightly bounding your intersection points. Yoy might want to run Newton's iteration from them in order to make intersection points precise.
Here is the outline of a sample algorithm:
Start with a single curve piece (the whole input curve) and a single surface
piece (whole surface), and one potentially intersection pair (PIP) of these pieces.
Subdivide each curve piece into two halves (by parameter), subdivide each surface piece into four quadrants (by both parameters).
For each old PIP check all 8 pairs of curve half vs surface quadrant. If they surely do not intersect, forget them. If they can intersect, save them as a new PIP.
Unless all pieces are small enough, repeat from step 2 with new pieces and PIP-s.
For each pair of curve piece and surface piece, you have to check whether they can potentially intersect, which can be easily done by checking their axis-aligned bounding boxes. Also, you can represent your curves and surfaces as NURBS, in which case you can use convex hulls as tighter bounding volumes.
Generally, there are tons of variations and improvements of this algorithms. I advise the following literature for deeper knowledge:
Shape interrogation for computer-aided design and manufacturing.
chapter 4: for root solvers
section 5.7: for curve-surface intersection
PhD of Michael Hohmeyer.
section 4.5: for curve-surface intersection
sections 4.1 and 4.2: for convex hulls intersection (if you are brave enough).
Bottom line
If you are seeking for a simple and working solution, and you are sure that hyperbolas and cones are the only things you have to worry about, then you'd better use implicit definition of cone and solve quartic equation with some standard numerical algorithm from a good library available to you.