I have a problem that is really beginning to annoy me. I am getting bogged
down in the maths of radius, chord etc. of an arc.
Ideally I would want an object to move from the start point (X,Y) to an end
point (X,Y) along the path of an arc for a circle with a given radius and a
lower point say mid point (X,Y).
I have looked at so many maths sites (maths not being my strong point), and
seem to be getting nowhere very quickly. Any pointers would be appreciated.
Thanks again.
Alastair MacFarlane
Perhaps this may be of use:
'form with a timer & a command button as the 'object' to move
Option Explicit
Private PI As Single
Private CX As Single, CY As Single
Private Radius As Single
Private Angle As Single
'180-Ang makes 0 degrees=12 o'clock
Private Function GetX(ByVal Ang As Single, ByVal Rad As Single) As Single
GetX = Rad * Sin(Radians(180 - Ang))
End Function
Private Function GetY(ByVal Ang As Single, ByVal Rad As Single) As Single
GetY = Rad * Cos(Radians(180 - Ang))
End Function
Private Function Radians(ByVal Deg As Single) As Single
Radians = (Deg * PI) / 180
End Function
Private Sub Form_Load()
PI = 4 * Atn(1)
AutoRedraw = True
ScaleMode = vbPixels
CX = ScaleWidth \ 2
CY = ScaleHeight \ 2
Radius = CX * 0.5
Command1.Move CX + GetX(Angle, Radius), CY + GetY(Angle, Radius)
Circle (CX, CY), Radius
Timer1.Interval = 100
End Sub
Private Sub Timer1_Timer()
Command1.Move CX + GetX(Angle, Radius), CY + GetY(Angle, Radius)
Angle = Angle + 1
End Sub
Rather you should be determined to solve the problem !.
> Ideally I would want an object to move from the start point (X,Y) to an
> end point (X,Y) along the path of an arc for a circle with a given radius
> and a lower point say mid point (X,Y).
Are you talking of the centerpoint ?.
> I have looked at so many maths sites (maths not being my strong point),
> and seem to be getting nowhere very quickly. Any pointers would be
> appreciated.
Yet, did you get somewhere. If so, it's just about if you already
made some usable.
> Thanks again.
>
> Alastair MacFarlane
>
Knowing the start -and end -angles you calculate
the coordinates to the startpoint and endpoint.
Divide the angle between these points into
infinitesimal angle units, for exampel 0,5 degree.
Then let the procedure calculate the coordinates
to all these point too. The points can be calculated
on the fly, or they could be stored in an array before
the move begins.
When start to move then use the SetPoint metode
to set the current point at the startpoint, and from
there, go to the next point by a strait line using the
Line methode: Line -(X,Y)
and so on to the endpoint.
To control the speed of the move, you can use
a timer to signal begining of the next linesegment.
If it bumps too much, you gotta calculate more
points or smaller infinitisimals.
The program should be set up to calculate all
these points -not you.
/senn
Thanks for the speedy reply. It will take me a while to understand the code.
I appreciate your time this Saturday and have a pleasant weekend.
Alastair MacFarlane
"Norm Cook" <norm...@cableone.net> wrote in message
news:%23OipzcS...@TK2MSFTNGP04.phx.gbl...
Thanks for the pointer to solve the problem. You just know when you are not
going to get an answer to problem without asking for help. I have no issues
with admitting defeat.
I was not directly asking for an answer that Norm provided. He went further
than I expected.
I do appreciate your help. Thanks.
Alastair MacFarlane
"senn" <senn@homeplace&.fix> wrote in message
news:OsaVRhS2...@TK2MSFTNGP05.phx.gbl...
"Norm Cook" <norm...@cableone.net> skrev i en meddelelse
news:%23OipzcS...@TK2MSFTNGP04.phx.gbl...
> '180-Ang makes 0 degrees=12 o'clock
In Visual Basic degrees is measured relative
to the positive X-axis Clockwise around
(in a Forms standard coordinate system).
So 12 o'clock is 270 degrees( or -90 degrees ).
You have unfortunately interchanged Sin and Cos
in the functions GetX and GetY.
If you want these to comply with the VB established
coordinate system, these functions should rather be
GetX = Rad * Cos(Radians(Ang))
GetY = Rad * Sin(Radians(Ang))
/senn
Hi Senn
I've been doing some work with angles and curves recently, with some help
and pointers from yourself (Thank you). I read what you wrote above and it
dosn't look right. I would have said
"In Visual Basic degrees is measured relative
to the positive X-axis antiClockwise around
So 12 o'clock is 90 degrees
So to get from 3 oclock to 12 oclock you would have to go from 0 Deg to 90
Deg
Me.Circle (100, 100), 60, , 0 * PI / 180, 90 * PI / 180
(I always work in pixels)
Am I right or missing something?
Ivar
Is the lower point is the center of a circle or a point on it? If it's a
point on it, then here is a VB6 sample that calculates a circle's center and
radius based on 3 points. To try it, just paste the following code in the
general section of Form1, click 3 times anywhere in the form to draw a
circle:
Option Explicit
' 3 Points on a circle
Dim x1 As Single
Dim x2 As Single
Dim x3 As Single
Dim y1 As Single
Dim y2 As Single
Dim y3 As Single
' Circle center
Dim h As Single
Dim k As Single
' Circle radius
Dim r As Single
' Calculates a circle's center and raduis given 3 points
Private Sub CalcCircleCenterAndRadius(ByVal x1 As Single, _
ByVal y1 As Single, ByVal x2 As Single, ByVal y2 As Single, _
ByVal x3 As Single, ByVal y3 As Single)
h = y1 * (x2 ^ 2 + y2 ^ 2 - x3 ^ 2 - y3 ^ 2) + y2 * ( _
x3 ^ 2 + y3 ^ 2 - x1 ^ 2 - y1 ^ 2) + y3 * ( _
x1 ^ 2 + y1 ^ 2 - x2 ^ 2 - y2 ^ 2)
h = h / (2 * (y1 * (x2 - x3) + y2 * (x3 - x1) + y3 * (x1 - x2)))
k = x1 * (x3 ^ 2 + y3 ^ 2 - x2 ^ 2 - y2 ^ 2) + x2 * ( _
x1 ^ 2 + y1 ^ 2 - x3 ^ 2 - y3 ^ 2) + x3 * ( _
x2 ^ 2 + y2 ^ 2 - x1 ^ 2 - y1 ^ 2)
k = k / (2 * (y1 * (x2 - x3) + y2 * (x3 - x1) + y3 * (x1 - x2)))
r = Sqr((x1 - h) ^ 2 + (y1 - k) ^ 2)
End Sub
' Draw an X shape to mark a point
Private Sub Cross(ByVal x As Integer, ByVal y As Integer)
Dim i As Integer
For i = -5 To 5
PSet (x + i, y + i), RGB(255, 0, 0)
PSet (x + i, y - i), RGB(255, 0, 0)
Next
End Sub
Private Sub Form_MouseDown(Button As Integer, Shift As Integer, _
x As Single, y As Single)
Static iPointsCount As Integer
If (Button And vbRightButton) Then
' Start over
iPointsCount = 0
Cls
Refresh
Exit Sub
End If
iPointsCount = iPointsCount + 1
If iPointsCount > 3 Then
iPointsCount = 1
End If
Cross x, y
Select Case iPointsCount
Case 1: x1 = x: y1 = y
Case 2: x2 = x: y2 = y
Case 3: x3 = x: y3 = y
CalcCircleCenterAndRadius x1, y1, x2, y2, x3, y3
Circle (h, k), r
End Select
End Sub
Private Sub Form_Paint()
CurrentX = 0
CurrentY = 0
Print "Left click 3 times to define a circle"
Print "Right click to start over"
End Sub
The Circle method goes anti-clockwise as you
discovered. But, in this thread we're working in
the Forms coordinate system, which point the
Y-axis downward. And we're using the Cos and
Sin functions to calculate the angles, the same we
did in the Bezier problem. Remember, in the Bezier
thread you did; ThePoints(n).Y = CY - ..............
-That is, you used the minus sign to place the Bezier
in the quadrant above the positive X-axis. If you
didn't, the Bezier would had layed below the
positive X-axis, which is 1'st quadrant in the
Forms coordinate system. If you run Norms program
with the alterations of mine given below you'll see
that, the circle moves clockwise around. Notice,
the angle increment is positive, and we do not
use the Circle method !.
I think it's valuable you brought that question
in here, to mark the difference working with the
circle. -I missed it in my previous answer !.
/senn
Option Explicit
Private PI As Single
Private CX As Single, CY As Single
Private Radius As Single
Private Angle As Single
Private Function GetX(ByVal Ang As Single, ByVal Rad As Single) As Single
GetX = Rad * Cos(Radians(Ang))
End Function
Private Function GetY(ByVal Ang As Single, ByVal Rad As Single) As Single
GetY = Rad * Sin(Radians(Ang))
End Function
Private Function Radians(ByVal Deg As Single) As Single
Radians = (Deg * PI) / 180
End Function
Private Sub Form_Load()
PI = 4 * Atn(1)
AutoRedraw = True
ScaleMode = vbPixels
CX = ScaleWidth \ 2
CY = ScaleHeight \ 2
Radius = CX * 0.5
Angle = 180
Command1.Move CX + GetX(Angle, Radius), CY + GetY(Angle, Radius)
Circle (CX, CY), Radius
Timer1.Interval = 1
End Sub
Private Sub Timer1_Timer()
Command1.Move CX + GetX(Angle, Radius), CY + GetY(Angle, Radius)
Angle = Angle + 0.4 'Positive increment
End Sub