00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #include <new>
00047
00048 #include "Math2d.h"
00049 #include "Math3d.h"
00050 #include "Structs/Structs.h"
00051
00052
00053 #include <math.h>
00054
00055
00056
00057
00058
00059
00060
00061 const Vec2d Math2d::zero_vec = { 0, 0 };
00062
00063
00064
00065
00066
00067
00068 void Math2d::SetVec(Vec2d &vec, float x, float y)
00069 {
00070 vec.x = x;
00071 vec.y = y;
00072 }
00073
00074 void Math2d::SetVec(Vec2d &vec, const Vec2d &sourceVector)
00075 {
00076 vec.x = sourceVector.x;
00077 vec.y = sourceVector.y;
00078 }
00079
00080
00081 void Math2d::AddToVec(Vec2d &vec, const Vec2d &vectorToAdd)
00082 {
00083 vec.x += vectorToAdd.x;
00084 vec.y += vectorToAdd.y;
00085 }
00086
00087 void Math2d::SubtractFromVec(Vec2d &vec, const Vec2d &vectorToSubtract)
00088 {
00089 vec.x -= vectorToSubtract.x;
00090 vec.y -= vectorToSubtract.y;
00091 }
00092
00093 void Math2d::AddVecVec(const Vec2d &vector1, const Vec2d &vector2, Vec2d &result)
00094 {
00095 result.x = vector1.x + vector2.x;
00096 result.y = vector1.y + vector2.y;
00097 }
00098
00099 void Math2d::SetRotationMat(Mat2d &matrix, float angle)
00100 {
00101 const float sa = sinf(angle);
00102 const float ca = cosf(angle);
00103
00104 matrix.r1 = matrix.r4 = ca;
00105 matrix.r2 = -sa;
00106 matrix.r3 = sa;
00107 }
00108
00109 void Math2d::MulMatScalar(const Mat2d &matrix, float scalar, Mat2d &result)
00110 {
00111 result.r1 = matrix.r1 * scalar;
00112 result.r2 = matrix.r2 * scalar;
00113 result.r3 = matrix.r3 * scalar;
00114 result.r4 = matrix.r4 * scalar;
00115 }
00116
00117 void Math2d::MulMatMat(const Mat2d &matrix1, const Mat2d &matrix2, Mat2d &result)
00118 {
00119 const float r1 = matrix1.r1 * matrix2.r1 + matrix1.r2 * matrix2.r3;
00120 const float r2 = matrix1.r1 * matrix2.r2 + matrix1.r2 * matrix2.r4;
00121 const float r3 = matrix1.r3 * matrix2.r1 + matrix1.r4 * matrix2.r3;
00122 result.r4 = matrix1.r3 * matrix2.r2 + matrix1.r4 * matrix2.r4;
00123 result.r1 = r1;
00124 result.r2 = r2;
00125 result.r3 = r3;
00126 }
00127
00128 void Math2d::MulMatVec(const Mat2d &matrix, const Vec2d &vec, Vec2d &result)
00129 {
00130 const float temp = matrix.r1 * vec.x + matrix.r2 * vec.y;
00131 result.y = matrix.r3 * vec.x + matrix.r4 * vec.y;
00132 result.x = temp;
00133 }
00134
00135 void Math2d::MulMatVec(const Mat2d &matrix, const Vec2d &vector1, const Vec2d &vector2, Vec2d &result)
00136 {
00137 const float temp = matrix.r1 * vector1.x + matrix.r2 * vector1.y + vector2.x;
00138 result.y = matrix.r3 * vector1.x + matrix.r4 * vector1.y + vector2.y;
00139 result.x = temp;
00140 }
00141
00142 void Math2d::MulVecScalar(const Vec2d &vec, float scalar, Vec2d &result)
00143 {
00144 result.x = scalar * vec.x;
00145 result.y = scalar * vec.y;
00146 }
00147
00148 void Math2d::SubtractVecVec(const Vec2d &vector1, const Vec2d &vector2, Vec2d &result)
00149 {
00150 result.x = vector1.x - vector2.x;
00151 result.y = vector1.y - vector2.y;
00152 }
00153
00154
00155 float Math2d::ScalarProduct(const Vec2d &vector1, const Vec2d &vector2)
00156 {
00157 return vector1.x * vector2.x + vector1.y * vector2.y;
00158 }
00159
00160 void Math2d::NormalizeVec(Vec2d &vec)
00161 {
00162 const float length = sqrtf(vec.x * vec.x + vec.y * vec.y);
00163
00164 if (length != 0.0f)
00165 {
00166 vec.x /= length;
00167 vec.y /= length;
00168 }
00169 }
00170
00171 float Math2d::Length(const Vec2d &vec)
00172 {
00173 return sqrtf(vec.x * vec.x + vec.y * vec.y);
00174 }
00175
00176 float Math2d::SquaredLength(const Vec2d &vec)
00177 {
00178 return vec.x * vec.x + vec.y * vec.y;
00179 }
00180
00181 float Math2d::Distance(const Vec2d &vector1, const Vec2d &vector2)
00182 {
00183 const float x1 = vector1.x - vector2.x;
00184 const float x2 = vector1.y - vector2.y;
00185
00186 return sqrtf(x1 * x1 + x2 * x2);
00187 }
00188
00189 float Math2d::SquaredDistance(const Vec2d &vector1, const Vec2d &vector2)
00190 {
00191 const float x1 = vector1.x - vector2.x;
00192 const float x2 = vector1.y - vector2.y;
00193
00194 return x1 * x1 + x2 * x2;
00195 }
00196
00197 float Math2d::Angle(const Vec2d &vector1, const Vec2d &vector2)
00198 {
00199 const float sp = vector1.x * vector2.x + vector1.y * vector2.y;
00200 const float l1 = sqrtf(vector1.x * vector1.x + vector1.y * vector1.y);
00201 const float l2 = sqrtf(vector2.x * vector2.x + vector2.y * vector2.y);
00202
00203 return acosf(sp / (l1 * l2));
00204 }
00205
00206 void Math2d::RotateVec(const Vec2d &vec, float angle, Vec2d &result)
00207 {
00208 const float ca = cosf(angle);
00209 const float sa = sinf(angle);
00210
00211 const float temp = ca * vec.x - sa * vec.y;
00212 result.y = sa * vec.x + ca * vec.y;
00213 result.x = temp;
00214 }
00215
00216 void Math2d::RotateVec(const Vec2d &point, const Vec2d ¢er, float angle, Vec2d &result)
00217 {
00218 const float cx = center.x;
00219 const float cy = center.y;
00220
00221 SubtractVecVec(point, center, result);
00222 RotateVec(result, angle, result);
00223
00224 result.x += cx;
00225 result.y += cy;
00226 }
00227
00228 void Math2d::Transpose(const Mat2d &matrix, Mat2d &result)
00229 {
00230 result.r1 = matrix.r1;
00231 result.r4 = matrix.r4;
00232
00233 const float temp = matrix.r2;
00234 result.r2 = matrix.r3;
00235 result.r3 = temp;
00236 }
00237
00238 void Math2d::Invert(const Mat2d &matrix, Mat2d &result)
00239 {
00240 const float a = matrix.r1;
00241 const float b = matrix.r2;
00242 const float c = matrix.r3;
00243 const float d = matrix.r4;
00244
00245 float det_inverse = 1 / (a * d - b * c);
00246
00247 result.r1 = d * det_inverse;
00248 result.r2 = -b * det_inverse;
00249 result.r3 = -c * det_inverse;
00250 result.r4 = a * det_inverse;
00251 }
00252
00253 void Math2d::ApplyHomography(const Mat3d &A, const Vec2d &p, Vec2d &result)
00254 {
00255
00256
00257
00258
00259
00260 const float y_ = A.r4 * p.x + A.r5 * p.y + A.r6;
00261 const float z_ = A.r7 * p.x + A.r8 * p.y + A.r9;
00262
00263 result.x = (A.r1 * p.x + A.r2 * p.y + A.r3) / z_;
00264 result.y = y_ / z_;
00265 }
00266
00267 void Math2d::Average(const Vec2d &vector1, const Vec2d &vector2, Vec2d &result)
00268 {
00269 result.x = 0.5f * (vector1.x + vector2.x);
00270 result.y = 0.5f * (vector1.y + vector2.y);
00271 }
00272
00273 void Math2d::Mean(const CVec2dArray &vectorList, Vec2d &result)
00274 {
00275 Mean(vectorList.GetElements(), vectorList.GetSize(), result);
00276 }
00277
00278 void Math2d::Mean(const Vec2d *pVectors, int nVectors, Vec2d &result)
00279 {
00280 if (nVectors == 0)
00281 {
00282 result = zero_vec;
00283 return;
00284 }
00285
00286 float sum_x = 0.0f, sum_y = 0.0f;
00287
00288 for (int i = 0; i < nVectors; i++)
00289 {
00290 sum_x += pVectors[i].x;
00291 sum_y += pVectors[i].y;
00292 }
00293
00294 result.x = sum_x / float(nVectors);
00295 result.y = sum_y / float(nVectors);
00296 }
00297
00298 void Math2d::ComputeRectangleCornerPoints(const Rectangle2d &rectangle, Vec2d resultCornerPoints[4])
00299 {
00300 const float cx = rectangle.center.x;
00301 const float cy = rectangle.center.y;
00302 const float width2 = 0.5f * rectangle.width;
00303 const float height2 = 0.5f * rectangle.height;
00304 const float angle = rectangle.angle;
00305
00306
00307 SetVec(resultCornerPoints[0], cx - width2, cy - height2);
00308 SetVec(resultCornerPoints[1], cx + width2, cy - height2);
00309 SetVec(resultCornerPoints[2], cx + width2, cy + height2);
00310 SetVec(resultCornerPoints[3], cx - width2, cy + height2);
00311
00312 if (angle != 0.0f)
00313 {
00314 for (int i = 0; i < 4; i++)
00315 RotateVec(resultCornerPoints[i], rectangle.center, angle, resultCornerPoints[i]);
00316 }
00317 }