summaryrefslogtreecommitdiff
path: root/path
diff options
context:
space:
mode:
Diffstat (limited to 'path')
-rwxr-xr-xpath/fixed.ml102
-rwxr-xr-xpath/fixed.mli6
2 files changed, 83 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}
diff --git a/path/fixed.mli b/path/fixed.mli
index c6af84d..32f6012 100755
--- a/path/fixed.mli
+++ b/path/fixed.mli
@@ -40,9 +40,15 @@ module Make(Point:P) : sig
val distance
: Gg.v2 -> t -> (Gg.v2 * float * Point.t * Point.t) option
+ val iter
+ : t -> f:(Point.t -> unit) -> unit
+
val map_point
: t -> (Point.t -> Point.t) -> t
+ val remove_point
+ : t -> Point.t -> t
+
type bezier =
{ p0:Point.t (* The starting point *)
; p1:Point.t (* The end point *)