aboutsummaryrefslogtreecommitdiff
path: root/path/fixed.ml
diff options
context:
space:
mode:
authorSébastien Dailly <sebastien@chimrod.com>2021-01-06 22:09:53 +0100
committerSébastien Dailly <sebastien@chimrod.com>2021-01-06 22:09:53 +0100
commita63662059215a26db627c4b76147a3c9338f5b74 (patch)
treec71b984b2327ebe743809e04b0a29aac0e15cc56 /path/fixed.ml
parent6ae97ecca8b4f38213f0f45aa6eaef944cd6b497 (diff)
Point suppression
Diffstat (limited to 'path/fixed.ml')
-rwxr-xr-xpath/fixed.ml102
1 files changed, 77 insertions, 25 deletions
diff --git a/path/fixed.ml b/path/fixed.ml
index 7ee0705..95a42d5 100755
--- a/path/fixed.ml
+++ b/path/fixed.ml
@@ -129,15 +129,6 @@ module Make(Point:P) = struct
) in
Repr.stop repr
- let box
- : bezier -> Gg.box2
- = fun bezier ->
- Gg.Box2.of_pts
- (Point.get_coord bezier.p0)
- (Point.get_coord bezier.p1)
- |> (fun b -> Gg.Box2.add_pt b bezier.ctrl0)
- |> (fun b -> Gg.Box2.add_pt b bezier.ctrl1)
-
(** Return the distance between a given point and the curve. May return
None if the point is out of the curve *)
let distance
@@ -157,23 +148,20 @@ module Make(Point:P) = struct
res
end
| Curve bezier ->
- begin match Gg.Box2.mem point (box bezier) with
- | false -> res
- | true ->
- let bezier' = Shapes.Bezier.(
-
- { p0 = Point.get_coord bezier.p0
- ; p1 = Point.get_coord bezier.p1
- ; ctrl0 = bezier.ctrl0
- ; ctrl1 = bezier.ctrl1 }
- ) in
- let _, point' = Shapes.Bezier.get_closest_point point bezier' in
- let distance = Gg.V2.( norm (point - point') ) in
- match res with
- | None -> Some (point', distance, bezier.p0, bezier.p1)
- | Some (_, d, _, _) -> if d < distance then res else (Some (point', distance, bezier.p0, bezier.p1))
- end
+ let bezier' = Shapes.Bezier.(
+
+ { p0 = Point.get_coord bezier.p0
+ ; p1 = Point.get_coord bezier.p1
+ ; ctrl0 = bezier.ctrl0
+ ; ctrl1 = bezier.ctrl1 }
+ ) in
+ let _, point' = Shapes.Bezier.get_closest_point point bezier' in
+ let distance = Gg.V2.( norm (point - point') ) in
+ match res with
+ | None -> Some (point', distance, bezier.p0, bezier.p1)
+ | Some (_, d, _, _) when d < distance -> res
+ | _ -> (Some (point', distance, bezier.p0, bezier.p1))
)
let map_point
@@ -187,6 +175,70 @@ module Make(Point:P) = struct
) in
{id; path}
+ let iter
+ : t -> f:(Point.t -> unit) -> unit
+ = fun {path; _} ~f ->
+ Array.iter path
+ ~f:(function
+ | Empty -> ()
+ | Line (p1, p2) -> f p1; f p2
+ | Curve bezier -> f bezier.p0 ; f bezier.p1
+ )
+
+
+ let remove_point
+ : t -> Point.t -> t
+ = fun {id; path} point ->
+
+ (* First search the element to remove *)
+ let idx = ref None
+ and counter = ref 0 in
+
+ let _ = Array.exists
+ path
+ ~f:(fun element ->
+
+ let res = match element with
+ | Empty -> false
+ | Line (p0, p1)
+ | Curve {p0;p1;_} ->
+ if p0 = point then (
+ idx := Some (!counter) ;
+ true
+ ) else if p1 = point then (
+ idx := Some (!counter +1) ;
+ true
+ ) else
+ false
+ in
+ incr counter;
+ res) in
+
+ match !idx with
+ | None -> {id; path}
+ | Some 0 ->
+ (* Remove the first point *)
+ let path' = Array.init
+ ((Array.length path) -1)
+ ~f:( fun i -> Array.get path (i + 1)) in
+ {id; path=path'}
+ | Some n when n = (Array.length path) ->
+ (* Remove the last point *)
+ let path' = Array.init
+ ((Array.length path) -1)
+ ~f:( fun i -> Array.get path i) in
+ {id; path=path'}
+ | Some n ->
+ let path' = Array.init
+ ((Array.length path) -1)
+ ~f:(fun i ->
+ if i < (n -1) then
+ Array.get path (i)
+ else
+ Array.get path (i +1)
+ ) in
+ {id; path=path'}
+
let update
: t -> path array -> t
= fun {id; _} path -> {id; path}