4
$\begingroup$

How can I use Mathematica (version 9) to plot an ellipse, given the coordinates of its two foci and the length of its semimajor axis, where the major axis is not necessarily parallel to either the $x$-axis or the $y$-axis? I also need the scales of the two axes to be equal.

For example, the foci might be at $(3,2)$ and $(5,1)$ and the semimajor axis might be $1.7$.

The following gives an ellipse of the right size, shape, and centre, but wrong orientation:

Graphics[Circle[{4, 1.5}, {1.7, Sqrt[1.64]}]]
$\endgroup$
3
  • 4
    $\begingroup$ Is this a Mathematica question ? How would you do it outside Mathematica ? $\endgroup$
    – Lotus
    Commented Aug 27, 2018 at 13:00
  • $\begingroup$ Welcome to Mathematica.SE. Are you sure you are posting on the right site? There is nothing in your question making it clear that it is concerned with Mathematica software. $\endgroup$
    – m_goldberg
    Commented Aug 27, 2018 at 14:13
  • $\begingroup$ Edited to make clear. $\endgroup$
    – user59886
    Commented Aug 27, 2018 at 15:21

5 Answers 5

3
$\begingroup$

You can find a geometric solution to this problem by using an implicit region definition directly based on the definition of an ellipse: sum of distances from foci equals twice the semimajor axis.

With[{foci = {{3, 2}, {5, 1}}, semimajoraxis = 3/2},
 Region[ImplicitRegion[
   Sum[EuclideanDistance[{x, y}, p], {p, foci}] == 
    2 semimajoraxis, {x, y}],
  Axes -> True, Epilog -> {Red, Point[foci]}]]

ellipse

Geometric regions functionality was introduced in Mathematica 10. Similar things can be accomplished using RegionPlot on earlier versions, but it requires explicit plot range, which complicates the approach (basically here I define the plot range to be $\pm \mathtt{semimajoraxis}$ on $x$ and $y$ axes).

With[{foci = {{3, 2}, {5, 1}}, semimajoraxis = 3/2},
 RegionPlot[
  Sum[EuclideanDistance[{x, y}, p], {p, foci}] < 2 semimajoraxis, 
  Evaluate[Sequence @@ 
    MapThread[{#1, #2 - semimajoraxis, #2 + semimajoraxis} &, {{x, y},
       Mean[foci]}]],
  AspectRatio -> Automatic, PlotStyle -> None, 
  Epilog -> {Red, Point[foci]}]]

ellipse

I hope this works for you, since my v9 seems to nag about need for legacy Java. Does it work?

$\endgroup$
4
  • $\begingroup$ Many thanks for this. It's just what I need, but can it be made to work for Mma v9? $\endgroup$
    – user59886
    Commented Aug 27, 2018 at 15:29
  • $\begingroup$ @ruffle Oh my. Geometric regions functionality was introduced in v10. I'll add a RegionPlot variant which should work in v9 in a moment. $\endgroup$
    – kirma
    Commented Aug 27, 2018 at 15:34
  • $\begingroup$ @ruffle Try again, does it work? $\endgroup$
    – kirma
    Commented Aug 27, 2018 at 15:53
  • 1
    $\begingroup$ Yes, this works perfectly. Many thanks! $\endgroup$
    – user59886
    Commented Aug 27, 2018 at 16:33
3
$\begingroup$
foci = {{3, 2}, {5, 1}};
a = 3/2;

{{x1, y1}, {x2, y2}} = foci;
d = EuclideanDistance @@ foci;

{ContourPlot[Sum[EuclideanDistance[{x, y}, p], {p, foci}] == 2 a, 
{x, 2.5, 5.5}, {y, 0.3, 2.7}, AspectRatio -> Automatic], 

 ParametricPlot[{(x1 + x2)/2, (y1 + y2)/2} + 
  {a/d (x2 - x1) Cos[t] + Sqrt[a^2/d^2 - 1/4] (y1 - y2) Sin[t], 
   a/d (y2 - y1) Cos[t] + Sqrt[a^2/d^2 - 1/4] (x2 - x1) Sin[t]}, 
   {t, 0, 2 Pi}]
}

enter image description here

$\endgroup$
3
$\begingroup$

I came across this (not so recent) question, and it occurs to me that the following code is simpler - assuming all you want is the plot:

foci = {{3, 2}, {5, 1}}; semimajoraxis = 3/2; 
Graphics[{Rotate[Circle[Mean[foci], {3/2, 1}], 
   VectorAngle[{1, 0}, foci[[1]] - Mean[foci]]], 
   {Red, 
   Point /@ {foci, Mean[foci]}}}, Axes -> True, 
   AxesOrigin -> {2.5, 0}] 

Tomas Garza

$\endgroup$
2
$\begingroup$

I will note that one can use Ellipsoid[] for this:

With[{f1 = {3, 2}, f2 = {5, 1}, a = 17/10},
     With[{r = RotationMatrix[{{1, 0}, f2 - f1}]},
          Graphics[{Directive[EdgeForm[ColorData[97, 1]], FaceForm[]], 
                    Ellipsoid[(f1 + f2)/2, 
                              r.DiagonalMatrix[{a^2, a^2 - Norm[f1 - f2]^2/4}].Transpose[r]]},
                   Frame -> True]]]

ellipse


If one is dissatisfied with Ellipsoid[] (like in this answer), one could also fall back on the NURBS representation. Here is a routine for making the BSplineCurve[] equivalent of Ellipsoid[]:

makeEllipse[p_?VectorQ, m_?MatrixQ] := Module[{aff, eig},
    eig = Eigensystem[N[m]];
    aff = AffineTransform[{Transpose[eig[[2]]].DiagonalMatrix[Sqrt[eig[[1]]]], p}];
    BSplineCurve[aff[{{1, 0}, {1, 1}, {-1, 1}, {-1, 0}, {-1, -1}, {1, -1}, {1, 0}}],
                 SplineClosed -> True, SplineDegree -> 2, 
                 SplineKnots -> {0, 0, 0, 1/4, 1/2, 1/2, 3/4, 1, 1, 1}, 
                 SplineWeights -> {1, 1/2, 1/2, 1, 1/2, 1/2, 1}]]

and now one can use makeEllipse[] as a replacement for Ellipsoid[] in the code given above.

$\endgroup$
1
$\begingroup$

You can use the "SplineCircle" resource function to specify the semimajor axis direction:

Graphics[
    {
    ResourceFunction["SplineCircle"][{4,1.4}, {1.7,Sqrt[1.64]}, {2,-1}],
    Red, Point[{{3,2}, {5,1}}]
    },
    Axes->True
]

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.