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.php');
36
37/**
38 * Image_3D_Object_Sphere
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.1.0
48 */
49class Image_3D_Object_Sphere extends Image_3D_Object
50{
51
52    protected $_points;
53    protected $_virtualPolygon;
54    protected $_radius;
55
56    public function __construct($options)
57    {
58        parent::__construct();
59
60        $this->_lines = array();
61        $this->_points = array();
62        $this->_virtualPolygon = array();
63        $this->_radius = (float) @$options['r'];
64        $detail = (int) @$options['detail'];
65
66        $this->_createTetraeder();
67
68        for ($step = 0; $step < $detail; $step++) $this->_sierpinsky();
69
70        $this->_getRealPolygones();
71    }
72
73    protected function _sierpinsky()
74    {
75        $newPolygones   = array();
76        $proceededLines = array();
77        foreach ($this->_virtualPolygon as $points) {
78
79            $lines = array(
80                array(min($points[0], $points[1]), max($points[0], $points[1])),
81                array(min($points[1], $points[2]), max($points[1], $points[2])),
82                array(min($points[2], $points[0]), max($points[2], $points[0]))
83            );
84
85            $new = array();
86            foreach ($lines as $line) {
87                if (!isset($proceededLines[$line[0]][$line[1]])) {
88                    // Calculate new point
89                    $newX = ($this->_points[$line[0]]->getX() + $this->_points[$line[1]]->getX()) / 2;
90                    $newY = ($this->_points[$line[0]]->getY() + $this->_points[$line[1]]->getY()) / 2;
91                    $newZ = ($this->_points[$line[0]]->getZ() + $this->_points[$line[1]]->getZ()) / 2;
92
93                    $multiplikator = $this->_radius / sqrt(pow($newX, 2) + pow($newY, 2) + pow($newZ, 2));
94
95                    $this->_points[] = new Image_3D_Point($newX * $multiplikator, $newY * $multiplikator, $newZ * $multiplikator);
96
97                    $proceededLines[$line[0]][$line[1]] = count($this->_points) - 1;
98                }
99                $new[] = $proceededLines[$line[0]][$line[1]];
100            }
101
102            $newPolygones[] = array($points[0], $new[0], $new[2]);
103            $newPolygones[] = array($points[1], $new[1], $new[0]);
104            $newPolygones[] = array($points[2], $new[2], $new[1]);
105            $newPolygones[] = array($new[0], $new[1], $new[2]);
106        }
107        $this->_virtualPolygon = $newPolygones;
108    }
109
110    protected function _createTetraeder()
111    {
112        $laenge = $this->_radius / sqrt(3);
113
114        $this->_points[] = new Image_3D_Point(sqrt(2) * -$laenge, $laenge, 0);
115        $this->_points[] = new Image_3D_Point(sqrt(2) * $laenge, $laenge, 0);
116        $this->_points[] = new Image_3D_Point(0, -$laenge, sqrt(2) * -$laenge);
117        $this->_points[] = new Image_3D_Point(0, -$laenge, sqrt(2) * $laenge);
118
119        $this->_virtualPolygon[] = array(0, 1, 3);
120        $this->_virtualPolygon[] = array(1, 2, 3);
121        $this->_virtualPolygon[] = array(0, 2, 1);
122        $this->_virtualPolygon[] = array(0, 3, 2);
123    }
124
125    protected function _getRealPolygones()
126    {
127        foreach ($this->_virtualPolygon as $points) {
128            $this->_addPolygon(new Image_3D_Polygon($this->_points[$points[0]], $this->_points[$points[1]], $this->_points[$points[2]]));
129        }
130    }
131}
132