3dphotoshoot

annotate libs/vmath/vector.cc @ 15:2d48f65da357

assman
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 07 Jun 2015 20:40:37 +0300
parents
children
rev   line source
nuclear@10 1 /*
nuclear@10 2 libvmath - a vector math library
nuclear@10 3 Copyright (C) 2004-2015 John Tsiombikas <nuclear@member.fsf.org>
nuclear@10 4
nuclear@10 5 This program is free software: you can redistribute it and/or modify
nuclear@10 6 it under the terms of the GNU Lesser General Public License as published
nuclear@10 7 by the Free Software Foundation, either version 3 of the License, or
nuclear@10 8 (at your option) any later version.
nuclear@10 9
nuclear@10 10 This program is distributed in the hope that it will be useful,
nuclear@10 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
nuclear@10 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
nuclear@10 13 GNU Lesser General Public License for more details.
nuclear@10 14
nuclear@10 15 You should have received a copy of the GNU Lesser General Public License
nuclear@10 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
nuclear@10 17 */
nuclear@10 18 #include "vector.h"
nuclear@10 19 #include "vmath.h"
nuclear@10 20
nuclear@10 21 // ---------- Vector2 -----------
nuclear@10 22
nuclear@10 23 Vector2::Vector2(scalar_t x, scalar_t y)
nuclear@10 24 {
nuclear@10 25 this->x = x;
nuclear@10 26 this->y = y;
nuclear@10 27 }
nuclear@10 28
nuclear@10 29 Vector2::Vector2(const vec2_t &vec)
nuclear@10 30 {
nuclear@10 31 x = vec.x;
nuclear@10 32 y = vec.y;
nuclear@10 33 }
nuclear@10 34
nuclear@10 35 Vector2::Vector2(const Vector3 &vec)
nuclear@10 36 {
nuclear@10 37 x = vec.x;
nuclear@10 38 y = vec.y;
nuclear@10 39 }
nuclear@10 40
nuclear@10 41 Vector2::Vector2(const Vector4 &vec)
nuclear@10 42 {
nuclear@10 43 x = vec.x;
nuclear@10 44 y = vec.y;
nuclear@10 45 }
nuclear@10 46
nuclear@10 47 void Vector2::normalize()
nuclear@10 48 {
nuclear@10 49 scalar_t len = length();
nuclear@10 50 x /= len;
nuclear@10 51 y /= len;
nuclear@10 52 }
nuclear@10 53
nuclear@10 54 Vector2 Vector2::normalized() const
nuclear@10 55 {
nuclear@10 56 scalar_t len = length();
nuclear@10 57 return Vector2(x / len, y / len);
nuclear@10 58 }
nuclear@10 59
nuclear@10 60 void Vector2::transform(const Matrix3x3 &mat)
nuclear@10 61 {
nuclear@10 62 scalar_t nx = mat[0][0] * x + mat[0][1] * y + mat[0][2];
nuclear@10 63 y = mat[1][0] * x + mat[1][1] * y + mat[1][2];
nuclear@10 64 x = nx;
nuclear@10 65 }
nuclear@10 66
nuclear@10 67 Vector2 Vector2::transformed(const Matrix3x3 &mat) const
nuclear@10 68 {
nuclear@10 69 Vector2 vec;
nuclear@10 70 vec.x = mat[0][0] * x + mat[0][1] * y + mat[0][2];
nuclear@10 71 vec.y = mat[1][0] * x + mat[1][1] * y + mat[1][2];
nuclear@10 72 return vec;
nuclear@10 73 }
nuclear@10 74
nuclear@10 75 void Vector2::rotate(scalar_t angle)
nuclear@10 76 {
nuclear@10 77 *this = Vector2(cos(angle) * x - sin(angle) * y, sin(angle) * x + cos(angle) * y);
nuclear@10 78 }
nuclear@10 79
nuclear@10 80 Vector2 Vector2::rotated(scalar_t angle) const
nuclear@10 81 {
nuclear@10 82 return Vector2(cos(angle) * x - sin(angle) * y, sin(angle) * x + cos(angle) * y);
nuclear@10 83 }
nuclear@10 84
nuclear@10 85 Vector2 Vector2::reflection(const Vector2 &normal) const
nuclear@10 86 {
nuclear@10 87 return 2.0 * dot_product(*this, normal) * normal - *this;
nuclear@10 88 }
nuclear@10 89
nuclear@10 90 Vector2 Vector2::refraction(const Vector2 &normal, scalar_t src_ior, scalar_t dst_ior) const
nuclear@10 91 {
nuclear@10 92 // quick and dirty implementation :)
nuclear@10 93 Vector3 v3refr = Vector3(this->x, this->y, 1.0).refraction(Vector3(this->x, this->y, 1), src_ior, dst_ior);
nuclear@10 94 return Vector2(v3refr.x, v3refr.y);
nuclear@10 95 }
nuclear@10 96
nuclear@10 97 /*
nuclear@10 98 std::ostream &operator <<(std::ostream &out, const Vector2 &vec)
nuclear@10 99 {
nuclear@10 100 out << "[" << vec.x << " " << vec.y << "]";
nuclear@10 101 return out;
nuclear@10 102 }
nuclear@10 103 */
nuclear@10 104
nuclear@10 105
nuclear@10 106 // --------- Vector3 ----------
nuclear@10 107
nuclear@10 108 Vector3::Vector3(scalar_t x, scalar_t y, scalar_t z)
nuclear@10 109 {
nuclear@10 110 this->x = x;
nuclear@10 111 this->y = y;
nuclear@10 112 this->z = z;
nuclear@10 113 }
nuclear@10 114
nuclear@10 115 Vector3::Vector3(const vec3_t &vec)
nuclear@10 116 {
nuclear@10 117 x = vec.x;
nuclear@10 118 y = vec.y;
nuclear@10 119 z = vec.z;
nuclear@10 120 }
nuclear@10 121
nuclear@10 122 Vector3::Vector3(const Vector2 &vec)
nuclear@10 123 {
nuclear@10 124 x = vec.x;
nuclear@10 125 y = vec.y;
nuclear@10 126 z = 1;
nuclear@10 127 }
nuclear@10 128
nuclear@10 129 Vector3::Vector3(const Vector4 &vec)
nuclear@10 130 {
nuclear@10 131 x = vec.x;
nuclear@10 132 y = vec.y;
nuclear@10 133 z = vec.z;
nuclear@10 134 }
nuclear@10 135
nuclear@10 136 Vector3::Vector3(const SphVector &sph)
nuclear@10 137 {
nuclear@10 138 *this = sph;
nuclear@10 139 }
nuclear@10 140
nuclear@10 141 Vector3 &Vector3::operator =(const SphVector &sph)
nuclear@10 142 {
nuclear@10 143 x = sph.r * cos(sph.theta) * sin(sph.phi);
nuclear@10 144 z = sph.r * sin(sph.theta) * sin(sph.phi);
nuclear@10 145 y = sph.r * cos(sph.phi);
nuclear@10 146 return *this;
nuclear@10 147 }
nuclear@10 148
nuclear@10 149 void Vector3::normalize()
nuclear@10 150 {
nuclear@10 151 scalar_t len = length();
nuclear@10 152 x /= len;
nuclear@10 153 y /= len;
nuclear@10 154 z /= len;
nuclear@10 155 }
nuclear@10 156
nuclear@10 157 Vector3 Vector3::normalized() const
nuclear@10 158 {
nuclear@10 159 scalar_t len = length();
nuclear@10 160 return Vector3(x / len, y / len, z / len);
nuclear@10 161 }
nuclear@10 162
nuclear@10 163 Vector3 Vector3::reflection(const Vector3 &normal) const
nuclear@10 164 {
nuclear@10 165 return 2.0 * dot_product(*this, normal) * normal - *this;
nuclear@10 166 }
nuclear@10 167
nuclear@10 168 Vector3 Vector3::refraction(const Vector3 &normal, scalar_t src_ior, scalar_t dst_ior) const
nuclear@10 169 {
nuclear@10 170 return refraction(normal, src_ior / dst_ior);
nuclear@10 171 }
nuclear@10 172
nuclear@10 173 Vector3 Vector3::refraction(const Vector3 &normal, scalar_t ior) const
nuclear@10 174 {
nuclear@10 175 scalar_t cos_inc = dot_product(*this, -normal);
nuclear@10 176
nuclear@10 177 scalar_t radical = 1.0 + SQ(ior) * (SQ(cos_inc) - 1.0);
nuclear@10 178
nuclear@10 179 if(radical < 0.0) { // total internal reflection
nuclear@10 180 return -reflection(normal);
nuclear@10 181 }
nuclear@10 182
nuclear@10 183 scalar_t beta = ior * cos_inc - sqrt(radical);
nuclear@10 184
nuclear@10 185 return *this * ior + normal * beta;
nuclear@10 186 }
nuclear@10 187
nuclear@10 188 void Vector3::transform(const Matrix3x3 &mat)
nuclear@10 189 {
nuclear@10 190 scalar_t nx = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z;
nuclear@10 191 scalar_t ny = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z;
nuclear@10 192 z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z;
nuclear@10 193 x = nx;
nuclear@10 194 y = ny;
nuclear@10 195 }
nuclear@10 196
nuclear@10 197 Vector3 Vector3::transformed(const Matrix3x3 &mat) const
nuclear@10 198 {
nuclear@10 199 Vector3 vec;
nuclear@10 200 vec.x = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z;
nuclear@10 201 vec.y = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z;
nuclear@10 202 vec.z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z;
nuclear@10 203 return vec;
nuclear@10 204 }
nuclear@10 205
nuclear@10 206 void Vector3::transform(const Matrix4x4 &mat)
nuclear@10 207 {
nuclear@10 208 scalar_t nx = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3];
nuclear@10 209 scalar_t ny = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3];
nuclear@10 210 z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3];
nuclear@10 211 x = nx;
nuclear@10 212 y = ny;
nuclear@10 213 }
nuclear@10 214
nuclear@10 215 Vector3 Vector3::transformed(const Matrix4x4 &mat) const
nuclear@10 216 {
nuclear@10 217 Vector3 vec;
nuclear@10 218 vec.x = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3];
nuclear@10 219 vec.y = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3];
nuclear@10 220 vec.z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3];
nuclear@10 221 return vec;
nuclear@10 222 }
nuclear@10 223
nuclear@10 224 void Vector3::transform(const Quaternion &quat)
nuclear@10 225 {
nuclear@10 226 Quaternion vq(0.0f, *this);
nuclear@10 227 vq = quat * vq * quat.inverse();
nuclear@10 228 *this = vq.v;
nuclear@10 229 }
nuclear@10 230
nuclear@10 231 Vector3 Vector3::transformed(const Quaternion &quat) const
nuclear@10 232 {
nuclear@10 233 Quaternion vq(0.0f, *this);
nuclear@10 234 vq = quat * vq * quat.inverse();
nuclear@10 235 return vq.v;
nuclear@10 236 }
nuclear@10 237
nuclear@10 238 void Vector3::rotate(const Vector3 &euler)
nuclear@10 239 {
nuclear@10 240 Matrix4x4 rot;
nuclear@10 241 rot.set_rotation(euler);
nuclear@10 242 transform(rot);
nuclear@10 243 }
nuclear@10 244
nuclear@10 245 Vector3 Vector3::rotated(const Vector3 &euler) const
nuclear@10 246 {
nuclear@10 247 Matrix4x4 rot;
nuclear@10 248 rot.set_rotation(euler);
nuclear@10 249 return transformed(rot);
nuclear@10 250 }
nuclear@10 251
nuclear@10 252 /*
nuclear@10 253 std::ostream &operator <<(std::ostream &out, const Vector3 &vec)
nuclear@10 254 {
nuclear@10 255 out << "[" << vec.x << " " << vec.y << " " << vec.z << "]";
nuclear@10 256 return out;
nuclear@10 257 }
nuclear@10 258 */
nuclear@10 259
nuclear@10 260
nuclear@10 261 // -------------- Vector4 --------------
nuclear@10 262 Vector4::Vector4(scalar_t x, scalar_t y, scalar_t z, scalar_t w)
nuclear@10 263 {
nuclear@10 264 this->x = x;
nuclear@10 265 this->y = y;
nuclear@10 266 this->z = z;
nuclear@10 267 this->w = w;
nuclear@10 268 }
nuclear@10 269
nuclear@10 270 Vector4::Vector4(const vec4_t &vec)
nuclear@10 271 {
nuclear@10 272 x = vec.x;
nuclear@10 273 y = vec.y;
nuclear@10 274 z = vec.z;
nuclear@10 275 w = vec.w;
nuclear@10 276 }
nuclear@10 277
nuclear@10 278 Vector4::Vector4(const Vector2 &vec)
nuclear@10 279 {
nuclear@10 280 x = vec.x;
nuclear@10 281 y = vec.y;
nuclear@10 282 z = 1;
nuclear@10 283 w = 1;
nuclear@10 284 }
nuclear@10 285
nuclear@10 286 Vector4::Vector4(const Vector3 &vec)
nuclear@10 287 {
nuclear@10 288 x = vec.x;
nuclear@10 289 y = vec.y;
nuclear@10 290 z = vec.z;
nuclear@10 291 w = 1;
nuclear@10 292 }
nuclear@10 293
nuclear@10 294 void Vector4::normalize()
nuclear@10 295 {
nuclear@10 296 scalar_t len = (scalar_t)sqrt(x*x + y*y + z*z + w*w);
nuclear@10 297 x /= len;
nuclear@10 298 y /= len;
nuclear@10 299 z /= len;
nuclear@10 300 w /= len;
nuclear@10 301 }
nuclear@10 302
nuclear@10 303 Vector4 Vector4::normalized() const
nuclear@10 304 {
nuclear@10 305 scalar_t len = (scalar_t)sqrt(x*x + y*y + z*z + w*w);
nuclear@10 306 return Vector4(x / len, y / len, z / len, w / len);
nuclear@10 307 }
nuclear@10 308
nuclear@10 309 void Vector4::transform(const Matrix4x4 &mat)
nuclear@10 310 {
nuclear@10 311 scalar_t nx = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3] * w;
nuclear@10 312 scalar_t ny = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3] * w;
nuclear@10 313 scalar_t nz = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3] * w;
nuclear@10 314 w = mat[3][0] * x + mat[3][1] * y + mat[3][2] * z + mat[3][3] * w;
nuclear@10 315 x = nx;
nuclear@10 316 y = ny;
nuclear@10 317 z = nz;
nuclear@10 318 }
nuclear@10 319
nuclear@10 320 Vector4 Vector4::transformed(const Matrix4x4 &mat) const
nuclear@10 321 {
nuclear@10 322 Vector4 vec;
nuclear@10 323 vec.x = mat[0][0] * x + mat[0][1] * y + mat[0][2] * z + mat[0][3] * w;
nuclear@10 324 vec.y = mat[1][0] * x + mat[1][1] * y + mat[1][2] * z + mat[1][3] * w;
nuclear@10 325 vec.z = mat[2][0] * x + mat[2][1] * y + mat[2][2] * z + mat[2][3] * w;
nuclear@10 326 vec.w = mat[3][0] * x + mat[3][1] * y + mat[3][2] * z + mat[3][3] * w;
nuclear@10 327 return vec;
nuclear@10 328 }
nuclear@10 329
nuclear@10 330 // TODO: implement 4D vector reflection
nuclear@10 331 Vector4 Vector4::reflection(const Vector4 &normal) const
nuclear@10 332 {
nuclear@10 333 return *this;
nuclear@10 334 }
nuclear@10 335
nuclear@10 336 // TODO: implement 4D vector refraction
nuclear@10 337 Vector4 Vector4::refraction(const Vector4 &normal, scalar_t src_ior, scalar_t dst_ior) const
nuclear@10 338 {
nuclear@10 339 return *this;
nuclear@10 340 }
nuclear@10 341
nuclear@10 342 /*
nuclear@10 343 std::ostream &operator <<(std::ostream &out, const Vector4 &vec)
nuclear@10 344 {
nuclear@10 345 out << "[" << vec.x << " " << vec.y << " " << vec.z << " " << vec.w << "]";
nuclear@10 346 return out;
nuclear@10 347 }
nuclear@10 348 */