How to detect if an ellipse intersects(collides with) a circle

后端 未结 10 2553
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-09 03:41

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 recta

相关标签:
10条回答
  • 2020-12-09 04:00

    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.

    0 讨论(0)
  • 2020-12-09 04:01

    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.

    0 讨论(0)
  • 2020-12-09 04:05

    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:

    Ellipse Equation : Polar form relative to center

    (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.

    0 讨论(0)
  • 2020-12-09 04:06

    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

    0 讨论(0)
  • 2020-12-09 04:17

    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.

    0 讨论(0)
  • 2020-12-09 04:18

    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)

    0 讨论(0)
提交回复
热议问题