Date: 02-16-2022
Return to Index
created by gbSnippets
'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
http://www.garybeene.com/sw/gbsnippets.htm