The Ellipse

Autocad has an ellipse object. The AddEllipse method takes a center point, a second point which is the end of the major axis, and a factor autodesk calls RadiusRatio, which is just b / a. This is not the same thing as Eccentricity which is c / a, though similar but inverse and they both must be less than 1. I have not seen RadiusRatio in a math book. RadiusRatio gives a circle if it is equal to 1. If it is greater than 1 it throws an error. Eccentricity is a math term and gives a circle when it is zero. If it were 1 i believe the ellipse would collapse to a straight line.

To create an autocad vba ellipse with vertical axis, make the second point, MajorAxis, vertical above the center point. Autocad gives no indication where the Focus is. It has to be calculated from the values of A and B.

```Sub init_frm_ellipse()
a = frm_Ellipse.txt_a1
b = frm_Ellipse.txt_b1
End Sub

Sub horz_new_ellipse()
'RadiusRatio must be less than or equal to 1
'MajorAxis is a relative point off the center, not an absolute point
Call init_frm_ellipse

Dim ptctr(0 To 2) As Double
Dim pta(0 To 2) As Double
Call initpt(ptctr, 0, 0, 0)
Call initpt(pta, a, 0, 0)

obj_ellipse.Update
End Sub

Sub vert_new_ellipse()
Call init_frm_ellipse

Dim ptctr(0 To 2) As Double
Dim pta(0 To 2) As Double
Call initpt(ptctr, 0, 0, 0)
Call initpt(pta, 0, a, 0)

obj_ellipse.Update
End Sub
```

The autodesk method advantage is that by specifying a center, then a relative point from the center for the end of the major axis, the ellipse can be turned to any angle. With some simple trig we can accept input in degrees and calculate the major axis vertex.

``` Function deg2rad(deg As Double) As Double
deg2rad = deg * Pi / 180
End Function

Sub init_frm_ellipse()
a = frm_Ellipse.txt_a1
b = frm_Ellipse.txt_b1
c = frm_Ellipse.txt_c1
End Sub

Sub new_ellipse()
'RadiusRatio must be less than or equal to 1
'MajorAxis is a point, not a length
Call init_frm_ellipse

Dim ptctr(0 To 2) As Double
Dim pta(0 To 2) As Double
Dim x1 As Double, y1 As Double

Call initpt(ptctr, 0, 0, 0)
Call initpt(pta, x1, y1, 0)

obj_ellipse.Update
End Sub
```

we can move the ellipse off the center. The input for AddEllipse does not require an absolute point for MajorAxis. It takes a point relative to the center.

Drawing the ellipse is straightforward. calculating the focus and end points to mark them requires some trig to accomodate the angled axes.

```
Sub new_ellipse()
'takes input from the form
'a major axis
'b minor axis
'd degree of major axis
'h and k, xy values for center of ellipse
'converts input to
'RadiusRatio must be less than or equal to 1
'MajorAxis is a point relative from the center, not an absolute point
Call init_frm_ellipse ' gets the values from the form

Dim ctr(0 To 2) As Double
Dim pt_a(0 To 2) As Double
Dim x1 As Double, y1 As Double

Call initpt(ctr, h, k, 0)
Call initpt(pt_a, x1, y1, 0)

obj_ellipse.Update

'to plot points
Dim pt_a1(0 To 2) As Double
Dim pt_a2(0 To 2) As Double
Dim pt_b1(0 To 2) As Double
Dim pt_b2(0 To 2) As Double
Dim pt_f1(0 To 2) As Double
Dim pt_f2(0 To 2) As Double

Dim fx1 As Double, fy1 As Double, fx2 As Double, fy2 As Double
Dim ax1 As Double, ay1 As Double, ax2 As Double, ay2 As Double
Dim bx1 As Double, by1 As Double, bx2 As Double, by2 As Double

'c is the focal distance from ctr
c = (a ^ 2 - b ^ 2) ^ 0.5
fx1 = h + c * Cos(deg2rad(d))
fy1 = k + c * Sin(deg2rad(d))
fx2 = h - c * Cos(deg2rad(d))
fy2 = k - c * Sin(deg2rad(d))

bx1 = h + b * Cos(deg2rad(d + 90))
by1 = k + b * Sin(deg2rad(d + 90))

bx2 = h - b * Cos(deg2rad(d + 90))
by2 = k - b * Sin(deg2rad(d + 90))

ax1 = h + a * Cos(deg2rad(d))
ay1 = k + a * Sin(deg2rad(d))

ax2 = h - a * Cos(deg2rad(d))
ay2 = k - a * Sin(deg2rad(d))

Call initpt(pt_a1, ax1, ay1, 0)
Call initpt(pt_a2, ax2, ay2, 0)
Call initpt(pt_b1, bx1, by1, 0)
Call initpt(pt_b2, bx2, by2, 0)
Call initpt(pt_f1, fx1, fy1, 0)
Call initpt(pt_f2, fx2, fy2, 0)

Update

End Sub
```

In astronomy, planets orbit around the sun in ellipses with the sun at one focus. To draw these orbits we need to input the different numbers but always draw one focus, the sun, at the origin.

orbits of the nine planets (simplified with major axes aligned, no inclination). The sun and all planets are drawn full size, but the distances of the orbits are so vast they are not seen. this is much more fun to do yourself to zoom around and get a feel for the distance than to look at a screenshot.

the astronomy book gives the half major axis in (x 10^6 km), Orbital Eccentricity, and planet radius in km. those are the inputs. The value for Uranus caused Long and Double variable types to overflow but i had no issues using Currency data type. don’t base your senior thesis on this, i dont have supervision. it gives a visually correct orbit for pluto that it actually crosses inside neptune’s orbit because of pluto’s higher eccentricity. there are other 3D factors i do not take into consideration, inclination – ellipse tilt – and two other twists in 3D space. so neptune and pluto can never collide.

```Public Const xkm As Currency = 1000000

Sub solar_system()
'testCall planetary_ellipse(6, 0.5, 1)

Dim pt0(0 To 2) As Double
Call initpt(pt0, 0, 0, 0)

'this is the sun

'mercury
Call planetary_ellipse(57.9 * xkm, 0.206, 2440)

'venus
Call planetary_ellipse(108.2 * xkm, 0.007, 6052)

'earth
Call planetary_ellipse(149.6 * xkm, 0.017, 6378)

'mars
Call planetary_ellipse(227.9 * xkm, 0.093, 3397)

'jupiter
Call planetary_ellipse(778.4 * xkm, 0.048, 71492)

'saturn
Call planetary_ellipse(1427 * xkm, 0.054, 60268)

'too large
'uranus
Call planetary_ellipse(2871 * xkm, 0.047, 25559)

'neptune
Call planetary_ellipse(4498 * xkm, 0.009, 24764)

'pluto
Call planetary_ellipse(5906 * xkm, 0.249, 1195)

End Sub

Sub planetary_ellipse(a As Currency, e As Double, r As Long)
'a is major axis km
'e is eccentricity
'r is planetary equatorial radius in km

'RadiusRatio must be less than or equal to 1
'MajorAxis is a point, not a length

Dim b As Double
Dim c As Double

Dim ctr(0 To 2) As Double
Dim f1(0 To 2) As Double
Dim f2(0 To 2) As Double
Dim pt_a(0 To 2) As Double
Dim pt_p(0 To 2) As Double
Dim a_vector(0 To 2) As Double

c = a * e
b = a * (1 - e ^ 2) ^ 0.5

Call initpt(ctr, c, 0, 0)
Call initpt(f1, 0, 0, 0)
Call initpt(f2, 2 * c, 0, 0)
Call initpt(pt_a, a + c, 0, 0)
Call initpt(pt_p, c - a, 0, 0)

Call initpt(a_vector, 1 * a, 0, 0)