Skip to content

Instantly share code, notes, and snippets.

@andrewrcollins
Created January 18, 2013 08:34
Show Gist options
  • Save andrewrcollins/4563178 to your computer and use it in GitHub Desktop.
Save andrewrcollins/4563178 to your computer and use it in GitHub Desktop.
<?php
// http://en.wikipedia.org/wiki/B%C3%A9zier_curve#Explicit_definition
// calculate C(n,k) aka binomial coefficient
// http://php.net/manual/en/ref.math.php#57895
function C($n, $k)
{
$j = $res = 1;
if($k < 0 || $k > $n)
return 0;
if(($n - $k) < $k)
$k = $n - $k;
while($j <= $k)
{
$res *= $n--;
$res /= $j++;
}
return $res;
}
// t : [0, 1]
// P0, P1, ..., Pn : n-dimensional point
// B(t) = sum i=0...n C(n,i) * (1-t)^(n-i) * t^i * Pi
function GeneralBezierCurve($t /* , P0, P1, ..., Pn */)
{
$n = func_num_args() - 2;
$u = 1 - $t;
$p = array_fill(0, count(func_get_arg(1)) - 1, 0);
for($i = 0; $i <= $n; $i++)
{
$P_i = func_get_arg($i + 1);
$C_i = C($n, $i);
$u_i = pow($u, $n - $i);
$t_i = pow($t, $i);
// $T_i = C($n, $i) * pow($u, $n - $i) * pow($t, $i) * $P_i;
$function = function($i) use ($C_i, $u_i, $t_i) {
return $C_i * $u_i * $t_i * $i;
};
$T_i = array_map($function, $P_i);
// sum of terms
// $p += $T_i;
$function = function($a, $b) {
return $a + $b;
};
$p = array_map($function, $p, $T_i);
}
return $p;
}
// http://en.wikipedia.org/wiki/B%C3%A9zier_curve#Quadratic_B.C3.A9zier_curves
// t : [0, 1]
// p0, p1, p2 : n-dimensional point
// B(t) = (1-t)^2 * p0 + 2*(1-t)*t * p1 + t^2 * p2
function QuadraticBezierCurve($t, $p0, $p1, $p2)
{
$u = 1 - $t;
$uu = $u * $u;
$tt = $t * $t;
// first term
// $t1 = $uu * $p0;
$function = function($i) use ($uu) {
return $uu * $i;
};
$t1 = array_map($function, $p0);
// second term
// $t2 = 2 * $u * $t * $p1;
$function = function($i) use ($u, $t) {
return 2 * $u * $t * $i;
};
$t2 = array_map($function, $p1);
// third term
// $t3 = $tt * $p2;
$function = function($i) use ($tt) {
return $tt * $i;
};
$t3 = array_map($function, $p2);
// sum of terms
// $p = $t1 + $t2 + $t3;
$function = function($a, $b, $c) {
return $a + $b + $c;
};
$p = array_map($function, $t1, $t2, $t3);
return $p;
}
// http://en.wikipedia.org/wiki/B%C3%A9zier_curve#Cubic_B.C3.A9zier_curves
// t : [0, 1]
// p0, p1, p2, p3 : n-dimensional point
// B(t) = (1-t)^3 * p0 + 3*(1-t)^2*t * p1 + 3*(1-t)*t^2 * p2 + t^3 * p3
function CubicBezierCurve($t, $p0, $p1, $p2, $p3)
{
$u = 1 - $t;
$uu = $u * $u;
$uuu = $uu * $u;
$tt = $t * $t;
$ttt = $tt * $t;
// first term
// $t1 = $uuu * $p0;
$function = function($i) use ($uuu) {
return $uuu * $i;
};
$t1 = array_map($function, $p0);
// second term
// $t2 = 3 * $uu * $t * $p1;
$function = function($i) use ($uu, $t) {
return 3 * $uu * $t * $i;
};
$t2 = array_map($function, $p1);
// third term
// $t3 = 3 * $u * $tt * $p2;
$function = function($i) use ($u, $tt) {
return 3 * $u * $tt * $i;
};
$t3 = array_map($function, $p2);
// fourth term
// $t4 = $ttt * $p3;
$function = function($i) use ($ttt) {
return $ttt * $i;
};
$t4 = array_map($function, $p3);
// sum of terms
// $p = $t1 + $t2 + $t3 + $t4;
$function = function($a, $b, $c, $d) {
return $a + $b + $c + $d;
};
$p = array_map($function, $t1, $t2, $t3, $t4);
return $p;
}
$p0 = array(0, 50);
$p1 = array(50, 100);
$p2 = array(200, 200);
for($t = 0.0; $t < 1.0; $t += 0.1)
{
$p_quadratic = QuadraticBezierCurve($t, $p0, $p1, $p2);
echo $t . "\t" . implode(",", $p_quadratic) . "\n";
$p_general = GeneralBezierCurve($t, $p0, $p1, $p2);
echo $t . "\t" . implode(",", $p_general) . "\n";
}
$p0 = array(0, 50, 150);
$p1 = array(50, 100, 0);
$p2 = array(200, 200, 150);
$p3 = array(100, 200, 50);
for($t = 0.0; $t < 1.0; $t += 0.1)
{
$p_cubic = CubicBezierCurve($t, $p0, $p1, $p2, $p3);
echo $t . "\t" . implode(",", $p_cubic) . "\n";
$p_general = GeneralBezierCurve($t, $p0, $p1, $p2, $p3);
echo $t . "\t" . implode(",", $p_general) . "\n";
}
$p0 = array(0, 50);
$p1 = array(50, 100);
$p2 = array(200, 200);
$p3 = array(100, 200);
$p4 = array(100, 50);
for($t = 0.0; $t < 1.0; $t += 0.1)
{
$p_general = GeneralBezierCurve($t, $p0, $p1, $p2, $p3, $p4);
echo $t . "\t" . implode(",", $p_general) . "\n";
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment