diff options
Diffstat (limited to 'path')
-rwxr-xr-x | path/fixed.ml | 27 | ||||
-rwxr-xr-x | path/fixed.mli | 9 | ||||
-rwxr-xr-x | path/point.ml | 1 |
3 files changed, 29 insertions, 8 deletions
diff --git a/path/fixed.ml b/path/fixed.ml index 2d42566..176d818 100755 --- a/path/fixed.ml +++ b/path/fixed.ml @@ -76,6 +76,9 @@ module Make(Point:P) = struct : int * path list -> path array = fun (n, t) -> + (* The array is initialized with a magic number, and just after + filled with the values from the list in reverse. All the elements are set. + *) let res = Obj.magic (Array.make n 0) in List.iteri t ~f:(fun i elem -> Array.set res (n - i - 1) elem ); @@ -125,10 +128,18 @@ module Make(Point:P) = struct ) in Repr.stop repr + + type approx = + { distance : float + ; closest_point : Gg.v2 + ; ratio : float + ; p0 : Point.t + ; p1 : Point.t } + (** Return the distance between a given point and the curve. May return None if the point is out of the curve *) let distance - : Gg.v2 -> t -> (Gg.v2 * float * Point.t * Point.t) option + : Gg.v2 -> t -> approx option = fun point beziers -> Array.fold_left beziers.path @@ -151,12 +162,16 @@ module Make(Point:P) = struct ; 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 + let ratio, 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)) + | Some {distance; _} when distance < distance' -> res + | _ -> Some + { closest_point = point' + ; distance = distance' + ; p0 = bezier.p0 + ; p1 = bezier.p1 + ; ratio } ) let map_point diff --git a/path/fixed.mli b/path/fixed.mli index 1f12006..06b3539 100755 --- a/path/fixed.mli +++ b/path/fixed.mli @@ -32,10 +32,17 @@ module Make(Point:P) : sig val repr : t -> (module Repr.M with type t = Point.t and type repr = 's) -> 's -> 's + type approx = + { distance : float + ; closest_point : Gg.v2 + ; ratio : float + ; p0 : Point.t + ; p1 : Point.t } + (** Return the distance between a given point and the curve. May return None if the point is out of the curve *) val distance - : Gg.v2 -> t -> (Gg.v2 * float * Point.t * Point.t) option + : Gg.v2 -> t -> approx option val iter : t -> f:(Point.t -> unit) -> unit diff --git a/path/point.ml b/path/point.ml index 4c34899..ec6f8ad 100755 --- a/path/point.ml +++ b/path/point.ml @@ -58,7 +58,6 @@ let get_coord' let mix : float -> Gg.v2 -> t -> t -> t = fun f point p0 p1 -> - incr internal_id; let angle0 = p0.angle and angle1 = p1.angle and width0 = get_width p0 |