Bézier curves/Intersections: Difference between revisions
→{{header|ATS}}: Changes to make the program more robust against duplicates. Similar to what was done to the D and Modula-2. Also now the parameters are sorted.
(→{{header|Modula-2}}: Removed the stop after four intersections (it seems inadvisable, given there might be "near-intersections").) |
(→{{header|ATS}}: Changes to make the program more robust against duplicates. Similar to what was done to the D and Modula-2. Also now the parameters are sorted.) |
||
Line 228:
error_squared / tol <= length_squared * tol
end
(* One might be curious why "t@ype" instead of "type". The answer is:
the notation "type" is restricted to types that take up the same
space as a C void-pointer, which includes ATS pointers, "boxed"
types, etc. A "t@ype" can take up any amount of space, and so
includes any type there is (except for linear types, which is a
whole other subject). For instance, "int", "double", unboxed
records, unboxed tuples, and so on. *)
fun {a, b : t@ype} (* A polymorphic template function. *)
list_any (pred : (a, b) -<cloref1> bool,
lst : List0 b)
: bool =
(* Does pred(obj, item) return true for any list item? Here the
<cloref1> notation means that pred is a CLOSURE of the ordinary
garbage-collected kind, such as functions tend implicitly to be
in Lisps, MLs, Haskell, etc. *)
case+ lst of
| NIL => false
| hd :: tl =>
if pred (obj, hd) then
true
else
list_any (pred, obj, tl)
fun
find_intersection_parameters
(px : @(double, double, double),
py : @(double, double, double),
qx : @(double, double, double),
qy : @(double, double, double),
tol : double
: List0 double =
let
val px = bernstein2spower_degree2 px
Line 242 ⟶ 267:
fun
within_spacing (t_candidate : double,
loop {n : nat | n <= 4}▼
t_in_list : double)
:<cloref1> bool =
abs (t_candidate - t_in_list) < spacing
fun
(params : list (double, n),
n : int n,
workload : List0 (@(double, double)))
:
| NIL => params
if flat_enough
▲ in
in
▲ solve_linear_quadratic (@(portionx0, portionx2),
if 0.0 <= root0 && root0 <= 1.0
~list_any (within_spacing,
if 0.0 <=
else if 0.0 <=
in
loop (NIL, 0, @(0.0, 1.0) :: NIL)
Line 300 ⟶ 331:
val qy = @(1.0, 2.0, 3.0)
val tol = 0.001 (* "Flatness ratio" *)
val
val t_list = find_intersection_parameters (px, py, qx, qy,
tol, spacing)
(* For no particular reason, sort the intersections so they go
from top to bottom. *)
val t_list = list_vt2t (list_vt_reverse (list_mergesort t_list))
val () = println! ("From top to bottom:")
fun
Line 320 ⟶ 358:
{{out}}
<pre>From top to bottom:
<pre>(0.881023, 1.118975)▼
(0.654983, 2.854983)
(-0.681024, 2.681025)
(-0.854982, 1.345016)
=={{header|D}}==
|