1<?php 2 3/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ 4 5/** 6 * 3d Library 7 * 8 * PHP versions 5 9 * 10 * LICENSE: 11 * This library is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU Lesser General Public 13 * License as published by the Free Software Foundation; either 14 * version 2.1 of the License, or (at your option) any later version. 15 * 16 * This library is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 * Lesser General Public License for more details. 20 * 21 * You should have received a copy of the GNU Lesser General Public 22 * License along with this library; if not, write to the Free Software 23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 24 * 25 * @category Image 26 * @package Image_3D 27 * @author Kore Nordmann <3d@kore-nordmann.de> 28 * @copyright 1997-2005 Kore Nordmann 29 * @license http://www.gnu.org/licenses/lgpl.txt lgpl 2.1 30 * @version CVS: $Id$ 31 * @link http://pear.php.net/package/PackageName 32 * @since File available since Release 0.1.0 33 */ 34 35require_once('Image/3D/Paintable/Object/Map.php'); 36 37/** 38 * Image_3D_Object_Bezier 39 * 40 * @category Image 41 * @package Image_3D 42 * @author Kore Nordmann <3d@kore-nordmann.de> 43 * @copyright 1997-2005 Kore Nordmann 44 * @license http://www.gnu.org/licenses/lgpl.txt lgpl 2.1 45 * @version Release: @package_version@ 46 * @link http://pear.php.net/package/PackageName 47 * @since Class available since Release 0.3.0 48 */ 49class Image_3D_Object_Bezier extends Image_3D_Object_Map { 50 51 public function __construct($options) { 52 // Fetch options 53 $x_detail = max(2, (int) @$options['x_detail']); 54 $y_detail = max(2, (int) @$options['y_detail']); 55 56 if (!isset($options['points']) || !is_array($options['points'])) return false; 57 58 $points = array(); 59 foreach ($options['points'] as $row) { 60 if (!is_array($row)) continue; 61 $points[] = array(); 62 $akt_row = count($points) - 1; 63 64 foreach ($row as $point) { 65 if (!is_array($point)) continue; 66 $points[$akt_row][] = $point; 67 } 68 } 69 70 $n = count($points) - 1; 71 $m = count($points[0]) - 1; 72 $map = array(); 73 74 for ($u = 0; $u <= $x_detail; ++$u) { 75 for ($v = 0; $v <= $y_detail; ++$v) { 76 $point = array(0, 0, 0); 77 78 for ($i = 0; $i <= $n; ++$i) { 79 for ($j = 0; $j <= $m; ++$j) { 80 $factor = $this->_bernstein($i, $n, $u / $x_detail) * $this->_bernstein($j, $m, $v / $y_detail); 81 $point[0] += $points[$i][$j][0] * $factor; 82 $point[1] += $points[$i][$j][1] * $factor; 83 $point[2] += $points[$i][$j][2] * $factor; 84 } 85 } 86 87 $map[$u][$v] = new Image_3D_Point($point[0], $point[1], $point[2]); 88 } 89 } 90 91 parent::__construct($map); 92 } 93 94 protected function _binomial_coefficient($n, $k) { 95 if ($k > $n) return 0; 96 if ($k == 0) return 1; 97 98 if (2 * $k > $n) { 99 $result = $this->_binomial_coefficient($n, $n - $k); 100 } else { 101 $result = $n; 102 for ($i = 2; $i <= $k; ++$i) { 103 $result *= $n + 1 - $i; 104 $result /= $i; 105 } 106 } 107 108 return $result; 109 } 110 111 protected function _bernstein($i, $n, $t) { 112 return $this->_binomial_coefficient($n, $i) * pow($t, $i) * pow(1 - $t, $n - $i); 113 } 114 115} 116