aboutsummaryrefslogtreecommitdiff
path: root/script.it/state/selection.ml
blob: 3590a98037670d17b0d0b9c0245d05f2cc6fcb3b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
open StdLabels
module Path = Script_path

type 'a selection =
  | Path of 'a
  | Point of ('a * Path.Point.t)

type t = int selection

let find_selection :
    int selection -> Outline.t list -> Outline.t selection option =
 fun selection paths ->
  match selection with
  | Path id -> Option.map (fun p -> Path p) (Outline.find paths id)
  | Point (id, pt) ->
      Option.map (fun p -> Point (p, pt)) (Outline.find paths id)


let threshold = 20.

let get_from_paths :
       float * float
    -> Outline.t list
    -> float * (Gg.v2 * Outline.t * Path.Point.t * Path.Point.t) option =
 fun position outlines ->
  let point = Gg.V2.of_tuple position in
  (* If the user click on a curve, select it *)
  List.fold_left
    outlines
    ~init:(threshold, None)
    ~f:(fun (dist, selection) outline ->
      match Path.Fixed.distance point outline.Outline.path with
      | Some { closest_point; distance; p0; p1; ratio } when distance < dist ->
          (ratio, Some (closest_point, outline, p0, p1))
      | _ -> (dist, selection) )


let select_path : Outline.t -> t = fun outline -> Path outline.Outline.id

let select_point : Outline.t -> Gg.v2 -> t =
 fun outline v2_point ->
  let point' = ref None in
  let dist = ref threshold in

  Path.Fixed.iter outline.Outline.path ~f:(fun p ->
      let open Gg.V2 in
      let new_dist = norm (Path.Point.get_coord p - v2_point) in
      match new_dist < !dist with
      | false -> ()
      | true ->
          dist := new_dist;
          point' := Some p );

  match !point' with
  | Some point -> Point (outline.Outline.id, point)
  | None -> Path outline.Outline.id

(*
      (* If the point does not exists, find the exact point on the curve *)
      let coord = Gg.V2.to_tuple v2_point in
      begin match get_from_paths coord [path] with
        | _, None -> Path (Path.Fixed.id path)
        | f, Some (point, path, p0, p1) ->

          let point' = Path.Point.mix f point p0 p1 in
          Point (Path.Fixed.id path, point')
      end
      *)