Permalink
Browse files

Move RangeOfSize from test file to KnotVector.pm. New tougher Nubs te…

…sts. Nubs.Evaluate now takes a direction argument. KnotVector.N_local no longer takes a direction argument (it was unused).
  • Loading branch information...
1 parent 69cc207 commit ec1121675633cbb34fa7b60a6db4611bab1099df SF committed Oct 21, 2009
Showing with 49 additions and 22 deletions.
  1. +19 −2 lib/KnotVector.pm
  2. +4 −4 lib/Nurbs.pm
  3. +0 −16 t/02-knots.t
  4. +26 −0 t/03-nubs.t
View
@@ -9,6 +9,23 @@ sub infix:<O/>($a, $b)
return $a / $b;
}
+# this one is handy for testing
+multi sub RangeOfSize($a, $b, $size)
+{
+ my $delta = ($b - $a) / ($size - 1);
+ my $value = $a;
+ return gather
+ {
+ loop (my $i = 0; $i + 1 < $size; $i++)
+ {
+ my $result = $value;
+ take $result;
+ $value += $delta;
+ }
+ take $b;
+ }
+}
+
class KnotVector
{
has @.knots;
@@ -37,7 +54,7 @@ class KnotVector
}
}
- multi method N_local(Int $n0, Int $p, $u, KnotBasisDirection $direction = Left)
+ multi method N_local(Int $n0, Int $p, $u)
{
my @N_prev = 0 xx $p, 1, 0;
my @N = 0 xx ($p + 2);
@@ -60,7 +77,7 @@ class KnotVector
{
my $n0 = self.N0_index($p, $u, $direction);
my @N = 0 xx (@.knots.elems - $p - 1);
- @N[($n0)..($n0 + $p)] = self.N_local($n0, $p, $u, $direction);
+ @N[($n0)..($n0 + $p)] = self.N_local($n0, $p, $u);
return @N;
}
}
View
@@ -18,16 +18,16 @@ class Nubs
self.WHAT.perl ~ ".new($.degree, {$.knot_vector.perl}, {@.control_points.perl})";
}
- multi method Evaluate($t)
+ multi method Evaluate($t, KnotBasisDirection $direction = Left)
{
- my $n0 = $.knot_vector.N0_index($.degree, $t);
+ my $n0 = $.knot_vector.N0_index($.degree, $t, $direction);
return [+] ($.knot_vector.N_local($n0, $.degree, $t)
>>*<< @.control_points[$n0 .. ($n0 + $.degree)]);
}
- multi method Evaluate($base_t, $actual_t)
+ multi method Evaluate($base_t, $actual_t, KnotBasisDirection $direction = Left)
{
- my $n0 = $.knot_vector.N0_index($.degree, $base_t);
+ my $n0 = $.knot_vector.N0_index($.degree, $base_t, $direction);
return [+] ($.knot_vector.N_local($n0, $.degree, $actual_t)
>>*<< @.control_points[$n0 .. ($n0 + $.degree)]);
}
View
@@ -20,22 +20,6 @@ multi sub N(@u, $i, $p, $u, KnotBasisDirection $direction = Left)
+ ((@u[$i + $p + 1] - $u) O/ (@u[$i + $p + 1] - @u[$i + 1])) * N(@u, $i + 1, $p - 1, $u, $direction);
}
-multi sub RangeOfSize($a, $b, $size)
-{
- my $delta = ($b - $a) / ($size - 1);
- my $value = $a;
- return gather
- {
- loop (my $i = 0; $i + 1 < $size; $i++)
- {
- my $result = $value;
- take $result;
- $value += $delta;
- }
- take $b;
- }
-}
-
my @knots = (0, 0, 1, 1);
is_approx(N(@knots, 0, 0, -1), 0, "Before first knot is 0");
is_approx(N(@knots, 0, 0, 0), 0, "At first knot is 0");
View
@@ -25,4 +25,30 @@ is_approx_vector($nubs1.Evaluate(0.4), Vector.new(0.4, 4, 40, 400), "\$nubs1.Eva
my $nubs2 = Nubs.new(1, $kv, (Vector.new(1, 10, 100, 1000), Vector.new(0, 0, 0, 0)));
is_approx_vector($nubs2.Evaluate(0.0), Vector.new(1, 10, 100, 1000), "\$nubs2.Evaluate(0.0) is (1, 10, 100, 1000)");
+# hardcore tests
+
+my @control_points = (Vector.new(-1, -2, -3),
+ Vector.new(1, 0, 0),
+ Vector.new(1, 1, 0),
+ Vector.new(0, 1, 0),
+ Vector.new(1, 2, 0),
+ Vector.new(1, 2, 1),
+ Vector.new(1, 2, -1));
+my @knots = (-1, -1, -1, -1, 1, 2, 2, 3, 3, 3, 3);
+my Nubs $nubs = Nubs.new(3, KnotVector.new(@knots), @control_points);
+
+is_approx_vector $nubs.Evaluate(-1), Vector.new(-1, -2, -3), "\$nubs.Evaluate(-1) is (-1, -2, -3)";
+is_approx_vector $nubs.Evaluate(3.0, Right), Vector.new(1, 2, -1), "\$nubs.Evaluate(3.0) is (1, 2, -1)";
+
+my $translation = Vector.new(3, 4.0, 5);
+my Nubs $nubs3 = Nubs.new(3, KnotVector.new(@knots), @control_points >>+>> $translation);
+
+for RangeOfSize(-1, 3, 10) -> $t
+{
+ my $direction = $t < 3 ?? Left !! Right;
+ is_approx_vector $nubs3.Evaluate($t, $direction),
+ $nubs.Evaluate($t, $direction) + $translation,
+ "\$nubs3.Evaluate($t) == \$nubs.Evaluate($t) + \$translation";
+}
+
done_testing;

0 comments on commit ec11216

Please sign in to comment.