// Return 'true' if the point 'p' is owned by e.
// The lines represents all intersections with other ellipses.
- let pixelOwnedByE (p: PointD) (e: Ellipse) (others: (Ellipse * Line) list) =
+ let pixelOwnedByE (p: PointF) (e: Ellipse) (others: (Ellipse * Line) list) =
e.Contains p.X p.Y &&
seq {
- let c = PointD(e.Cx, e.Cy)
+ let c = PointF(e.Cx, e.Cy)
+
for e', d1 in others do
- let d2 = Utils.lineFromTwoPoints c p
- let c' = PointD(e'.Cx, e'.Cy)
+ let d2 = lineFromTwoPoints c p
+ let c' = PointF(e'.Cx, e'.Cy)
let v = pointFromTwoLines d1 (lineFromTwoPoints c c')
let case1 = sign (v.X - c.X) <> sign (v.X - c'.X) || Utils.squaredDistanceTwoPoints v c > Utils.squaredDistanceTwoPoints v c'
if d2.Valid
then
let p' = Utils.pointFromTwoLines d1 d2
+ let delta, delta' =
+ let d = c.X - p.X
+ // To avoid rounding.
+ if abs d < 0.001f then c.Y - p.Y, c.Y - p'.Y else d, c.X - p'.X
+
// Yield 'false' when the point is owned by another ellipse.
if case1
then
- yield sign (c.X - p.X) <> sign (c.X - p'.X) || Utils.squaredDistanceTwoPoints c p' > Utils.squaredDistanceTwoPoints c p
+ yield sign delta <> sign delta' || Utils.squaredDistanceTwoPoints c p' > Utils.squaredDistanceTwoPoints c p
else
- yield sign (c.X - p.X) = sign (c.X - p'.X) && Utils.squaredDistanceTwoPoints c p' < Utils.squaredDistanceTwoPoints c p
+ yield sign delta = sign delta' && Utils.squaredDistanceTwoPoints c p' < Utils.squaredDistanceTwoPoints c p
else
yield case1
} |> Seq.forall id
// 1) Associate touching ellipses with each ellipses and remove ellipse with more than two intersections.
let tree = KdTree.Tree.BuildTree ellipses
- let neighbors (e: EllipseFlaggedKd) : (EllipseFlaggedKd * PointD * PointD) list =
+ let neighbors (e: EllipseFlaggedKd) : (EllipseFlaggedKd * PointF * PointF) list =
if not e.Removed
then
tree.Search (searchRegion e)
otherE.Removed <- true
None
| Some (area, px, py) when area > 0.f && px.Length = 2 ->
- Some (otherE, PointD(px.[0], py.[0]), PointD(px.[1], py.[1]))
+ Some (otherE, PointF(px.[0], py.[0]), PointF(px.[1], py.[1]))
| _ ->
None
else
let mutable area = 0
for y in (if minY < 0 then 0 else minY) .. (if maxY >= h then h - 1 else maxY) do
for x in (if minX < 0 then 0 else minX) .. (if maxX >= w then w - 1 else maxX) do
- let p = PointD(float32 x, float32 y)
+ let p = PointF(float32 x, float32 y)
if pixelOwnedByE p e (neighbors |> List.choose (fun (otherE, p1, p2) -> if otherE.Removed then None else Some (otherE :> Ellipse, Utils.lineFromTwoPoints p1 p2)))
then
area <- area + 1
let elements = new Matrix<byte>(maxY - minY + 1, maxX - minX + 1)
for y in minY .. maxY do
for x in minX .. maxX do
- let p = PointD(float32 x, float32 y)
+ let p = PointF(float32 x, float32 y)
if pixelOwnedByE p e (neighbors |> List.choose (fun (otherE, p1, p2) -> if otherE.Removed then None else Some (otherE :> Ellipse, Utils.lineFromTwoPoints p1 p2)))
then
elements.[y-minY, x-minX] <- 1uy