00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <math.h>
00018 #include <stdio.h>
00019 #include "mmath.h"
00020
00021 Vector3 Vector3_new(float x, float y, float z)
00022 {
00023 Vector3 result;
00024
00025 result.x = x;
00026 result.y = y;
00027 result.z = z;
00028
00029 return result;
00030 }
00031
00032 Vector3 Vector3_add(Vector3 u, Vector3 v)
00033 {
00034 Vector3 result;
00035
00036 result.x = u.x + v.x;
00037 result.y = u.y + v.y;
00038 result.z = u.z + v.z;
00039
00040 return result;
00041 }
00042
00043 Vector3 Vector3_sub(Vector3 u, Vector3 v)
00044 {
00045 Vector3 result;
00046
00047 result.x = u.x - v.x;
00048 result.y = u.y - v.y;
00049 result.z = u.z - v.z;
00050
00051 return result;
00052 }
00053
00054 Vector3 Vector3_smult(float s, Vector3 v)
00055 {
00056 Vector3 result;
00057
00058 result.x = s * v.x;
00059 result.y = s * v.y;
00060 result.z = s * v.z;
00061
00062 return result;
00063 }
00064
00065 Vector3 Vector3_mult(Vector3 u, Vector3 v)
00066 {
00067 Vector3 result;
00068
00069 result.x = u.x * v.x;
00070 result.y = u.y * v.y;
00071 result.z = u.z * v.z;
00072
00073 return result;
00074 }
00075
00076 Vector3 Vector3_cross(Vector3 u, Vector3 v)
00077 {
00078 Vector3 result;
00079
00080 result.x = u.y * v.z - u.z * v.y;
00081 result.y = u.z * v.x - u.x * v.z;
00082 result.z = u.x * v.y - u.y * v.x;
00083
00084 return result;
00085 }
00086
00087 float Vector3_dot(Vector3 u, Vector3 v)
00088 {
00089 return u.x*v.x + u.y*v.y + u.z*v.z;
00090 }
00091
00092 float Vector3_normalize(Vector3 *v)
00093 {
00094 float d = (float)sqrt(SQR(v->x) + SQR(v->y) + SQR(v->z));
00095
00096 if (d > EPS) {
00097 v->x /= d;
00098 v->y /= d;
00099 v->z /= d;
00100 return d;
00101 } else {
00102 v->x = v->y = v->z = 0.f;
00103 return 0.f;
00104 }
00105 }
00106
00107 void Vector3_stderr(char *s, Vector3 v)
00108 {
00109 fprintf(stderr, "%s <%f, %f, %f>\n", s, v.x, v.y, v.z);
00110 }
00111
00112 Quaternion Quaternion_new(float w, float x, float y, float z)
00113 {
00114 Quaternion result;
00115
00116 result.x = w;
00117 result.y = x;
00118 result.z = y;
00119 result.w = z;
00120
00121 return result;
00122 }
00123
00124 Quaternion Quaternion_fromAngleAxis(float angle, Vector3 axis)
00125 {
00126 Quaternion q;
00127 float l = Vector3_normalize(&axis);
00128
00129 if(l > EPS){
00130 l = (float)sin(0.5f * angle) / l;
00131 q.x = axis.x * l;
00132 q.y = axis.y * l;
00133 q.z = axis.z * l;
00134 q.w = (float)cos(0.5f * angle);
00135 } else {
00136 q.x = 0.f;
00137 q.y = 0.f;
00138 q.z = 0.f;
00139 q.w = 1.f;
00140 }
00141
00142 return q;
00143 }
00144
00145 Quaternion Quaternion_mult(Quaternion p, Quaternion q)
00146 {
00147 Quaternion result;
00148
00149 result.w = p.w * q.w - (p.x * q.x + p.y * q.y + p.z * q.z);
00150 result.x = p.w * q.x + q.w * p.x + p.y * q.z - p.z * q.y;
00151 result.y = p.w * q.y + q.w * p.y + p.z * q.x - p.x * q.z;
00152 result.z = p.w * q.z + q.w * p.z + p.x * q.y - p.y * q.x;
00153
00154 return result;
00155 }
00156
00157 void Quaternion_getAngleAxis(const Quaternion q, float *angle, Vector3 *axis)
00158 {
00159 float d = (float)sqrt(SQR(q.x) + SQR(q.y) + SQR(q.z));
00160
00161 if(d > EPS){
00162 d = 1.f / d;
00163 axis->x = q.x * d;
00164 axis->y = q.y * d;
00165 axis->z = q.z * d;
00166 *angle = 2.f * (float)acos(q.w);
00167 } else {
00168 axis->x = 0.f;
00169 axis->y = 0.f;
00170 axis->z = 1.f;
00171 *angle = 0.f;
00172 }
00173 }
00174
00175 void Quaternion_normalize(Quaternion *q)
00176 {
00177 float d = (float)sqrt(SQR(q->w) + SQR(q->x) + SQR(q->y) + SQR(q->z));
00178 if (d > EPS) {
00179 d = 1.f / d;
00180 q->w *= d;
00181 q->x *= d;
00182 q->y *= d;
00183 q->z *= d;
00184 } else {
00185 q->w = 1.f;
00186 q->x = q->y = q->z = 0.f;
00187 }
00188 }
00189
00190 Quaternion Quaternion_inverse(Quaternion q)
00191 {
00192 Quaternion result;
00193 float d = SQR(q.w) + SQR(q.x) + SQR(q.y) + SQR(q.z);
00194 if (d > EPS) {
00195 d = 1.f / (float)sqrt(d);
00196 result.w = q.w * d;
00197 result.x = -q.x * d;
00198 result.y = -q.y * d;
00199 result.z = -q.z * d;
00200 } else {
00201 result.w = 1.f;
00202 result.x = result.y = result.z = 0.f;
00203 }
00204 return result;
00205 }
00206
00207 Vector3 Quaternion_multVector3(Quaternion q, Vector3 v)
00208 {
00209 Vector3 result, u;
00210 float uu, uv;
00211
00212 u.x = q.x;
00213 u.y = q.y;
00214 u.z = q.z;
00215
00216 uu = Vector3_dot(u, u);
00217 uv = Vector3_dot(u,v);
00218
00219 result = Vector3_smult(2.f, Vector3_add(Vector3_smult(uv, u),
00220 Vector3_smult(q.w, Vector3_cross(u, v))));
00221 result = Vector3_add(result, Vector3_smult(SQR(q.w) - uu, v));
00222
00223 return result;
00224 }
00225
00226
00227 void Quaternion_stderr(char *s, Quaternion q)
00228 {
00229 fprintf(stderr, "%s (%f <%f, %f, %f>)\n", s, q.w, q.x, q.y, q.z);
00230 }
00231