// Ellipse.A is always equal or greater than Ellipse.B.
// Ellipse.Alpha is between 0 and Pi.
let ellipse (p1x: float) (p1y: float) (m1: float) (p2x: float) (p2y: float) (m2: float) (p3x: float) (p3y: float) : Types.Ellipse option =
- let accuracy_extremum_search_1 = 4
- let accuracy_extremum_search_2 = 3
+ let accuracy_extremum_search_1 = 7 // 3
+ let accuracy_extremum_search_2 = 7 // 4
// p3 as the referencial.
let p1x = p1x - p3x
let b1 = -m1 * p1x + p1y
let b2 = -m2 * p2x + p2y
- let px = -((b1 - b2)/(m1 - m2))
- let py = -((m2 * b1 - m1 * b2)/(m1 - m2))
+ let px = -((b1 - b2) / (m1 - m2))
+ let py = -((m2 * b1 - m1 * b2) / (m1 - m2))
let rot1 = vectorRotation p1x p1y v1x v1y px py
let rot2 = vectorRotation p2x p2y v2x v2y px py
- if rot1 = rot2 || rot1 * atan2 (p1y - py) (p1x - px) + rot2 * atan2 (p2y - py) (p2x - px) <= 0.0
+ if rot1 = rot2
then
None
else
+ let alpha1 = atan2 (p1y - py) (p1x - px)
+ let alpha2 = atan2 (p2y - py) (p2x - px)
+
+ let alpha1' = if alpha1 < 0.0 then 2.0 * Math.PI + alpha1 else alpha1
+ let alpha2' = if alpha2 < 0.0 then 2.0 * Math.PI + alpha2 else alpha2
+
+ let diff = rot1 * alpha1' + rot2 * alpha2'
+
+ if diff > Math.PI || (diff < 0.0 && diff > -Math.PI)
+ then
+ None
+ else
Some (m1, m2)
+
let find (edges: Matrix<byte>)
(xDir: Image<Gray, float>)
(yDir: Image<Gray, float>)
match ellipse p1xf p1yf m1 p2xf p2yf m2 p3xf p3yf with
| Some e when e.Cx > 0.0 && e.Cx < (float w) - 1.0 && e.Cy > 0.0 && e.Cy < (float h) - 1.0 &&
e.A >= r1 - radiusTolerance && e.A <= r2 + radiusTolerance && e.B >= r1 - radiusTolerance && e.B <= r2 + radiusTolerance ->
+
+ let prout = areVectorsValid p1xf p1yf p2xf p2yf -xDirData.[p1y, p1x, 0] -yDirData.[p1y, p1x, 0] -xDirData.[p2y, p2x, 0] -yDirData.[p2y, p2x, 0]
ellipses.Add e
| _ -> ()
| _ -> ()