Calculate Bezier AABB - graphics

I'd like to calculate the AABB (axis aligned bounding box) for a quadratic or bezier curve.
The only way I know how to do this is evaluating a high number of points on the bezier curve, and then use those points to calculate the AABB.
Is there a better way?

Great resource on Bezier curves, and working example of AABB http://pomax.github.io/bezierinfo/#boundingbox
For quadratic curve if you need it, also calculate this using derivatives.
Always avoid iterative methods when closed form is available.

It should be possible by looking for minimum and maximum thanks to the derivative of the curve in parametric form. have a look at this article: http://nishiohirokazu.blogspot.jp/2009/06/how-to-calculate-bezier-curves-bounding.html

The quadratic bezier curve consists of 2 coordinate functions — x(t) and y(t) where.
These functions may have maximum or minimum (the points where x'(t) = 0 and y'(t) = 0) and these points are the boundary points of the aabb.
So the algorithm is:
Imagine x0, y0, x1, y1, x2, y2 are known and calculate the values t(x0, x1, x2) and t(y0, y1, y2) when x'(t) = 0 and y'(t) = 0 respectively.
Calculate both values and check whether they are >= 0 and <= 1. If they are evaluate the points of the quadratic bezier.
Take the first and the last points.
Now you have 4 points (or maybe less), use them to calculate AABB.
By the way:
t(x0, x1, x2) = (x0 - x1) / (x2 - 2 * x1 + x0)
t(y0, y1, y2) = (y0 - y1) / (y2 - 2 * y1 + y0)
You can find the full code here: https://github.com/keyten/Graphics2D/blob/Delta/Core/Curve.Math.js#L295

Related

Finding the intersection of the Circle and Infinite Cylinder in 3D space

Finding the intersection of the Circle and Infinite Cylinder. (all in 3D)
• Circle is defined by center, plane in which it lies and radius.
• Cylinder is defined by axis and radius.
how can i get the intersection of these two?
WLOG the cylinder has equation X² + Y² = 1 (if not, you can make it so by translation, rotation and scaling).
Then the parametric equation of the circle is
P = C + U cos t + V sin t
where C is the center point and U, V two orthogonal vectors in the circle plane, of length R.
You can rationalize with the substitution cos t = (1 - u²) / (1 + u²), sin t = 2u / (1 + u²).
Combining these equations,
(Cx (1 + u²) + Ux (1 - u²) + Vx 2u)² + (Cy (1 + u²) + Uy (1 - u²) + Vy 2u)² = (1 + u²)²
which is a quartic one. There is no particular simplification of the coefficients.
You can solve numerically or by the closed-form formulas. There can be up to four solutions.
I guess that this is strictly equivalent to finding the intersections between the torus formed by inflating the circle circumference and the straight line obtained by deflating the cylinder to its axis. This is well addressed in the ray-tracing literature.
You can also sse it as a circle/ellipse intersection problem in 2D.
Let's some base point of cylinder is A0, unit axis direction vector is AD, radius AR. Circle center is B0, circle plane unit normal is BN, radius BR.
Circle intersects cylinder, if distance from B0 to cyl. axis is smaller than sum of cylinder radius plus projection of circle radius onto normal to axis
Dist <= AR + BR * Abs(Cos(AD, BN)).
Cos(AD, BN) = DotProduct(AD, BN)
Distance(B0, cyl.axis) = Abs(VectorProduct(AD, B0-A0))

drawling perpendicular line to two set of points in pixel coordinates?

For example, I have points {x1 = 70,y1 = 200},{x2 = 50,y2 = 400} in pixel coordinates. If I am to draw a perpendicular to this line, with the start point as (x1,y1) how would I go about getting the end point of the perpendicular line in jogl?
Here's what I have tried so far:
Calculated the normal :
dx = x2-x1; dy = y2-y1;
drawLine{(x1,y1},(dy,dx)}
I have tried negative values for dx and dy. couldn't get the perpendicular line.
Any help appreciated.
Use (x1 + dy, y1 - dx) for a clockwise-rotated line, and (x1 - dy, y1 + dx) for anti-". The main thing was you forgot to add the world coordinates onto the displacement vector for the second point. (and also some sign-related stuff)

Function to find if a point lies on a line given two points in python

def isOnLine(xCord1, yCord1, xCord2, yCord2, xCord3, yCord3):
mSlope = (yCord2 - yCord1) / (xCord2 - xCord1)
return mSlope
lineEquation = y - yCord1 = mSlope * (x - xCord1)
What I need is a function that when given three coordinates, will determine a line from the first two coordinates and then take the third coordinate and see if it falls on the line, returning a bool indicating true if the coordinate does fall on the line or a false if the coordinate does not fall on the line.
So far all I have is a function finding the slope of a line from the first two coordinates given. I know I can take the slope and the first two coordinates and find the equation of the line and then using the equation of the line take the third coordinate and see if it lies on the line. However I can't use that equation because y and x have no assigned value, is there another way I can calculate this?
You are close to a theoretically correct function, that works with perfect (error free) data.
def is_on_line(x1, y1, x2, y2, x3, y3):
slope = (y2 - y1) / (x2 - x1)
return y3 - y1 == slope * (x3 - x1)
print(is_on_line(0, 0, 1, 1, 2, 2))
# True
Lurkers suggestion is to turn the equality test above into the equivalent
(y3 - y1) / (x3 - x1) == slope
However, for arbitrary floating point numbers, exact equality for whatever criterion you use is essentially impossible. So you must test 'close enough'. You could either subtract slope and test that the difference is close enough to 0. Or you could divide by slope and test close enough to 1. What I would do is look up the formula for the perpendicular distance between a point and a line and test that distance for 'close enough' to 0.

find the equation of a line from bezier curve control points

I would like to find the equation of a curve in the form y = ax2 + bx + c
from the following svg path:
<path id="curve1" d="M100,200 C100,100 400,100 400,200" />
this gives me 4 points that can be seen on the attached image.
100,200 (start point in purple)
100,100 (control point 1 in red)
400,100 (control point 2 in green)
400,200 (end point in blue)
wikipedia has a great article explaining bezier curves however I am not sure how to apply the maths shown there to get equation of the curve.
http://en.wikipedia.org/wiki/B%C3%A9zier_curve
plotted curve, click to see image
You can't.
The SVG you're showing uses a cubic path, which uses a third order parametric curve, meaning it has the form:
fx(t) = x1 * (1-t)³ + x2 * 3 * (1-t)²t + x3 * 3 * (1-t)t² + x4 * t³
fy(t) = y1 * (1-t)³ + y2 * 3 * (1-t)²t + y3 * 3 * (1-t)t² + y4 * t³
(which is plotted for t going from 0, inclusive, to 1, inclusive).
So there are two reasons why you can't express that curve as a form y=ax²+b:
you'd need, at the very least, a form ax³+bx²+c instead, and
this is a parametric curve, not a simple function graph; for Bezier curves it is not the case that y is expressed in terms of x at all, but instead both the x and y values are controlled by a "master parameter" t.
We know that second degree functions like y=ax²+b can only model parabola, and looking at the image we can see that the plotted curve looks nothing like one of those (not even a squashed parabola) so we can't even "kind of sort of" approximate the curve with a second degree function in this case.
(sometimes you can get away with that, but definitely not in this case)

Draw 2 parallel lines

How can I calculate the points to draw 2 parallel lines.
I know the start and end points for the centre of the parallel lines. To makes thing a little bit harder, it needs to support straight and Bezier curved lines.
The question is vague, but here's a possibility. Hope that helps.
For a segment (x1,y1)-(x2,y2) you can calculate another segment, n pixels away in a direction represented by angle a this way
x1b = x1 + n cos a
y1b = y1 - n sin a
x2b = x2 + n cos a
y2b = y2 - n sin a

Resources