I'm smoothing a path via cubic interpolation, based on this math:
mu2 = mu*mu;
a0 = -0.5*x0 + 1.5*x1 - 1.5*x2 + 0.5*x3;
a1 = x0 - 2.5*x1 + 2*x2 - 0.5*x3;
a2 = -0.5*x0 + 0.5*x2;
a3 = x1;
interpolated_x = (a0*mu*mu2+a1*mu2+a2*mu+a3)
When I try to trace a segment on the path by iterating mu from 0.0 to 1.0, the distances are not equal. In the screenshot, the red points are the points of the path, the green and blue points are control points to calculate the curve.
Is there a way I can calculate a percentage of distance covered of a segment that gives me equal distances?
(I want to calculate a movement on this path, that has the same speed and depends on the percentage of distance covered. In this way, the movement would be faster in the middle of each segments.)
This function interpolates between x_1 and x_2 for values mu=0..1. But if you calculate the speed xp = diff(x, mu) at the end points you will find
xp_1 = (x_2-x_0)/2 xp_2 = (x_3-x_1)/2
So if the speed isn't equal and the ends points, it is going to vary by location. Even if it was equal at the ends points with v = (x_2-x_0)/2 = (x_3-x_1)/2 or
x_0 = x_2 -2 v x_3 = 2 v + x_1
or the speed function
xp = v - 6*mu*(v+x_1-x_2) + 6*mu2*(v+x_1-x_2)
To make the speed constant, v+x_1-x_2 = 0, or v=x_2-x_1 which yields the linear interpolation function
xp = x_2 - x_1
x = x_1 + mu*(x_2-x_1)
So to keep the spacing equal, you must use linear interpolation.
To provide equal spacing, you need to get curve segments of equal length. Note that curve length (both for the whole curve and for it's fragment) might be calculated using integration (in parametric form from here)
ds = Sqrt((dx/dt)^2+(dy/dt)^2)*dt
L = Integral{t=a..b} (ds), where t = 0..1 for overall length.
Sadly for cubic curves such integral (here it is elliptic) cannot be solved analytically and should be calculated numerically. It is well-known problem for Bezier curves, for instance.
So to build equal-length segments, you need to numerically find length L of the whole curve, find l[i]=i*L/n for position of i-th point and numerically find (for example, with binary search) parameter for this position.
For example, in a 2D space, with x [0 ; 1] and y [0 ; 1]. For p = 4, intuitively, I will place each point at each corner of the square.
But what can be the general algorithm?
Edit: The algorithm needs modification if dimensions are not orthogonal to eachother
To uniformly place the points as described in your example you could do something like this:
var combinedSize = 0
for each dimension d in d0..dn {
combinedSize += d.length;
}
val listOfDistancesBetweenPointsAlongEachDimension = new List
for each d dimension d0..dn {
val percentageOfWholeDimensionSize = d.length/combinedSize
val pointsToPlaceAlongThisDimension = percentageOfWholeDimensionSize * numberOfPoints
listOfDistancesBetweenPointsAlongEachDimension[d.index] = d.length/(pointsToPlaceAlongThisDimension - 1)
}
Run on your example it gives:
combinedSize = 2
percentageOfWholeDimensionSize = 1 / 2
pointsToPlaceAlongThisDimension = 0.5 * 4
listOfDistancesBetweenPointsAlongEachDimension[0] = 1 / (2 - 1)
listOfDistancesBetweenPointsAlongEachDimension[1] = 1 / (2 - 1)
note: The minus 1 deals with the inclusive interval, allowing points at both endpoints of the dimension
2D case
In 2D (n=2) the solution is to place your p points evenly on some circle. If you want also to define the distance d between points then the circle should have radius around:
2*Pi*r = ~p*d
r = ~(p*d)/(2*Pi)
To be more precise you should use circumference of regular p-point polygon instead of circle circumference (I am too lazy to do that). Or you can compute the distance of produced points and scale up/down as needed instead.
So each point p(i) can be defined as:
p(i).x = r*cos((i*2.0*Pi)/p)
p(i).y = r*sin((i*2.0*Pi)/p)
3D case
Just use sphere instead of circle.
ND case
Use ND hypersphere instead of circle.
So your question boils down to place p "equidistant" points to a n-D hypersphere (either surface or volume). As you can see 2D case is simple, but in 3D this starts to be a problem. See:
Make a sphere with equidistant vertices
sphere subdivision triangulation
As you can see there are quite a few approaches to do this (there are much more of them even using Fibonacci sequence generated spiral) which are more or less hard to grasp or implement.
However If you want to generalize this into ND space you need to chose general approach. I would try to do something like this:
Place p uniformly distributed place inside bounding hypersphere
each point should have position,velocity and acceleration vectors. You can also place the points randomly (just ensure none are at the same position)...
For each p compute acceleration
each p should retract any other point (opposite of gravity).
update position
just do a Newton D'Alembert physics simulation in ND. Do not forget to include some dampening of speed so the simulation will stop in time. Bound the position and speed to the sphere so points will not cross it's border nor they would reflect the speed inwards.
loop #2 until max speed of any p crosses some threshold
This will more or less accurately place p points on the circumference of ND hypersphere. So you got minimal distance d between them. If you got some special dependency between n and p then there might be better configurations then this but for arbitrary numbers I think this approach should be safe enough.
Now by modifying #2 rules you can achieve 2 different outcomes. One filling hypersphere surface (by placing massive negative mass into center of surface) and second filling its volume. For these two options also the radius will be different. For one you need to use surface and for the other volume...
Here example of similar simulation used to solve a geometry problem:
How to implement a constraint solver for 2-D geometry?
Here preview of 3D surface case:
The number on top is the max abs speed of particles used to determine the simulations stopped and the white-ish lines are speed vectors. You need to carefully select the acceleration and dampening coefficients so the simulation is fast ...
I am writing a graphics application that needs to calculate and display a list of points along a curve arc which is described by three points.
Lets say we have points (1,1), (2,4) and (5,2). I need an algorithm that can give me the values of y for each x from 1 to 5 that fall on the interpolated arc.
I'm sure this is a simple task for you math whizes out there, but for me it's a bit beyond my mathematical payscale.
Thanks in advance!
So the problem is how to compute the center C = (c1, c2) and radius r of a circumference given by three points P = (p1, p2), Q = (q1, q2) and S = (s1, s2).
The idea is very simple. It consists in realizing that, by definition, the center has the same distance to all three points P, Q and S.
Now, the set of all points that are equidistant from Pand Q is the perpendicular to the segment PQ incident at the mid point (P+Q)/2. Similarly, the set of all points equidistant from Q and S is the perpendicular to QS passing thru (Q+S)/2. So, the center C must be the intersection of these two lines.
Let's compute the parametric equations of these two straight lines.
For this we will need two additional functions that I will call dist(A,B) which computes the distance between points A and B and perp(A,B) that normalizes the vector B-A dividing it by its length (or norm) and answers the perpendicular vector to this normalized vector (keep in mind that a perpendicular to (a,b) is (-b,a) because their inner product is 0)
dist((a1,a2),(b1,b2))
Return sqrt(square(b1-a1) + square(b2-a2))
perp((a1,a2),(b1,b2))
dist := dist((a1,a2),(b1,b2)).
a := (b1-a1)/dist.
b := (b2-a2)/dist.
Return (-b,a).
We can now write the parametric expressions of our two lines
(P+Q)/2 + perp(P,Q)*t
(Q+S)/2 + perp(Q,S)*u
Note that both parameters are different, hence the introduction of two variables t and u.
Equating these parametric expressions:
(P+Q)/2 + perp(P,Q)*t = (Q+S)/2 + perp(Q,S)*u
which consists of two linear equations, one for each coordinate, and two unknowns t and u (see below). The solution of this 2x2 system gives the values of the parameters t and u that injected into the parametric expressions give the center C of the circumference.
Once C is known, the radius r can be calculated as r := dist(P,C).
Linear equations
(P+Q)/2 + perp(P,Q)*t = (Q+S)/2 + perp(Q,S)*u
First linear equation (coordinate x)
(p1+q1)/2 + (p2-q2)/dist(P,Q)*t = (q1+s1)/2 + (q2-s2)/dist(Q,S)*u
Second linear equation (coordinate y)
(p2+q2)/2 + (q1-p1)/dist(P,Q)*t = (q2+s2)/2 + (s1-q1)/dist(Q,S)*u
Linear System (2x2)
(p2-q2)/dist(P,Q)*t + (s2-q2)/dist(Q,S)*u = (s1-p1)/2
(q1-p1)/dist(P,Q)*t + (q1-s1)/dist(Q,S)*u = (s2-p2)/2
I want to improve a collision system.
Right now I detect if 2 irregular objects collide if their bounding rectangles collide.
I want to obtain the for rectangle the corresponding ellipse while for the other one to use a circle. I found a method to obtain the ellipse coordinates but I have a problem when I try to detect if it intersects the circle.
Do you know a algorithm to test if a circle intersects an ellipse?
Short answer: Solving exactly for whether the two objects intersect is complicated enough to be infeasible for the purpose of collision detection. Discretize your ellipse as an n-sided polygon for some n (depending on how accurate you need to be) and do collision detection with that polygon.
Long answer: If you insist on determining if the smooth ellipse and circle intersect, there are two main approaches. Both involve solving first for the closest point to the circle's center on the ellipse, and then comparing that distance to the circle's radius.
Approach 1: Use a parametrization of the ellipse. Transform your coordinates so that the ellipse is at the origin, with its axes aligned to the x-y axes. That is:
Center of ellipse: (0,0)
Center of circle: c = (cx, cy)
Radius of circle: r
Radius of x-aligned axis of ellipse: a
Radius of y-aligned axis of ellipse: b.
The equation of the ellipse is then given by a cos(t), b sin(t). To find the closest point, we want to minimize the square distance
|| (a cos t, b sin t) - c ||^2. As Jean points out, this is "just calculus": take a derivative, and set it equal to 0. Unless I'm missing something, though, solving the resulting (quite nasty) equation for t is not possible analytically, and must be approximated using e.g. Newton's Method.
Plug in the t you find into the parametric equation to get the closest point.
Pro: Numerical solve is only in one variable, t.
Con: You must be able to write down a parametrization of the ellipse, or transform your coordinates so that you can. This shouldn't be too hard for any reasonable representation you have of the ellipse. However, I'm going to show you a second method, which is much more general and might be useful if you have to generalize your problem to, say, 3D.
Approach 2: Use multidimensional calculus. No change of coordinates is necessary.
Center of circle: c = (cx, cy)
Radius of cirlce: r
Ellipse is given by g(x, y) = 0 for a function g. For instance, per Curd's answer you might use g(x,y) = distance of (x,y) from focus 1 + distance of (x,y) from focus 2 - e.
Finding the point on the ellipse closest to the center of the circle can then be phrased as a constrained minimization problem:
Minimize ||(x,y) - c||^2 subject to g(x,y) = 0
(Minimizing the square distance is equivalent to minimizing the distance, and much more pleasant to deal with since it's a quadratic polynomial in x,y.)
To solve the constrained minimization problem, we introduce Lagrange multiplier lambda, and solve the system of equations
2 * [ (x,y) -c ] + lambda * Jg(x,y) = 0
g(x,y) = 0
Here Jg is the gradient of g. This is a system of three (nonlinear) equations in three unknowns: x, y, and lambda. We can solve this system using Newton's Method, and the (x,y) we get is the closest point to the circle's center.
Pro: No parametrization needs to be found
Pro: Method is very general, and works well whenever writing g is easier than finding a parametric equation (such as in 3D)
Con: Requires a multivariable Newton solve, which is very hairy if you don't have access to a numerical method package.
Caveat: both of these approaches technically solve for the point which extremizes the distance to the circle's center. Thus the point found might be the furthest point from the circle, and not the closest. For both methods, seeding your solve with a good initial guess (the center of the circle works well for Method 2; you're on your own for Method 1) will reduce this danger.
Potential Third Approach?: It may be possible to directly solve for the roots of the system of two quadratic equations in two variables representing the circle and ellipse. If a real root exists, the objects intersect. The most direct way of solving this system, again using a numerical algorithm like Newton's Method, won't help because lack of convergence does not necessary imply nonexistence of a real root. For two quadratic equations in two variables, however, there may exist a specialized method that's guaranteed to find real roots, if they exist. I myself can't think of a way of doing this, but you may want to research it yourself (or see if someone on stackoverflow can elaborate.)
An ellipse is defined a the set of points whose
sum of the distance to point A and the distance to point B is constant e.
(A and B are called the foci of the ellipse).
All Points P, whose sum AP + BP is less than e, lie within the ellipse.
A circle is defined as the set of points whose
distance to point C is r.
A simple test for intersection of circle and ellipse is following:
Find
P as the intersection of the circle and the line AC and
Q as the intersection of the circle and the line BC.
Circle and ellipse intersect (or the circle lies completely within the ellipse) if
AP + BP <= e or AQ + BQ <= e
EDIT:
After the comment of Martin DeMello and adapting my answer accordingly I thought more about the problem and found that the answer (with the 2nd check) still doesn't detect all intersections:
If circle and ellipse are intersecting only very scarcely (just a little more than being tangent) P and Q will not lie within the ellipse:
So the test described above detects collision only if the overlap is "big enough".
Maybe it is good enough for your practical purposes, although mathematically it is not perfect.
I know that it's too late but I hope it would help somebody. My approach to solve this problem was to interpolate the ellipse into an n-dimensions polygon, then to construct a line between every 2 points and find whether the circle intersects with any of the lines or not. This doesn't provide the best performance, but it is handy and easy to implement.
To interpolate the ellipse to an n-dimensions polygon, you can use:
float delta = (2 * PI) / n;
std::vector<Point*> interpolation;
for(float t = 0; t < (2 * PI); t += delta) {
float x = rx * cos(t) + c->get_x();
float y = ry * sin(t) + c->get_y();
interpolation.push_back(new Point(x, y));
}
c: The center of the ellipse.
rx: The radius of x-aligned axis of the ellipse.
ry: The radius of y-aligned axis of the ellipse.
Now we have the interpolation points, we can find the intersection between the circle and the lines between every 2 points.
One way to find the line-cricle intersection is described here,
an intersection occurs if an intersection occurred between any of the lines and the circle.
Hope this helps anybody.
find the point on the ellipse closest to the center of the circle
and then check if the distance from this point is smaller than the radius of the circle
if you need help doing this just comment, but it's simply calculus
edit: here's a ways towards the solution, since there is something wrong with curds
given center α β on the ellipse
and (for lack of remembering the term) x radius a, y radius b
the parametrization is
r(Θ) = (ab)/( ( (BcosΘ)^2 + (asinΘ)^2 )^.5)
x(Θ) = α + sin(Θ)r(Θ)
y(Θ) = β + cos(Θ)r(Θ)
and then just take the circle with center at (φ, ψ) and radius r
then the distance d(Θ) = ( (φ - x(Θ))^2 + (ψ - y(Θ) )^2)^.5
the minimum of this distance is when d'(Θ) = 0 (' for the derivative)
d'(Θ) = 1/d(Θ) * (-φx'(Θ) + x(Θ)x'(Θ) - ψy'(Θ) + y(Θ)y'(Θ) )
==>
x'(Θ) * (-φ + x(Θ)) = y'(Θ) * (ψ - y(Θ))
and keep going and going and hopefully you can solve for Θ
The framework you're working in might have things to help you solve this, and you could always take the easy way out and approximate roots via Newton's Method
if a circle and an ellipse collide, then either their boundaries intersect 1, 2, 3, or 4 times(or infinitely many in the case of a circular ellipse that coincides with the circle), or the circle is within the ellipse or vice versa.
I'm assuming the circle has an equation of (x - a)^2 + (y - b)^2 <= r^2 (1) and the ellipse has an equation of [(x - c)^2]/[d^2] + [(y - e)^2]/[f^2] <= 1 (2)
To check whether one of them is inside the other, you can evaluate the equation of the circle at the coordinates of the center of the ellipse(x=c, y=e), or vice versa, and see if the inequality holds.
to check the other cases in which their boundaries intersect, you have to check whether the system of equations described by (1) and (2) has any solutions.
you can do this by adding (1) and (2), giving you
(x - a)^2 + (y - b)^2 + [(x - c)^2]/[d^2] + [(y - e)^2]/[f^2] = r^2 + 1
next you multiply out the terms, giving
x^2 - 2ax + a^2 + y^2 - 2by + b^2 + x^2/d^2 - 2cx/d^2 + c^2/d^2 + y^2/f^2 - 2ey/f^2 + e^2/f^2 = r^2 + 1
collecting like terms, we get
(1 + 1/d^2)x^2 - (2a + 2c/d^2)x + (1 + 1/f^2)y^2 - (2b + 2e/f^2)y = 1 + r^2 - a^2 - b^2 - c^2/d^2 - e^2/f^2
now let m = (1 + 1/d^2), n = -(2a + 2c/d^2), o = (1 + 1/f^2), and p = -(2b + 2e/f^2)
the equation is now mx^2 + nx + oy^2 + py = 1 + r^2 - a^2 - b^2 - c^2/d^2 - e^2/f^2
now we need to complete the squares on the left hand side
m[x^2 + (n/m)x] + o[y^2 + (p/o)y] = 1 + r^2 - a^2 - b^2 - c^2/d^2 - e^2/f^2
m[x^2 + (n/m)x + (n/2m)^2 - (n/2m)^2] + o[y^2 + (p/o)y + (p/2o)^2 - (p/2o)^2] = 1 + r^2 - a^2 - b^2 - c^2/d^2 - e^2/f^2
m[(x + n/2m)^2 - (n/2m)^2] + o[(y + p/2o)^2 - (p/2o)^2] = 1 + r^2 - a^2 - b^2 - c^2/d^2 - e^2/f^2
m(x + n/2m)^2 - m(n/2m)^2 + o(y + p/2o)^2 - o(p/2o)^2 = 1 + r^2 - a^2 - b^2 - c^2/d^2 - e^2/f^2
m(x + n/2m)^2 + o(y + p/2o)^2 = 1 + r^2 - a^2 - b^2 - c^2/d^2 - e^2/f^2 + m(n/2m)^2 + o(p/2o)^2
this system has a solution iff 11 + r^2 - a^2 - b^2 - c^2/d^2 - e^2/f^2 + m(n/2m)^2 + o(p/2o)^2 >= 0
There you have it, if I didn't make any algebraic mistakes. I don't know how much you can simplify the resulting expression, so this solution might be quite computationally expensive if you're going to check for many circles/ellipses
Enlarge the ellipse's major and minor radii by the radius of the circle. Then test if the center of the given circle is within this new larger ellipse by summing the distances to the foci of the enlarged ellipse.
This algorithm is quite efficient. You can early-out if the given circle doesn't intersect a circle which circumscribes the ellipse. This is slower than a bounding box test, but finding the bounding box of a non-axis-aligned ellipse is tricky.
Forget about a mathematical solution. As you can easily see by drawing, you can have up to four solutions, and thus likely a fourth grade polynomial.
Instead just do a binary search along the edge of one of the figures. It is easy to determine if a point lies within an ellipse and even more so in a circle (just see if distance is shorter than radius).
If you really want to go for the maths, Wolfram MathWorld has a nice article here: http://mathworld.wolfram.com/Circle-EllipseIntersection.html but be warned, you'll still have to write a polynomial equation solver, probably using something like binary search.
Supposing:
the ellipse is centred at the origin and with the semi-major
axis (of length a) oriented along the x axis, and with a semi-minor
axis of length b; E2 is the eccentricity squared, ie (aa-bb)/(a*a);
the circle is centred at X,Y and of radius r.
The easy cases are:
the circle centre is inside the ellipse (ie hypot(X/a, Y/b) <= 1)
so there is an intersection;
the circle centre is outside a circle centred at 0 of radius a+r
(ie hypot(X,Y) > a+r) so there isn't an intersection.
One approach for the other cases is to compute the geodetic
coordinates (latitude, height) of the circle centre. The circle
intersects the ellipse if and only if the height is less than the radius.
The geodetic latitude of a point on an ellipse is the angle
the normal to the ellipse at the point makes with the x axis, and
the height of a point outside the ellipse is the distance of the
point from the point on the ellipse closest to it. Note the geodetic latitude is not same as the polar angle from the ellipse centre to the point unless the
ellipse is in fact circular.
In formulae the conversion from geodetic coordinates lat,ht to
cartesian coordinates X,Y is
X = (nu+ht)*cos(lat), Y = (nu * (1-E2) + ht)*sin(lat)
where nu = a/sqrt( 1 - E2*sin(lat)sin(lat)).
The point on the ellipse closest to X,Y is the point
with the same latitude, but zero height, ie x = nucos(lat),
y = nu * (1-E2) * sin(lat).
Note that nu is a function of latitude.
Unfortunately the process of finding lat,ht from X,Y is an
iterative one. One approach is to first find the latitude, and then
the height.
A little algebra shows that the latitude satisfies
lat = atan2( Y+ E2*nusin(lat), X)
which can be used to compute successive approximations to the latitude,
starting at lat = atan2( Y, X(1.0-E2)), or (more efficiently) can be
solved using newton's method.
The larger E2 is, ie the flatter the ellipse is, the more
iterations will be required. For example if the ellipse is nearly
circular (say E2<0.1) then five iterations will get x,y below
to within a*1e-12, but if the ellipse is very flat, e.g. E2=0.999
you'll need around 300 iterations to get the same accuracy!
Finally, given the latitude, the height can be computed
by computing (x,y):
x = nucos(lat), y = nu(1-E2)*sin(lat)
and then h is the distance from x,y to the circle centre,
h = hypot( X-x, Y-y)
This isn't that hard. user168715's answer is generally right, but doing calculus isn't necessary. Just trigonometry.
Find the angle between the center of the two objects. Using this you can find the closest point to the circle's center on the ellipse using the polar-form:
(Taken from Wikipedia article on Ellipses)
Now compare the distance between the two object centers, subtracting the ellipse radius and circle radius.
Maybe I'm missing something; maybe ArcTan/Cos/Sin are slow -- but I don't think so, and there should be fast-approximations if needed.
I wanted to provide some input into the more general problem involving contact between two ellipses. Calculating the distance of closest approach of two ellipses was a long standing problem and was only solved analytically within the last ten years-it is by no means simple. The solution to the problem may be found here http://www.e-lc.org/docs/2007_01_17_00_46_52/.
The general method to determine if there is contact between two ellipses is to first calculate the distance of closest approach of the ellipses in their current configuration and then subtract this from their current magnitude of separation. If this result is less than or equal to 0, then they are in contact.
If anyone is interested I can post code that calculates the distance of closest approach--it's in C++. The code is for the general case of two arbitrary ellipses, but you can obviously do it for a circle and ellipse, since a circle is an ellipse with equal minor and major axes.
I have a quadratic bezier curve described as (startX, startY) to (anchorX, anchorY) and using a control point (controlX, controlY).
I have two questions:
(1) I want to determine y points on that curve based on an x point.
(2) Then, given a line-segment on my bezier (defined by two intermediary points on my bezier curve (startX', startY', anchorX', anchorY')), I want to know the control point for that line-segment so that it overlaps the original bezier exactly.
Why? I want this information for an optimization. I am drawing lots of horizontal beziers. When the beziers are larger than the screen, performance suffers because the rendering engine ends up rendering beyond the extents of what is visible. The answers to this question will let me just render what is visible.
Part 1
The formula for a quadratic Bezier is:
B(t) = a(1-t)2 + 2bt(1-t) + ct2
= a(1-2t+t2) + 2bt - 2bt2 + ct2
= (a-2b+c)t2+2(b-a)t + a
where bold indicates a vector. With Bx(t) given, we have:
x = (ax-2bx+cx)t2+2(bx-ax)t + ax
where vx is the x component of v.
According to the quadratic formula,
-2(bx-ax) ± 2√((bx-ax)2 - ax(ax-2bx+cx))
t = -----------------------------------------
2(ax-2bx+cx)
ax-bx ± √(bx2 - axcx)
= ----------------------
ax-2bx+cx
Assuming a solution exists, plug that t back into the original equation to get the other components of B(t) at a given x.
Part 2
Rather than producing a second Bezier curve that coincides with part of the first (I don't feel like crunching symbols right now), you can simply limit the domain of your parametric parameter to a proper sub-interval of [0,1]. That is, use part 1 to find the values of t for two different values of x; call these t-values i and j. Draw B(t) for t ∈ [i,j]. Equivalently, draw B(t(j-i)+i) for t ∈ [0,1].
The t equation is wrong, you need to use eq(1)
(1) x = (ax-2bx+cx)t2+2(bx-ax)t + ax
and solve it using the the quadratic formula for the roots (2).
-b ± √(b^2 - 4ac)
(2) x = -----------------
2a
Where
a = ax-2bx+cx
b = 2(bx-ax)
c = ax - x