convex hull example script
The following script can be used for a simple convex hull with only one ring. With iterations the number of points can be simplified.
container Simplified := Simplify(iter_domain, 50); // domain and number of iterations
template Simplify
{
// begin case parameters
unit<uint32> iter_domain;
parameter<uint32> nrIterations;
// end case parameters
unit<uint32> iter := range(uint32, 0, nrIterations)
{
attribute<string> name := 'I' + string(id(.));
attribute<string> PrevName := MakeDefined(name[sub_or_null(id(.), 1)], 'StartingState');
}
container StartingState
{
unit<uint32> NextValue := sequence2points(iter_domain/geometry_rd);
}
container Iters := for_each_ne(iter/name, 'IterT('+iter/PrevName+', iter_domain)');
container LastIter := =last('Iters/'+iter/name);
template IterT
{
// begin case parameters
container PrevIterator;
unit<uint32> domain;
// end case parameters
unit<uint32> PrevValue := PrevIterator/NextValue;
container ConvexHullT := MakeConvexHullT(domain, PrevValue);
unit<uint32> NextValue := ConvexHullT/sequence/Convex_hull_points;
}
container MakeFinal
{
unit <uint32> domain_with_endpoints := union_unit(LastIter/NextValue, iter_domain)
{
attribute<geometries/rdc> point :=
union_data(., LastIter/NextValue/point, first(LastIter/NextValue/point, LastIter/NextValue/sequence_rel));
attribute<uint32> sequence_rel := union_data(., LastIter/NextValue/sequence_rel, id(iter_domain));
}
attribute<geometries/rdc> convex_hull (iter_domain, poly) :=
points2polygon(domain_with_endpoints/point, domain_with_endpoints/sequence_rel);
}
template MakeConvexHullT
{
// begin case parameters
unit<uint32> domain;
unit<uint32> seq;
// end case parameters
unit<uint32> sequence := seq
{
attribute<geometries/rdc> point := seq/point;
attribute<uint32> sequence_rel := seq/sequence_rel;
attribute<uint32> min_index (domain) := min_index(id(.), sequence_rel);
attribute<uint32> max_index (domain) := max_index(id(.), sequence_rel);
attribute<bool> IsFirst := id(.) == min_index[sequence_rel];
attribute<bool> IsLast := id(.) == max_index[sequence_rel];
attribute<uint32> prev_id := IsFirst ? rjoin(sequence_rel, id(domain), max_index) : sub_or_null(id(.), 1);
attribute<uint32> next_id := IsLast ? rjoin(sequence_rel, id(domain), min_index) : id(.)+1;
attribute<geometries/rdc> A := point[prev_id];
attribute<geometries/rdc> B := point;
attribute<geometries/rdc> C := point[next_id];
attribute<geometries/rdc> p := B - A;
attribute<geometries/rdc> q := C - B;
attribute<float32> Px := pointcol(p);
attribute<float32> Py := pointrow(p);
attribute<float32> Qx := pointcol(q);
attribute<float32> Qy := pointrow(q);
attribute<float32> det := Px*Qy - Py*Qx;
unit<uint32> Convex_hull_points :=
select_with_org_rel(det <= 0f && (point != rjoin(prev_id, id(.), point)))
{
attribute<geometries/rdc> point := ../point[org_rel];
attribute<uint32> sequence_rel := ../sequence_rel[org_rel];
}
}
}
}