Ellipses
Interactive ellipses extend the circle concept to support different horizontal and vertical radii. In Locus, ellipses are created using the Circle component with different width and height values.
Creating an Ellipse
An ellipse is simply a circle with different width and height dimensions:
import { Circle } from '@wangyaoshen/locus-2d';
// Create an ellipse with width=200, height=100
<Circle
width={200}
height={100}
fill="rgba(33, 150, 243, 0.3)"
stroke="#2196F3"
lineWidth={3}
/>
Interactive Ellipse
Use InteractiveCircle with different dimensions to create a draggable ellipse:
import { InteractiveCircle } from '@wangyaoshen/locus-2d';
import { Vector2 } from '@wangyaoshen/locus-core';
<InteractiveCircle
width={200}
height={100}
fill="rgba(156, 39, 176, 0.3)"
stroke="#9C27B0"
lineWidth={3}
position={new Vector2(0, 0)}
interactive={true}
onMove={(pos) => console.log('Ellipse center:', pos)}
/>
Ellipse Properties
| Property | Description |
|---|---|
width | Horizontal diameter (2 × semi-major axis if width > height) |
height | Vertical diameter (2 × semi-minor axis if width > height) |
position | Center point of the ellipse |
fill | Fill color |
stroke | Stroke color |
Use Cases
Orbit Visualization
// Create an elliptical orbit path
<Circle
width={400}
height={200}
stroke="#4CAF50"
lineWidth={2}
fill="transparent"
/>
// Add a draggable point on the orbit
<InteractiveCircle
size={20}
fill="#FF5722"
position={new Vector2(200, 0)}
constrain={ellipse([0, 0], 200, 100)}
interactive={true}
/>
Ellipse with Foci
// For an ellipse with semi-axes a and b:
// c = sqrt(a² - b²) where a > b
const a = 200; // semi-major
const b = 100; // semi-minor
const c = Math.sqrt(a * a - b * b);
// Foci at (-c, 0) and (c, 0)
const focus1 = [-c, 0];
const focus2 = [c, 0];
Constraining to Ellipse
Use the ellipse constraint to keep points on an elliptical path:
import { InteractivePoint, ellipse } from '@wangyaoshen/locus-interaction';
const point = new InteractivePoint({
position: [200, 0],
// Constrain to ellipse centered at origin with semi-axes 200, 100
constrain: ellipse([0, 0], 200, 100),
onMove: (pos) => {
const angle = Math.atan2(pos[1] / 100, pos[0] / 200);
console.log('Angle on ellipse:', angle);
},
});
Ellipse vs Circle
| Aspect | Circle | Ellipse |
|---|---|---|
| Radii | Equal (r) | Different (a, b) |
| Equation | x² + y² = r² | x²/a² + y²/b² = 1 |
| Foci | One (center) | Two (along major axis) |
| Eccentricity | 0 | 0 < e < 1 |
Mathematical Properties
For an ellipse with semi-major axis a and semi-minor axis b:
// Eccentricity
const eccentricity = Math.sqrt(1 - (b * b) / (a * a));
// Focal distance from center
const focalDistance = Math.sqrt(a * a - b * b);
// Point on ellipse at angle θ
const pointOnEllipse = (theta) => [
a * Math.cos(theta),
b * Math.sin(theta),
];
// Perimeter (approximation)
const perimeter = Math.PI * (3 * (a + b) - Math.sqrt((3 * a + b) * (a + 3 * b)));
// Area
const area = Math.PI * a * b;