Nothing new so i just got source translated from here.
https://www.geeksforgeeks.org/equation- ... are-given/
Now i was playing with segmented circle and tested workings.
Soon found out the precision is bad when all points are almost inline.
So i used a chat GPT helped me with adding extra checks, not helping..
With the mouse you can move points points 1,2,3 (with buttons 1,2 and 3.)
When all are aligned i can make the program hang/crash.
Any idea why this happens?
How can it hang on calculations? or is it the fb circle function itself?
Any help would be great.
Code: Select all
#Define Pi 3.1415926535897932
type v2dr_double
as double x, y
as double r
end type
function calculate_3p_circle(p1 as v2dr_double, p2 as v2dr_double, p3 as v2dr_double) as v2dr_double
dim as double x12 = p1.x - p2.x
dim as double x13 = p1.x - p3.x
dim as double y12 = p1.y - p2.y
dim as double y13 = p1.y - p3.y
dim as double y31 = p3.y - p1.y
dim as double y21 = p2.y - p1.y
dim as double x31 = p3.x - p1.x
dim as double x21 = p2.x - p1.x
dim as double sx13 = (p1.x * p1.x) - (p3.x * p3.x)
dim as double sy13 = (p1.y * p1.y) - (p3.y * p3.y)
dim as double sx21 = (p2.x * p2.x) - (p1.x * p1.x)
dim as double sy21 = (p2.y * p2.y) - (p1.y * p1.y)
dim as double denominator_f = 2 * ((y31) * (x12) - (y21) * (x13))
dim as double denominator_g = 2 * ((x31) * (y12) - (x21) * (y13))
' Check for collinear points (division by zero)
if abs(denominator_f) < 1e-10 or abs(denominator_g) < 1e-10 then ' Using a small tolerance
' Handle collinear case (e.g., return an error value)
return type(0.0, 0.0, -1.0) ' Indicate an error with a negative radius
end if
dim as double f = ((sx13) * (x12) _
+ (sy13) * (x12) _
+ (sx21) * (x13) _
+ (sy21) * (x13)) _
/ denominator_f
dim as double g = ((sx13) * (y12) _
+ (sy13) * (y12) _
+ (sx21) * (y13) _
+ (sy21) * (y13)) _
/ denominator_g
dim as double c = -(p1.x * p1.x) - (p1.y * p1.y) - 2 * g * p1.x - 2 * f * p1.y
dim as double r = sqr(g * g + f * f - c)
' Handle invalid radius (e.g., return an error value)
if r < 0 then return type(0.0, 0.0, -1.0)
return type<v2dr_double>(-g, -f, r)
end function
screenres 800, 600, 32
dim as long x, y, b, res
dim as v2dr_double p1 = type(2, 1.5)
dim as v2dr_double p2 = type(2.5, 4)
dim as v2dr_double p3 = type(5, 3)
window screen(0, 0)-(8, 6) ' Use this resolution
sleep 500
do
res = GetMouse (x, y, , b)
if res = 0 then
if b and 1 then p1.x = PMap(x, 2): p1.y = PMap(y, 3)
if b and 2 then p3.x = PMap(x, 2): p3.y = PMap(y, 3)
if b and 4 then p2.x = PMap(x, 2): p2.y = PMap(y, 3)
end if
var p4 = calculate_3p_circle(p1, p2, p3)
screenlock()
cls
locate 1,1
print p4.x, p4.y, p4.r
circle (p1.x, p1.y), .2, &hFF0000
circle (p2.x, p2.y), .2, &h00FF00
circle (p3.x, p3.y), .2, &h0000FF
if p4.r > 0 then
dim as double x41 = p4.x-p1.x
dim as double y41 = p4.y-p1.y
dim as double x43 = p4.x-p3.x
dim as double y43 = p4.y-p3.y
print
var _start = (atan2(x41, y41)+Pi*2.5): if _start > Pi*2 then _start -= Pi*2
var _end = (atan2(x43, y43)+Pi*2.5): if _end > Pi*2 then _end -= Pi*2
print _start, _end
line (p1.x, p1.y)-(p3.x, p3.y), &h888888, , &b0000000011110000
circle (p4.x, p4.y), p4.r, &hFFFF00, _start, _end
end if
screenunlock()
sleep 10
loop until multikey(&h01) 'escape
sleep
end