I want to make a drawing application which needs a few drawing functions I cant handle myself as im not very mathematicly inclined so any help will be appreciated.
The first on the list of functions is to create an arc from a start point, end point and radius.
The method signature is as followes.
Code:
Function CreateArc(byval StartPoint as PointF, EndPoint as PointF, Raduis as single) As PointF()
'Code to create an array of points...
return ptPoints()
End Function
Im also hoping that the function could also draw a full circle by supplying the same start and end points.
Thanks in advance
Re: Draw Arc from Start point, End point and Radius
To be clear, you have two points on a circle (Start and End) and you want to draw the part of the circle that connects the two points, given that the circle is of the given Radius? If this is the case, there are two valid arcs to draw in each case, as the attached picture illustrates. Both the golden and blue arcs connect the Start (green) and End (red) points along a circle.
If this is right... I'm not sure how you want to pick which curve to draw.
The time you enjoy wasting is not wasted time. Bertrand Russell
Re: Draw Arc from Start point, End point and Radius
Yes, I have thaught about this and was thinking(and may verywell be wrong)
that I can control the colckwise vs anticlockwise parameter of the arc by switching the start and end points and that will be controled with a UI element or logic (such as the way the user clicks the drawing to create the arc). but I gues that depends on the algorythm too, it is no problem to include an extra parameter into the algorithm as my application will need to know this before the arc is created, or at least when the user makes the end point selection.
Re: Draw Arc from Start point, End point and Radius
Sounds like the way to do it. You could even let the user press, say, Shift, to switch the concavity of the arc. Just swap the start and end points internally and you should have it.
I'll derive the position of the center as well as the angle from the positive x-axis (imagining a coordinate system with origin at the center of the circle) to the Start and End points. From there you should be able to find code to do what you want. I'm almost certain I read a thread on this a few years ago on the regular VB6 forum, so I figure it won't be too tough to find given the center and arc start/end parameters.
WLOG stick the center of the line connecting the two points at the origin. Then we have two points (x1, y1) and (-x1, -y1) on some circle. The line connecting the origin and the center of the circle they're on is normal to the line connecting the two points pictorially. The components of that normal vector are simply (y1, -x1) [(-y1, x1) works as well, and will give you the other curvature if you use it]. Travel along that normal until you're the proper radius from the two points. Thus you have a potential center point c*(y1, -x1) for some scalar travel distance c. The distance from this point to (x1, y1) must be R, so we can apply the distance formula and state this algebraically as
Arbitrarily take the positive square root; you could take negative root to get the other curvature as well.
The translated center is then at (c y1, -c x1) [or (-c y1, c x1) for the other curvature]. Given two points--Start = (x0a, y0a), End = (x0b, y0b)--not at the origin, we know the midpoint of the line connecting them is at ([x0a+x0b]/2, [y0a+y0b]/2), which is how far we must have translated them in the first place. So, untranslate the center to (c y1 + [x0a+x0b]/2, -c x1 + [y0a+y0b]/2). Get y1 and x1 in terms of the x0's and y0's by untranslating that point as well. We then have [translated and then untranslated first point] (x1 + [x0a+x0b]/2, y1 + [y0a+y0b]/2) = (x0a, y0a) [never translated], so that (x1, y1) = ([x0a-x0b]/2, [y0a-y0b]/2). This doesn't really simplify, so I won't substitute these back in.
To summarize, the center (x0, y0) of the circle connecting these two is at
(x0, y0) = (c y1 + [x0a+x0b]/2, -c x1 + [y0a+y0b]/2) where c = R/Sqrt(2 + x1^2 + y1^2) with (x1, y1) = ([x0a-x0b]/2, [y0a-y0b]/2) where (x0a, y0a) and (x0b, y0b) are the start and end point arguments, respectively. A computer can easily handle all the back substitutions, which will indeed resolve. I just didn't feel like writing something absolutely horrendous.... It'd be like a few hundred characters long.
Now, for the arc positions. This is a relatively simple matter of applying inverse cosines (thankfully ). Translate the original points again, this time using the center of the circle as the origin. The translated points (x2a, y2a), (x2b, y2b) are then given by (x2a, y2a) = (x0a - x0, y0a - y0) and (x2b, y2b) = (x0b - x0, y0b - y0). Now treat each of these points as a vector to find the angle between them and the positive x-axis. Normalize each translated point to simplify the calculation later. Call the translated, normalized starting and ending points (x3a, y3a) and (x3b, y3b) where (x3a, y3a) = (x2a, y2a) / Sqrt(x2a^2 + y2a^2) and (x3b, y3b) = (x2b, y2b) / Sqrt(x2b^2 + y2b^2).
Using unit vector dot products, for two unit vectors u and v we know that u dot v = cos(alpha), or alpha = arccos(u dot v). Thus, alphaa and alphab, the angles [presumably in radians; by default VB will give it in radians] from the positive x-axis going through the center of the circle to the start and end points is simply
Note, however, that if the point is below the x-axis, this will yield the clockwise instead of counterclockwise arc length. Adjust for this if y3a or y3b is negative:
If anyone's interested in checking my algebra, particularly for determining the constant c, I'd appreciate it. I have been double-checking as I've gone but you never know.
Last edited by jemidiah; Jan 18th, 2009 at 07:06 AM.
The time you enjoy wasting is not wasted time. Bertrand Russell