Date: 02-16-2022
Return to Index
'Compilable Example: (Jose Includes)
created by gbSnippets
#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
IDC_ChordWalker
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
Control Add Option, hDlg, %IDC_ChordWalker,"Walker",10,70,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 '4.712385
theta2 = 2 * PI '6.28318
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)
If Cb.Ctl = %IDC_ChordWalker And Cb.CtlMsg = %BN_Clicked Then Choice=4 : 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,R,RP As Single
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
GetXYOnEllipsePerimeter RC, BisectAngle, x1,y1, %True, %Red
Statusbar Set Text hDlg, %IDC_StatusBar, 1,0, "Half-Angle method"
Case 2 'half-chord
x0 = (rc.nRight + rc.nLeft) / 2 : y0 = (rc.nTop + rc.nBottom) / 2
GetXYOnEllipsePerimeter RC, Theta1, x1,y1, %True, %Red
GetXYOnEllipsePerimeter RC, Theta2, x2,y2, %True, %Red
Graphic Line (x1,y1)-(x2,y2), %Green 'chord
Graphic Line (x0,y0)-((x1+x2)/2,(y1+y2)/2), %Green 'line from center to midpoint of chord
BisectAngle = Atn(-1*(y-y0)/(x-x0)) 'calculate the angle to the middle of the chord
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
GetXYOnEllipsePerimeter RC, BisectAngle, x1,y1, %True, %Red
Statusbar Set Text hDlg, %IDC_StatusBar, 1,0, "Half-Chord method"
Case 3 'Michael foreshortening
Case 4 'Chord Walker
x0 = (rc.nRight + rc.nLeft) / 2 : y0 = (rc.nTop + rc.nBottom) / 2
RP = ArcLength(RC, theta1, theta2, 50)/2 'full perimeter
GetXYOnEllipsePerimeter RC, Theta1, x1,y1, %True, %Red
GetXYOnEllipsePerimeter RC, Theta2, x1,y1, %True, %Red
For BisectAngle = theta2 To theta1 Step -0.01
GetXYOnEllipsePerimeter RC, BisectAngle, x1,y1, %True, %Red
R = ArcLength(RC, BisectAngle,theta2, 50)
If R >= RP Then Graphic Line (x0,y0)-(x1,y1),%Blue : Exit For 'Draw to point on ellipse perimeter
Next i
Statusbar Set Text hDlg, %IDC_StatusBar, 1,0, "Walker method"
End Select
Graphic ReDraw
Beep
End Sub
Sub GetXYOnEllipsePerimeter (RC As Rect, ByVal theta As Single, x1 As Single, y1 As Single, DrawLineToXY As Long, iColor As Long)
Local rVert, rHorz, x0,y0,x,y,tn As Single
theta+=0.001
rVert = (rc.nBottom - rc.nTop) / 2
rHorz = (rc.nRight - rc.nLeft) / 2
x0 = (rc.nRight + rc.nLeft) / 2
y0 = (rc.nTop + rc.nBottom) / 2
tn = Tan(-theta)
x = rVert * rHorz / ((rVert*rVert + rHorz*rHorz*tn*tn)^0.5)
y = rVert * rHorz * tn / ((rVert*rVert + rHorz*rHorz*tn*tn)^0.5)
If theta >= PI/2 And theta <= 1.5*PI Then x = -1 * x : y = -1 * y
x1 = x0 + x
y1 = y0 + y
If DrawLineToXY Then Graphic Line (x0,y0)-(x1,y1), iColor
End Sub
http://www.garybeene.com/sw/gbsnippets.htm