aboutsummaryrefslogtreecommitdiff
path: root/path/builder.ml
diff options
context:
space:
mode:
authorSébastien Dailly <sebastien@chimrod.com>2021-01-01 11:08:38 +0100
committerSébastien Dailly <sebastien@chimrod.com>2021-01-01 11:08:38 +0100
commitaf88c8895bba85fe5340b34aafb3dce7650bd01f (patch)
treeee0c9d1bd463242c681c6202a9a57c8110d58f59 /path/builder.ml
parente25b7797708c19cbaef68c14ebef8738de44c2d9 (diff)
Use first type module instead of functors
Diffstat (limited to 'path/builder.ml')
-rwxr-xr-xpath/builder.ml203
1 files changed, 98 insertions, 105 deletions
diff --git a/path/builder.ml b/path/builder.ml
index bcad493..cb87fc5 100755
--- a/path/builder.ml
+++ b/path/builder.ml
@@ -15,20 +15,20 @@ end
module type REPR = sig
type t
- type 'a repr
+ type repr
(* Start a new path. *)
val start
- : t -> 'a repr -> 'a repr
+ : t -> repr -> repr
val line_to
- : t -> t -> 'a repr -> 'a repr
+ : t -> t -> repr -> repr
val quadratic_to
- : t -> Gg.v2 -> Gg.v2 -> t -> 'a repr -> 'a repr
+ : t -> Gg.v2 -> Gg.v2 -> t -> repr -> repr
val stop
- : 'a repr -> 'a repr
+ : repr -> repr
end
module Make(Point:P) = struct
@@ -122,105 +122,98 @@ module Make(Point:P) = struct
| [] -> None
| hd::_ -> Some hd
- (** Complete path **)
-
- module Draw(Repr:REPR with type t = Point.t) = struct
-
- (** Drawing path **)
-
- let draw
- : t -> 'a Repr.repr -> 'a Repr.repr
- = fun (points, beziers) path ->
-
- (* Represent the last points *)
- let path = match points with
- | [] ->
- ( path )
- | p1::[] ->
- ( Repr.start p1 path )
- | p1::p2::[] ->
- let path =
- Repr.start p1 path
- |> Repr.line_to p1 p2 in
- ( path )
- | p0::p1::p2::[] ->
- let path = Repr.start p0 path in
-
- let b = Shapes.Bezier.quadratic_to_cubic
- @@ Shapes.Bezier.three_points_quadratic
- (Point.get_coord p0)
- (Point.get_coord p1)
- (Point.get_coord p2)
- in
-
- let p0' = Point.copy p0 b.Shapes.Bezier.p0
- and p2' = Point.copy p1 b.Shapes.Bezier.p1 in
-
- ( Repr.quadratic_to
- p0'
- b.Shapes.Bezier.ctrl0
- b.Shapes.Bezier.ctrl1
- p2'
- path )
- | (p0::_ as points) ->
-
- let (let*) v f =
- match v with
- | Ok beziers -> f beziers
- | _ -> path in
-
- let points' = List.map ~f:Point.get_coord points in
- let connexion = match beziers with
- | [] -> None
- | hd ::_ -> Some (Point.get_coord hd.p1) in
-
- let* beziers = Shapes.Bspline.to_bezier ?connexion1:connexion points' in
-
- (* Stdlib does not provide fold_left_i function and we need to map
- each bezier point with the associated point in the curve.
-
- So I use references here for keeping each result element
-
- *)
- let path = ref path in
- let point = ref p0 in
-
- List.iteri
- points
- ~f:(fun i pt ->
-
- (* The first iteration is ignored, as we need both previous and
- current point for the two point in the curve.
-
- Do not forget that there is always n-1 bezier curve for n
- points *)
- if i > 0 then (
-
- let bezier = Array.get beziers (i - 1) in
-
- path := Repr.quadratic_to
- !point
- bezier.Shapes.Bezier.ctrl0
- bezier.Shapes.Bezier.ctrl1
- pt
- (!path);
- point := pt;
- )
- );
- ( !path )
- in
-
- (* Now represent the already evaluated points. Much easer to do, just
- iterate on them *)
- Repr.stop @@ List.fold_left beziers
- ~init:path
- ~f:(fun path bezier ->
- let p0' = bezier.p0
- and ctrl0 = bezier.ctrl0
- and ctrl1 = bezier.ctrl1
- and p1' = bezier.p1 in
- Repr.quadratic_to p0' ctrl0 ctrl1 p1' path
- )
- end
+ let repr
+ : t -> (module REPR with type t = Point.t and type repr = 's) -> 's -> 's
+ = fun (type s) (points, beziers) (module Repr : REPR with type t = Point.t and type repr = s) path ->
+
+ (* Represent the last points *)
+ let path = match points with
+ | [] ->
+ ( path )
+ | p1::[] ->
+ ( Repr.start p1 path )
+ | p1::p2::[] ->
+ let path =
+ Repr.start p1 path
+ |> Repr.line_to p1 p2 in
+ ( path )
+ | p0::p1::p2::[] ->
+ let path = Repr.start p0 path in
+
+ let b = Shapes.Bezier.quadratic_to_cubic
+ @@ Shapes.Bezier.three_points_quadratic
+ (Point.get_coord p0)
+ (Point.get_coord p1)
+ (Point.get_coord p2)
+ in
+
+ let p0' = Point.copy p0 b.Shapes.Bezier.p0
+ and p2' = Point.copy p1 b.Shapes.Bezier.p1 in
+
+ ( Repr.quadratic_to
+ p0'
+ b.Shapes.Bezier.ctrl0
+ b.Shapes.Bezier.ctrl1
+ p2'
+ path )
+ | (p0::_ as points) ->
+
+ let (let*) v f =
+ match v with
+ | Ok beziers -> f beziers
+ | _ -> path in
+
+ let points' = List.map ~f:Point.get_coord points in
+ let connexion = match beziers with
+ | [] -> None
+ | hd ::_ -> Some (Point.get_coord hd.p1) in
+
+ let* beziers = Shapes.Bspline.to_bezier ?connexion1:connexion points' in
+
+ (* Stdlib does not provide fold_left_i function and we need to map
+ each bezier point with the associated point in the curve.
+
+ So I use references here for keeping each result element
+
+ *)
+ let path = ref path in
+ let point = ref p0 in
+
+ List.iteri
+ points
+ ~f:(fun i pt ->
+
+ (* The first iteration is ignored, as we need both previous and
+ current point for the two point in the curve.
+
+ Do not forget that there is always n-1 bezier curve for n
+ points *)
+ if i > 0 then (
+
+ let bezier = Array.get beziers (i - 1) in
+
+ path := Repr.quadratic_to
+ !point
+ bezier.Shapes.Bezier.ctrl0
+ bezier.Shapes.Bezier.ctrl1
+ pt
+ (!path);
+ point := pt;
+ )
+ );
+ ( !path )
+ in
+
+ (* Now represent the already evaluated points. Much easer to do, just
+ iterate on them *)
+ Repr.stop @@ List.fold_left beziers
+ ~init:path
+ ~f:(fun path bezier ->
+ let p0' = bezier.p0
+ and ctrl0 = bezier.ctrl0
+ and ctrl1 = bezier.ctrl1
+ and p1' = bezier.p1 in
+ Repr.quadratic_to p0' ctrl0 ctrl1 p1' path
+ )
end