Ellipse Arc Length

Category: Drawing

Date: 02-16-2022

Return to Index


 
'Compilable Example:  (Jose Includes)
#Compiler PBWin 10
#Compile Exe
#Dim All
%Unicode = 1
#Include "Win32API.inc"
 
Enum Equates Singular
   IDC_Graphic = 500
   IDC_Statusbar
   IDC_HalfAngle
   IDC_HalfChord
   IDC_Michael
End Enum
 
Global hDlg As Dword, rc As Rect, Choice, a,b As Long, BisectAngle,PI,theta1,theta2 As Single
 
Function PBMain() As Long
   Dialog Default Font "Tahoma",10,0
   Dialog New Pixels, 0, "Bisect Ellipse Arc",800,300,650,300, %WS_OverlappedWindow To hDlg
   Control Add Graphic, hDlg, %IDC_Graphic,"Push", 100,0,650,300
   Control Add Option, hDlg, %IDC_HalfAngle,"Half-Angle",10,10,90,20
   Control Add Option, hDlg, %IDC_HalfChord,"Half-Chord",10,30,90,20
   Control Add Option, hDlg, %IDC_Michael,"Michael",10,50,90,20
   Graphic Attach hDlg, %IDC_Graphic, ReDraw
   Control Add Statusbar, hDlg, %IDC_StatusBar, "Bisect Ellipse Arc",0,0,0,0
   Dialog Show Modal hDlg Call DlgProc
End Function
 
CallBack Function DlgProc() As Long
   Select Case Cb.Msg
      Case %WM_InitDialog
         PI = 3.14159
         theta1 = 1.5 * PI
         theta2 = 2 * PI
         Choice = 1
         Control Set Option hDlg, %IDC_HalfAngle, %IDC_HalfAngle, %IDC_Michael
      Case %WM_Command
         If Cb.Ctl = %IDC_HalfAngle And Cb.CtlMsg = %BN_Clicked Then Choice=1 : BisectTheAngle(Choice)
         If Cb.Ctl = %IDC_HalfChord And Cb.CtlMsg = %BN_Clicked Then Choice=2 : BisectTheAngle(Choice)
         If Cb.Ctl = %IDC_Michael   And Cb.CtlMsg = %BN_Clicked Then Choice=3 : BisectTheAngle(Choice)
      Case %WM_Size
         Local w,h As Long
         Dialog Get Client hDlg To w,h
         Control Set Size hDlg, %IDC_Graphic, w-100,h-25
         rc.nTop = 10
         rc.nLeft = 10
         rc.nBottom = h - 30
         rc.nRight = w - 110
         a = (rc.nRight   - rc.nLeft)/2
         b = (rc.nBottom - rc.nTop)/2
         BisectTheAngle(Choice)
   End Select
End Function
 
Sub BisectTheAngle(Approach As Long)
   Local rVert, rHorz, x0,y0,x,y,x1,x2,y1,y2,xc,yc,tn,newTheta1,newTheta2 As Single
   rVert = (rc.nBottom - rc.nTop) / 2 : rHorz = (rc.nRight - rc.nLeft) / 2
   x0 = (rc.nRight + rc.nLeft) / 2    : y0 = (rc.nTop + rc.nBottom) / 2
   BisectAngle = 0
   Graphic Clear
   Graphic Pie (RC.nLeft,RC.nTop)-(RC.nRight,RC.nBottom),0,1.5*PI, %Blue          'full ellipse
   Graphic Pie (RC.nLeft,RC.nTop)-(RC.nRight,RC.nBottom),1.5*PI,2.0*PI, %Red      'lower right quadrant
   Select Case Approach
      Case 1  'half-angle
         BisectAngle = (theta1 + theta2)/2
         Graphic Pie (RC.nLeft,RC.nTop)-(RC.nRight,RC.nBottom),BisectAngle-0.001,BisectAngle+0.001, %rgb_DarkRed  'bisecting line
         Statusbar Set Text hDlg, %IDC_StatusBar, 1,0, "Half-Angle method"
      Case 2  'half-chord
         'theta1 point on ellipse
         tn = Tan(-theta1)
         x = rVert * rHorz      / ((rVert*rVert + rHorz*rHorz*tn*tn)^0.5)
         y = rVert * rHorz * tn / ((rVert*rVert + rHorz*rHorz*tn*tn)^0.5)
         If theta1 >= PI/2 And theta1 <= 1.5*PI Then x = -1 * x : y = -1 * y
         x1 = x0 + x
         y1 = y0 + y
         Graphic Line (x0,y0)-(x1,y1), %Green   'theta1
         'theta2 point on ellipse
         tn = Tan(-theta2)
         x = rVert * rHorz      / ((rVert*rVert + rHorz*rHorz*tn*tn)^0.5)
         y = rVert * rHorz * tn / ((rVert*rVert + rHorz*rHorz*tn*tn)^0.5)
         If theta2 >= PI/2 And theta2 <= 1.5*PI Then x = -1 * x : y = -1 * y
         x2 = x0 + x
         y2 = y0 + y
         Graphic Line (x0,y0)-(x2,y2), %Green  'theta2
         'the chord
         Graphic Line (x1,y1)-(x2,y2), %Green  'chord
         'midpoint (draw line to show it)
         x = (x1+x2)/2
         y = (y1+y2)/2
'         Graphic Line (x0,y0)-(x,y), %Green  'center through mid-chord
         'calculate the angle to the middle of the chord
         BisectAngle = Atn(-1*(y-y0)/(x-x0))
         If y >= y0 And x >= x0 Then  'quadrant1
            'no change
         ElseIf y >= y0 And x <= x0 Then  'quadrant2
             BisectAngle += PI/2
         ElseIf y <= y0 And x <= x0 Then  'quadrant3
             BisectAngle += PI
         ElseIf y <= y0 And x >= x0 Then  'quadrant4
             BisectAngle += 1.5*PI
         End If
         Graphic Pie (RC.nLeft,RC.nTop)-(RC.nRight,RC.nBottom),BisectAngle-0.001,BisectAngle+0.001, %rgb_DarkRed  'bisecting line
         Statusbar Set Text hDlg, %IDC_StatusBar, 1,0, "Half-Chord method"
      Case 3  'Michael foreshortening
         If theta1 <= PI/2 Or theta1 >= 1.5*PI Then        'first and fourth quadrants
            newTheta1 = Atn(rVert/rHorz * Sin(theta1) / Cos(theta1))
         ElseIf (theta1 >= PI/2) And (theta1 <= 1.5*PI) Then  'second and third quadrants
            newTheta1 = PI - Atn(rVert/rHorz * Sin(Pi - theta1) / Cos(Pi - theta1))
         End If
         If (theta2 <= PI/2) Or (theta2 >= 1.5*PI) Then        'first and fourth quadrants
            newTheta2 = Atn(rVert/rHorz * Sin(theta2) / Cos(theta2))
         ElseIf (theta2 >= PI/2) And (theta2 <= 1.5*PI) Then  'second and third quadrants
            newTheta2 = PI - Atn(rVert/rHorz * Sin(Pi - theta2) / Cos(Pi - theta2))
         End If
         BisectAngle = 1.5*PI + (newTheta1+newTheta2)/2  'PI * (CumPct + CumPct - Pct(n))
         Graphic Pie (RC.nLeft,RC.nTop)-(RC.nRight,RC.nBottom),BisectAngle-0.001,BisectAngle+0.001, %rgb_DarkRed  'bisecting line
         Statusbar Set Text hDlg, %IDC_StatusBar, 1,0, "Michael Method"
   End Select
   Graphic ReDraw
End Sub
 


created by gbSnippets
http://www.garybeene.com/sw/gbsnippets.htm