title: Given a fixed Angle, Width & Sagitta how can we calculate the horizontal and vertical radiuses of an ellipse?
body: <p>Given a fixed Angle, Width &amp; Sagitta how can we calculate the horizontal and vertical radiuses of an ellipse?</p>
  
  <p>I want to draw an elliptical arc that has a given arc width, height (Sagitta) and is a given angle of the ellipse.<br>
  In the below diagram the dashed black and yellow arc. To do this I need to know the 2 radiuses of the ellipse.</p>
  
  <p>For a circle, one can easily calculate it's 1 radius give any 2 values of the angle, sagitta or width.<br>
  See the snippet below.<br>
  How can I adapt the function to work for an ellipse?
  I the diagram the angle is so to speak symmetrical from -60 to 60 making an angle of 120. This is the case I really need i.e. where the arc reflects itself on both sides of either the vertical or horizontal axises.<br>
  In a case where the angle was 120 that started at 80 and ended at 200 there is no true sagitta just the highest point of the arc and a tight bounding box that would be much harder to solve if anyone has a solution also for that it would be a luxury.</p>
  
  <p><a href="https://i.stack.imgur.com/goO92.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/goO92.png" alt="Ellipse"></a></p>
  
  <pre><code>var arcCalc = function(r, w, a, s) {
    // to allow for object usage
    if (r instanceof Object) {
      w = r.w || r.width;
      a = r.a || r.angle;
      s = r.s || r.sagitta;
      r = r.r || r.radius;
    }
    w = this.toPts(w);
    s = this.toPts(s);
    r = this.toPts(r);
    var sin, cos, twoKnown;
    sin = Math.sin;
    cos = Math.cos;
    // if we know any two arguments then we can work out the other ones
    // if not we can't
    twoKnown = +!r + +!w + +!a + +!s &lt; 3;
    // At this point of time we are trying to avoid throwing errors
    // so for now just throw back the garbage we received
    if (!twoKnown)
      return {
        radius: r,
        width: w,
        angle: a,
        sagitta: s,
        r: r,
        w: w,
        a: a,
        s: s
      };
    if (a) {
      a *= Math.PI / 180;
    }
  
    if (!r) {
      if (!s) {
        r = w / (2 * sin(a / 2));
      } else if (!a) {
        r = (s * s + 0.5 * w * (0.5 * w)) / (2 * s);
      } else {
        r = s / (1 - cos(a / 2));
      }
    }
    // at this point we know we have r
    if (!w) {
      if (!s) {
        w = 2 * r * sin(a / 2);
      } else {
        w = 2 * Math.sqrt(s * (2 * r - s));
      }
    }
    // at this point we know we have r and w
    if (!a) {
      if (!s) {
        // We added the round because
        // w / (2*r) could come to 1.00000000001
        // and then NaN would be produced
        a = 2 * Math.asin(this.round(w / (2 * r)));
      } else {
        a = 2 * Math.acos(this.round(1 - s / r));
      }
    }
    if (!s) {
      s = r - r * cos(a / 2);
    }
  
    a *= 180 / Math.PI;
    return {
      radius: r,
      width: w,
      angle: a,
      sagitta: s,
      r: r,
      w: w,
      a: a,
      s: s
    };
  };
  </code></pre>