convex hull example script - ObjectVision/GeoDMS GitHub Wiki
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[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 LastIterI := =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(iter_domain, LastIter/NextValue)
{
attribute<geometries/rdc> point :=
union_data(., LastIter/NextValue/point, first(LastIter/NextValue/point, LastIter/NextValue/SequenceNr));
attribute<uint32> SequenceNr := union_data(., LastIter/NextValue/SequenceNr, ID(Iteratie_domain));
}
attribute<geometries/rdc> convex_hull (iter_domain, poly) :=
points2sequence(domain_with_endpoints /point, domain_with_endpoints /SequenceNr);
}
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> SequenceNr := seq/SequenceNr;
attribute<uint32> min_index (domain) := min_index(id(.), SequenceNr);
attribute<uint32> max_index (domain) := max_index(id(.), SequenceNr);
attribute<bool> IsFirst := id(.) == min_index[SequenceNr];
attribute<bool> IsLast := id(.) == max_index[SequenceNr];
attribute<uint32> prev_id := IsFirst ? rjoin(SequenceNr, id(domain), max_index) : ID(.)-1;
attribute<uint32> next_id := Islast ? rjoin(SequenceNr, 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> SequenceNr := ../SequenceNr[org_rel];
}
}
}
}