Skip to content

Instantly share code, notes, and snippets.

@fundon
Forked from JohannesMP/ClosestPointOnEllipse.cs
Created June 17, 2024 00:43
Show Gist options
  • Save fundon/11331322d3ca223c42e216df48c339e1 to your computer and use it in GitHub Desktop.
Save fundon/11331322d3ca223c42e216df48c339e1 to your computer and use it in GitHub Desktop.

Revisions

  1. fundon revised this gist Jun 17, 2024. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ClosestPointOnEllipse.cs
    Original file line number Diff line number Diff line change
    @@ -27,7 +27,7 @@ public static Vector2 Ellipse(Vector2 point, double semiMajor, double semiMinor)
    for (int i = 0; i < 3; ++i)
    {
    x = a * tx;
    y = a * ty;
    y = b * ty;

    ex = (a * a - b * b) * (tx * tx * tx) / a;
    ey = (b * b - a * a) * (ty * ty * ty) / b;
  2. @JohannesMP JohannesMP revised this gist Jul 15, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ClosestPointOnEllipse.cs
    Original file line number Diff line number Diff line change
    @@ -24,7 +24,7 @@ public static Vector2 Ellipse(Vector2 point, double semiMajor, double semiMinor)

    double x, y, ex, ey, rx, ry, qx, qy, r, q, t = 0;

    for (int i = 0; i < 4; ++i)
    for (int i = 0; i < 3; ++i)
    {
    x = a * tx;
    y = a * ty;
  3. @JohannesMP JohannesMP revised this gist Jul 15, 2018. 1 changed file with 13 additions and 10 deletions.
    23 changes: 13 additions & 10 deletions ClosestPointOnEllipse.cs
    Original file line number Diff line number Diff line change
    @@ -16,18 +16,21 @@ public static Vector2 Ellipse(Vector2 point, double semiMajor, double semiMinor)
    double px = Math.Abs(point.x);
    double py = Math.Abs(point.y);

    double tx = Math.PI / 4;
    double ty = Math.PI / 4;
    double a = semiMajor;
    double b = semiMinor;

    double tx = 0.70710678118;
    double ty = 0.70710678118;

    double x, y, ex, ey, rx, ry, qx, qy, r, q, t = 0;

    for (int i = 0; i < 4; ++i)
    {
    x = semiMajor * tx;
    y = semiMinor * ty;
    x = a * tx;
    y = a * ty;

    ex = (semiMajor * semiMajor - semiMinor * semiMinor) * (tx * tx * tx) / semiMajor;
    ey = (semiMinor * semiMinor - semiMajor * semiMajor) * (ty * ty * ty) / semiMinor;
    ex = (a * a - b * b) * (tx * tx * tx) / a;
    ey = (b * b - a * a) * (ty * ty * ty) / b;

    rx = x - ex;
    ry = y - ey;
    @@ -38,8 +41,8 @@ public static Vector2 Ellipse(Vector2 point, double semiMajor, double semiMinor)
    r = Math.Sqrt(rx * rx + ry * ry);
    q = Math.Sqrt(qy * qy + qx * qx);

    tx = (qx * r / q + ex) / semiMajor;
    ty = (qy * r / q + ey) / semiMinor;
    tx = Math.Min(1, Math.Max(0, (qx * r / q + ex) / a));
    ty = Math.Min(1, Math.Max(0, (qy * r / q + ey) / b));

    t = Math.Sqrt(tx * tx + ty * ty);

    @@ -49,8 +52,8 @@ public static Vector2 Ellipse(Vector2 point, double semiMajor, double semiMinor)

    return new Vector2
    {
    x = (float)(semiMajor * (point.x < 0 ? -tx : tx)),
    y = (float)(semiMinor * (point.y < 0 ? -ty : ty))
    x = (float)(a * (point.x < 0 ? -tx : tx)),
    y = (float)(b * (point.y < 0 ? -ty : ty))
    };
    }
    }
  4. @JohannesMP JohannesMP revised this gist Jul 13, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ClosestPointOnEllipse.cs
    Original file line number Diff line number Diff line change
    @@ -21,7 +21,7 @@ public static Vector2 Ellipse(Vector2 point, double semiMajor, double semiMinor)

    double x, y, ex, ey, rx, ry, qx, qy, r, q, t = 0;

    for (int i = 0; i < 3; ++i)
    for (int i = 0; i < 4; ++i)
    {
    x = semiMajor * tx;
    y = semiMinor * ty;
  5. @JohannesMP JohannesMP renamed this gist Jul 13, 2018. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  6. @JohannesMP JohannesMP renamed this gist Jul 13, 2018. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  7. @JohannesMP JohannesMP revised this gist Jul 13, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion NearestPointTo.cs
    Original file line number Diff line number Diff line change
    @@ -10,7 +10,7 @@ public static class NearestPointTo
    /// 2015-09 Original Paper by Luc. Maisonobe https://www.spaceroots.org/documents/distance/distance-to-ellipse.pdf
    /// 2017-08-27 Python Code by Carl Chatfield https://wet-robots.ghost.io/simple-method-for-distance-to-ellipse/
    /// 2017-11-10 Trig-Free Optimization by Adrian Stephens https://github.com/0xfaded/ellipse_demo/issues/1
    /// 2018-07-12 C# Code for Unity3D by Johannes Peter <this gist>
    /// 2018-07-12 C# Code for Unity3D by Johannes Peter https://gist.github.com/JohannesMP/777bdc8e84df6ddfeaa4f0ddb1c7adb3
    public static Vector2 Ellipse(Vector2 point, double semiMajor, double semiMinor)
    {
    double px = Math.Abs(point.x);
  8. @JohannesMP JohannesMP revised this gist Jul 13, 2018. 1 changed file with 8 additions and 6 deletions.
    14 changes: 8 additions & 6 deletions NearestPointTo.cs
    Original file line number Diff line number Diff line change
    @@ -3,11 +3,14 @@

    public static class NearestPointTo
    {
    // Credit:
    // 2015-09 Original Paper by Luc. Maisonobe https://www.spaceroots.org/documents/distance/distance-to-ellipse.pdf
    // 2017-08-27 Python Code by Carl Chatfield https://wet-robots.ghost.io/simple-method-for-distance-to-ellipse
    // 2017-11-10 Trig-Free Optimization by Adrian Stephens https://github.com/0xfaded/ellipse_demo/issues/1
    // 2018-07-12 C# Code for Unity3D by Johannes Peter https://gist.github.com/JohannesMP/777bdc8e84df6ddfeaa4f0ddb1c7adb3
    /// <summary>
    /// Find the closest point on an ellipse centered on the origin.
    /// </summary>
    /// Credit:
    /// 2015-09 Original Paper by Luc. Maisonobe https://www.spaceroots.org/documents/distance/distance-to-ellipse.pdf
    /// 2017-08-27 Python Code by Carl Chatfield https://wet-robots.ghost.io/simple-method-for-distance-to-ellipse/
    /// 2017-11-10 Trig-Free Optimization by Adrian Stephens https://github.com/0xfaded/ellipse_demo/issues/1
    /// 2018-07-12 C# Code for Unity3D by Johannes Peter <this gist>
    public static Vector2 Ellipse(Vector2 point, double semiMajor, double semiMinor)
    {
    double px = Math.Abs(point.x);
    @@ -18,7 +21,6 @@ public static Vector2 Ellipse(Vector2 point, double semiMajor, double semiMinor)

    double x, y, ex, ey, rx, ry, qx, qy, r, q, t = 0;

    // 3 iterations is enough for 6 significant figures in a float-based result.
    for (int i = 0; i < 3; ++i)
    {
    x = semiMajor * tx;
  9. @JohannesMP JohannesMP revised this gist Jul 13, 2018. 1 changed file with 3 additions and 2 deletions.
    5 changes: 3 additions & 2 deletions NearestPointTo.cs
    Original file line number Diff line number Diff line change
    @@ -5,9 +5,9 @@ public static class NearestPointTo
    {
    // Credit:
    // 2015-09 Original Paper by Luc. Maisonobe https://www.spaceroots.org/documents/distance/distance-to-ellipse.pdf
    // 2017-08-27 Python Code by Carl Chatfield https://wet-robots.ghost.io/simple-method-for-distance-to-ellipse/
    // 2017-08-27 Python Code by Carl Chatfield https://wet-robots.ghost.io/simple-method-for-distance-to-ellipse
    // 2017-11-10 Trig-Free Optimization by Adrian Stephens https://github.com/0xfaded/ellipse_demo/issues/1
    // 2018-07-12 C# Code for Unity3D by Johannes Peter <this gist>
    // 2018-07-12 C# Code for Unity3D by Johannes Peter https://gist.github.com/JohannesMP/777bdc8e84df6ddfeaa4f0ddb1c7adb3
    public static Vector2 Ellipse(Vector2 point, double semiMajor, double semiMinor)
    {
    double px = Math.Abs(point.x);
    @@ -18,6 +18,7 @@ public static Vector2 Ellipse(Vector2 point, double semiMajor, double semiMinor)

    double x, y, ex, ey, rx, ry, qx, qy, r, q, t = 0;

    // 3 iterations is enough for 6 significant figures in a float-based result.
    for (int i = 0; i < 3; ++i)
    {
    x = semiMajor * tx;
  10. @JohannesMP JohannesMP created this gist Jul 13, 2018.
    53 changes: 53 additions & 0 deletions NearestPointTo.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,53 @@
    using UnityEngine;
    using Math = System.Math;

    public static class NearestPointTo
    {
    // Credit:
    // 2015-09 Original Paper by Luc. Maisonobe https://www.spaceroots.org/documents/distance/distance-to-ellipse.pdf
    // 2017-08-27 Python Code by Carl Chatfield https://wet-robots.ghost.io/simple-method-for-distance-to-ellipse/
    // 2017-11-10 Trig-Free Optimization by Adrian Stephens https://github.com/0xfaded/ellipse_demo/issues/1
    // 2018-07-12 C# Code for Unity3D by Johannes Peter <this gist>
    public static Vector2 Ellipse(Vector2 point, double semiMajor, double semiMinor)
    {
    double px = Math.Abs(point.x);
    double py = Math.Abs(point.y);

    double tx = Math.PI / 4;
    double ty = Math.PI / 4;

    double x, y, ex, ey, rx, ry, qx, qy, r, q, t = 0;

    for (int i = 0; i < 3; ++i)
    {
    x = semiMajor * tx;
    y = semiMinor * ty;

    ex = (semiMajor * semiMajor - semiMinor * semiMinor) * (tx * tx * tx) / semiMajor;
    ey = (semiMinor * semiMinor - semiMajor * semiMajor) * (ty * ty * ty) / semiMinor;

    rx = x - ex;
    ry = y - ey;

    qx = px - ex;
    qy = py - ey;

    r = Math.Sqrt(rx * rx + ry * ry);
    q = Math.Sqrt(qy * qy + qx * qx);

    tx = (qx * r / q + ex) / semiMajor;
    ty = (qy * r / q + ey) / semiMinor;

    t = Math.Sqrt(tx * tx + ty * ty);

    tx /= t;
    ty /= t;
    }

    return new Vector2
    {
    x = (float)(semiMajor * (point.x < 0 ? -tx : tx)),
    y = (float)(semiMinor * (point.y < 0 ? -ty : ty))
    };
    }
    }