Smallest enclosing circle problem: Difference between revisions
m
→{{header|Raku}}: various idiomatifications
SqrtNegInf (talk | contribs) m (→{{header|Raku}}: various idiomatifications) |
|||
Line 937:
=={{header|Raku}}==
{{trans|Go}}
<lang perl6>
method gist { "({$.x~", "~$.y})" }
}
class C { has (P $.c, Numeric $.r); # Circle
method gist { "Center = " ~$.c.gist ~ " and Radius = $.r\n" }
#
method contains(P \p --> Bool) {
method encloses(@ps --> Bool) { [and] @ps.map: {
▲ } # returns whether a circle contains a slice of point
}
sub infix:<−> (P \a, P \b) { a.x - b.x, a.y - b.y } # note: Unicode 'minus'
# returns the square of the distance between two points
sub distSq (P \a, P \b) {
sub getCenter (\bx, \by, \cx, \cy --> P) {
my (\b,\c,\d) =
P.new: x => (cy*b - by*c) / (2 * d), y => (bx*c - cx*b) / (2 * d)
} # returns the center of a circle defined by 3 points
sub circleFrom3 (P \a, P \b, P \c --> C) {
my \k = $ = getCenter |(b
k.x, k.y Z[+=] a.x, a.y;
} # returns a unique circle that intersects 3 points
sub circleFrom2 (P \a, P \b --> C ) {
my \center = P.new: x => ((a.x + b.x) / 2), y => ((a.y + b.y) / 2) ;
} # returns smallest circle that intersects 2 points
sub secTrivial( @rs --> C ) {
given
when * == 0 { return C.new: c =>
when * == 1 { return C.new: c => @rs[0], r => 0 }
when * == 2 { return circleFrom2 |@rs
when * == 3 { #`{ no-op } }
when * > 3 { die "There shouldn't be more than 3 points." }
}
for 0, 1 X 1, 2 -> ( \i, \j ) {
}
} # returns smallest enclosing circle for n ≤ 3
sub
return secTrivial(@rs) if
my \p = @ps.shift;
return $_ if .contains(p) given Welzl-helper
} # helper function for Welzl method
# applies the Welzl algorithm to find the SEC
sub welzl(@ps --> C) {
my @tests = (
|