Coords.php:
[fledgeling.git] / Coords.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<?php 
abstract class Coords { 
        // Vector math only actually makes sense in Cartesian, so we have to 
        // convert there, and convert back.
        public function vector_add($vector2) {
                $class = get_class($this);
                $vector1 = $this->convert("CartesianCoords");
                $vector2 = $vector2->convert("CartesianCoords");
                list($x1, $y1, $z1) = $vector1->triplet();
                list($x2, $y2, $z2) = $vector2->triplet();
                $vector3 = new CartesianCoords($x1+$x2, $y1+$y2, $z1+$z2);
                return $vector3->convert($class);
        }
        
        public function vector_subtract($vector2) {
                $class = get_class($this);
                $vector1 = $this->convert("CartesianCoords");
                $vector2 = $vector2->convert("CartesianCoords");
                list($x1, $y1, $z1) = $vector1->triplet();
                list($x2, $y2, $z2) = $vector2->triplet();
                $vector3 = new CartesianCoords($x1-$x2, $y1-$y2, $z1-$z2);
                return $vector3->convert($class);
        }
        
}
 
class SphericalCoords extends Coords {
        public function __construct($r, $t, $p) {
                $this->radius = $r;
                $this->theta = $t;
                $this->phi = $p;
                        
                return $this;
        }
 
        public function triplet() {
                return array(
                $this->radius,
                $this->theta,
                $this->phi
                );
        }
 
        public function convert($class) {
                switch ($class) {
                        case "SphericalCoords":
                                return $this;
                                break;
                        case "CartesianCoords":
                                return new CartesianCoords(
                                        $this->radius * sin($this->theta) * cos($this->phi),
                                        $this->radius * sin($this->theta) * sin($this->phi),
                                        $this->radius * cos($this->theta)
                                );
                                break;
                        case "LinearCoords":
                                return new LinearCoords($this->radius);
                                break;
                        default:
                                throw new Exception(sprintf("Cannot convert from type '%s' to type '%s'.", get_class($this), $class));
                                break;
                }
        }
        
        public function string() {
                return sprintf("r = %.2f, ϑ = %.2f, ϕ = %.2f", $this->radius, $this->theta, $this->phi);
        }
        
        public function magnitude() {
                return $this->radius;
        }
 
        protected $radius = 0;
        protected $theta  = 0;
        protected $phi = 0;
}
 
class CartesianCoords extends Coords {
        public function __construct($x, $y, $z) {
                $this->x = $x;
                $this->y = $y;
                $this->z = $z;
                 
                return $this;
        }
         
        public function triplet() {
                return array(
                $this->x,
                $this->y,
                $this->z
                );
        }
        
        public function string() {
                return sprintf("x = %.2f, y = %.2f, z = %.2f", $this->x, $this->y, $this->z);
        }
        
        public function magnitude() {
                return sqrt(pow($this->x,2) + pow($this->y,2) + pow($this->z,2));
        }
         
        public function convert($class) {
                switch ($class) {
                        case "SphericalCoords":
                                $r = sqrt(pow($this->x,2) + pow($this->y,2) + pow($this->z,2));
                                $t = acos($this->z / $r);
                                $p = atan2($this->y, $this->x);
                                return new SphericalCoords($r, $t, $p);
                                break;
                        case "CartesianCoords":
                                return $this;
                                break;
                        case "LinearCoords":
                                return new LinearCoords($this->magnitude());
                                break;
                        default:
                                throw new Exception(sprintf("Cannot convert from type '%s' to type '%s'.", get_class($this), $class));
                                break;
                }
        }
         
        protected $x = 0;
        protected $y = 0;
        protected $z = 0;
}
 
class LinearCoords extends CartesianCoords {
        public function __construct($d) {
                // make a cartesian object, with just one axis
                $this->y = 0;
                $this->z = 0;
                $this->x = $d;
                 
                return $this;
        }
        
        public function string() {
                return "x = " . $this->x;
        }
        
        public function magnitude() {
                return $this->x;
        }
}
?>