Calculating an arc of on ellipse from an internally offset point

Hey everyone,

I’ve been struggling a bit with an issue dealing with calculating the arcs of an ellipse. In the attached image you’ll see a rectangle surrounded by an ellipse. The ellipse and rectangle share the same center, but both are divided into four quadrants. I am trying to come up with a formula that describes the ellipse’s four corresponding arcs, drawn from a point that is offset from the center of the two shapes. I don’t have any issues dealing with a circular shape instead of an ellipse as long as the arcs originate in the center instead of being offset. Surely there is some formula out there for drawing an ellipse from any point inside the ellipse? All my searches have come up with just drawing a regular ellipse offset from 0,0, NOT from a point offset internally.

The whole reason for this is to be able to draw a section of shielding around a ship that corresponds to the quadrant it is in.184322-ellipse-arcs.png

Sorry but I really do not grasp what you’re asking here. What do you mean by calculating “the arcs of an ellipse”? Are you looking for the arc lengths? However how do you actually split up the ellipse? Note that there is no neat equation to calculate the circumference of an ellipse.

I’m also not sure what you mean by “four corresponding arcs, drawn from a point that is offset from the center”. To me it’s totally unclear what you’re actually looking for in terms of numbers, coordinates, lengths, … One one hand you want to some how start at an arbitrary point inside your ellipse, on the other hand you want to start at the center. When you talk about quadrants, do you actually mean sectors that are 90° apart from each other? Or do you have something else in mind?

edit

Ok since it’s now more clear what you want, here’s an example how to calculate what you want. First of all, here’s the result visually:

Note the magenta lines are your original lines which are defined by the angles at the left. The “center” is the origin of your lines / rays. The actual center of the ellipse is (0, 0) indicated by the cyan lines. The yellow crosses are the intersection points on the squished ellipse / circle while the green crosses are the intersection point transformed back to the ellipse.

Here’s the script I quickly hacked together ^^

using UnityEngine;

public class EllipseCalc : MonoBehaviour
{
    public float a = 6;
    public float b = 4;
    public float angB = 42.5f;
    public float angR = 137.5f;
    public float angF = 222.5f;
    public float angL = 317.5f;
    public Vector2 center = new Vector2(-2,0);
    public int count = 360;

    void Update()
    {
        // draw ellipse
        var lastPos = new Vector2(a, 0);
        for(int i = 1; i <= count; i++)
        {
            float ang = i*Mathf.PI*2f / count;
            float s = Mathf.Sin(ang);
            float c = Mathf.Cos(ang);
            var p = new Vector2(c * a, s * b);
            Debug.DrawLine(lastPos, p);
            lastPos = p;
        }
        CalcLine(center, angB);
        CalcLine(center, angR);
        CalcLine(center, angF);
        CalcLine(center, angL);

        // draw circle
        lastPos = new Vector2(b, 0);
        for (int i = 1; i <= count; i++)
        {
            float ang = i * Mathf.PI * 2f / count;
            float s = Mathf.Sin(ang);
            float c = Mathf.Cos(ang);
            var p = new Vector2(c * b, s * b);
            Debug.DrawLine(lastPos, p);
            lastPos = p;
        }

        // draw origin
        Debug.DrawLine(Vector3.up * 10, -Vector3.up * 10, Color.cyan);
        Debug.DrawLine(Vector3.right * 10, -Vector3.right * 10, Color.cyan);
    }

    Vector2 DrawLine(Vector2 aCenter, float aAng, Color aColor)
    {
        aAng *= Mathf.Deg2Rad;
        float s = Mathf.Sin(aAng);
        float c = Mathf.Cos(aAng);
        var p = new Vector2(c, s);
        Debug.DrawLine(aCenter, aCenter + p * 20, aColor);
        return p;
    }

    float CalcLine(Vector2 aCenter, float aAng)
    {
        var d = DrawLine(aCenter, aAng, Color.magenta);

        d.x *= b / a;
        aCenter.x *= b / a;
        Debug.DrawLine(aCenter, aCenter + d * 20);
        if (IntersectLineCircle(aCenter, d, Vector2.zero, b, out float t))
        {
            var p = aCenter + d * t;
            Debug.DrawLine(p - Vector2.right, p + Vector2.right, Color.yellow);
            Debug.DrawLine(p - Vector2.up, p + Vector2.up, Color.yellow);
            p.x *= a / b;
            Debug.DrawLine(p - Vector2.right, p + Vector2.right, Color.green);
            Debug.DrawLine(p - Vector2.up, p + Vector2.up, Color.green);
            float newAng = Mathf.Atan2(p.y, p.x);
            return newAng;
        }
        return 0f;
    }

    public static bool IntersectLineCircle(Vector3 aStart, Vector3 aDir, Vector3 aCenter, float aRadius, out float aT)
    {
        aT = float.NaN;
        var dist = aStart - aCenter;

        float a = aDir.sqrMagnitude;
        float b = 2 * Vector3.Dot(dist, aDir);
        float c = dist.sqrMagnitude - aRadius*aRadius;

        float d = b * b - 4 * a * c;
        if (d < 0)
            return false;

        d = Mathf.Sqrt(d);
        //float t1 = (-b - d) / (2 * a);
        float t2 = (-b + d) / (2 * a);
        if (t2 < 0)
            return false;
        aT = t2;
        return true;
    }
}