0031668: Visualization - WebGL sample doesn't work on Emscripten 1.39
[occt.git] / src / math / math_Vector.cxx
CommitLineData
b311480e 1// Copyright (c) 1997-1999 Matra Datavision
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
b311480e 14
7fd59977 15#include <stdio.h>
16
3b010a74 17#include <math_Vector.hxx>
7fd59977 18#include <math_Matrix.hxx>
19
20#include <Standard_DimensionError.hxx>
21#include <Standard_DivideByZero.hxx>
22#include <Standard_RangeError.hxx>
23#include <Standard_NullValue.hxx>
24
18434846 25math_Vector::math_Vector(const Standard_Integer theLower, const Standard_Integer theUpper)
26: myLocArray (theUpper - theLower + 1),
27 Array (myLocArray[0], theLower, theUpper)
7fd59977 28{
18434846 29 //
7fd59977 30}
31
3b010a74 32math_Vector::math_Vector(const Standard_Integer theLower,
33 const Standard_Integer theUpper,
18434846 34 const Standard_Real theInitialValue)
35: myLocArray (theUpper - theLower + 1),
36 Array (myLocArray[0], theLower, theUpper)
7fd59977 37{
3b010a74 38 Array.Init(theInitialValue);
7fd59977 39}
40
18434846 41math_Vector::math_Vector(const Standard_Real* theTab,
3b010a74 42 const Standard_Integer theLower,
18434846 43 const Standard_Integer theUpper)
44: Array (*theTab, theLower, theUpper)
3b010a74 45{
2d2b3d53 46 Standard_RangeError_Raise_if ((theLower > theUpper), "math_Vector() - invalid dimensions");
7fd59977 47}
48
18434846 49math_Vector::math_Vector (const gp_XY& theOther)
50: myLocArray (2),
51 Array (myLocArray[0], 1,2)
b5ef9d91 52{
53 Array(1) = theOther.X();
54 Array(2) = theOther.Y();
55}
56
18434846 57math_Vector::math_Vector (const gp_XYZ& theOther)
58: myLocArray (3),
59 Array (myLocArray[0], 1, 3)
b5ef9d91 60{
61 Array(1) = theOther.X();
62 Array(2) = theOther.Y();
63 Array(3) = theOther.Z();
64}
65
3b010a74 66void math_Vector::Init(const Standard_Real theInitialValue)
67{
68 Array.Init(theInitialValue);
69}
7fd59977 70
18434846 71math_Vector::math_Vector (const math_Vector& theOther)
72: myLocArray (theOther.Length()),
73 Array (myLocArray[0], theOther.Lower(), theOther.Upper())
3b010a74 74{
18434846 75 memcpy (&myLocArray[0], &theOther.Array.First(), sizeof(Standard_Real) * theOther.Length());
7fd59977 76}
77
3b010a74 78void math_Vector::SetLower(const Standard_Integer theLower)
79{
18434846 80 Array.Resize (theLower, Array.Upper() - Array.Lower() + theLower, Standard_False);
3b010a74 81}
7fd59977 82
3b010a74 83Standard_Real math_Vector::Norm() const
84{
7fd59977 85 Standard_Real Result = 0;
86
18434846 87 for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
3b010a74 88 {
7fd59977 89 Result = Result + Array(Index) * Array(Index);
90 }
91 return Sqrt(Result);
92}
93
3b010a74 94Standard_Real math_Vector::Norm2() const
95{
7fd59977 96 Standard_Real Result = 0;
97
18434846 98 for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
3b010a74 99 {
7fd59977 100 Result = Result + Array(Index) * Array(Index);
101 }
102 return Result;
103}
104
3b010a74 105Standard_Integer math_Vector::Max() const
106{
7fd59977 107 Standard_Integer I=0;
108 Standard_Real X = RealFirst();
109
18434846 110 for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
3b010a74 111 {
112 if(Array(Index) > X)
113 {
7fd59977 114 X = Array(Index);
115 I = Index;
116 }
117 }
118 return I;
119}
120
3b010a74 121Standard_Integer math_Vector::Min() const
122{
7fd59977 123 Standard_Integer I=0;
124 Standard_Real X = RealLast();
125
18434846 126 for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
3b010a74 127 {
128 if(Array(Index) < X)
129 {
7fd59977 130 X = Array(Index);
131 I = Index;
132 }
133 }
134 return I;
135}
136
3b010a74 137void math_Vector::Set(const Standard_Integer theI1,
138 const Standard_Integer theI2,
139 const math_Vector &theV)
140{
18434846 141 Standard_RangeError_Raise_if ((theI1 < Lower()) || (theI2 > Upper())
2d2b3d53 142 || (theI1 > theI2) || (theI2 - theI1 + 1 != theV.Length()),
143 "math_Vector::Set() - invalid indices");
7fd59977 144
3b010a74 145 Standard_Integer I = theV.Lower();
146 for(Standard_Integer Index = theI1; Index <= theI2; Index++)
147 {
148 Array(Index) = theV.Array(I);
7fd59977 149 I++;
150 }
151}
152
3b010a74 153void math_Vector::Normalize()
154{
7fd59977 155 Standard_Real Result = Norm();
2d2b3d53 156 Standard_NullValue_Raise_if ((Result <= RealEpsilon()),
157 "math_Vector::Normalize() - vector has zero norm");
18434846 158 for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
3b010a74 159 {
7fd59977 160 Array(Index) = Array(Index) / Result;
161 }
162}
163
3b010a74 164math_Vector math_Vector::Normalized() const
165{
7fd59977 166 math_Vector Result = *this;
167
168 Result.Normalize();
169 return Result;
170}
171
3b010a74 172void math_Vector::Invert()
173{
18434846 174 for(Standard_Integer Index = Lower(); Index <= (Lower() + Length()) >> 1 ; Index++)
3b010a74 175 {
18434846 176 Standard_Integer J = Upper() + Lower() - Index;
177 Standard_Real aTemp = Array(Index);
7fd59977 178 Array(Index) = Array(J);
18434846 179 Array(J) = aTemp;
7fd59977 180 }
181}
182
3b010a74 183math_Vector math_Vector::Inverse() const
184{
7fd59977 185 math_Vector Result = *this;
186 Result.Invert();
187 return Result;
188}
189
3b010a74 190math_Vector math_Vector::Multiplied(const Standard_Real theRight) const
191{
18434846 192 math_Vector Result (Lower(), Upper());
193 for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
3b010a74 194 {
195 Result.Array(Index) = Array(Index) * theRight;
7fd59977 196 }
197 return Result;
198}
199
3b010a74 200math_Vector math_Vector::TMultiplied(const Standard_Real theRight) const
201{
18434846 202 math_Vector Result (Lower(), Upper());
203 for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
3b010a74 204 {
205 Result.Array(Index) = Array(Index) * theRight;
7fd59977 206 }
207 return Result;
208}
209
3b010a74 210void math_Vector::Multiply(const Standard_Real theRight)
211{
18434846 212 for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
3b010a74 213 {
214 Array(Index) = Array(Index) * theRight;
7fd59977 215 }
216}
217
3b010a74 218void math_Vector::Divide(const Standard_Real theRight)
219{
2d2b3d53 220 Standard_DivideByZero_Raise_if (Abs(theRight) <= RealEpsilon(),
221 "math_Vector::Divide() - devisor is zero");
7fd59977 222
18434846 223 for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
3b010a74 224 {
225 Array(Index) = Array(Index) / theRight;
7fd59977 226 }
227}
228
3b010a74 229math_Vector math_Vector::Divided (const Standard_Real theRight) const
230{
2d2b3d53 231 Standard_DivideByZero_Raise_if (Abs(theRight) <= RealEpsilon(),
232 "math_Vector::Divided() - devisor is zero");
3b010a74 233 math_Vector temp = Multiplied(1./theRight);
7fd59977 234 return temp;
235}
236
3b010a74 237void math_Vector::Add(const math_Vector& theRight)
238{
2d2b3d53 239 Standard_DimensionError_Raise_if (Length() != theRight.Length(),
240 "math_Vector::Add() - input vector has wrong dimensions");
7fd59977 241
18434846 242 Standard_Integer I = theRight.Lower();
243 for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
3b010a74 244 {
245 Array(Index) = Array(Index) + theRight.Array(I);
7fd59977 246 I++;
247 }
3b010a74 248}
7fd59977 249
3b010a74 250math_Vector math_Vector::Added(const math_Vector& theRight) const
251{
2d2b3d53 252 Standard_DimensionError_Raise_if (Length() != theRight.Length(),
253 "math_Vector::Added() - input vector has wrong dimensions");
7fd59977 254
18434846 255 math_Vector Result (Lower(), Upper());
3b010a74 256
18434846 257 Standard_Integer I = theRight.Lower();
258 for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
3b010a74 259 {
260 Result.Array(Index) = Array(Index) + theRight.Array(I);
7fd59977 261 I++;
262 }
263 return Result;
3b010a74 264}
7fd59977 265
3b010a74 266void math_Vector::Subtract(const math_Vector& theRight)
267{
2d2b3d53 268 Standard_DimensionError_Raise_if (Length() != theRight.Length(),
269 "math_Vector::Subtract() - input vector has wrong dimensions");
7fd59977 270
18434846 271 Standard_Integer I = theRight.Lower();
272 for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
3b010a74 273 {
274 Array(Index) = Array(Index) - theRight.Array(I);
7fd59977 275 I++;
276 }
3b010a74 277}
7fd59977 278
3b010a74 279math_Vector math_Vector::Subtracted (const math_Vector& theRight) const
280{
2d2b3d53 281 Standard_DimensionError_Raise_if (Length() != theRight.Length(),
282 "math_Vector::Subtracted() - input vector has wrong dimensions");
7fd59977 283
18434846 284 math_Vector Result(Lower(), Upper());
3b010a74 285
18434846 286 Standard_Integer I = theRight.Lower();
287 for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
3b010a74 288 {
289 Result.Array(Index) = Array(Index) - theRight.Array(I);
7fd59977 290 I++;
291 }
292 return Result;
3b010a74 293}
7fd59977 294
3b010a74 295math_Vector math_Vector::Slice(const Standard_Integer theI1, const Standard_Integer theI2) const
7fd59977 296{
18434846 297 Standard_RangeError_Raise_if ((theI1 < Lower()) || (theI1 > Upper()) || (theI2 < Lower()) || (theI2 > Upper()),
2d2b3d53 298 "math_Vector::Slice() - invalid indices");
7fd59977 299
3b010a74 300 if(theI2 >= theI1)
301 {
302 math_Vector Result(theI1, theI2);
303 for(Standard_Integer Index = theI1; Index <= theI2; Index++)
304 {
7fd59977 305 Result.Array(Index) = Array(Index);
3b010a74 306 }
307 return Result;
7fd59977 308 }
3b010a74 309 else
310 {
311 math_Vector Result(theI2, theI1);
312 for(Standard_Integer Index = theI1; Index >= theI2; Index--)
313 {
7fd59977 314 Result.Array(Index) = Array(Index);
315 }
316 return Result;
3b010a74 317 }
7fd59977 318}
319
3b010a74 320void math_Vector::Add (const math_Vector& theLeft, const math_Vector& theRight)
321{
2d2b3d53 322 Standard_DimensionError_Raise_if ((Length() != theRight.Length()) || (theRight.Length() != theLeft.Length()),
323 "math_Vector::Add() - input vectors have wrong dimensions");
7fd59977 324
18434846 325 Standard_Integer I = theLeft.Lower();
326 Standard_Integer J = theRight.Lower();
327 for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
3b010a74 328 {
329 Array(Index) = theLeft.Array(I) + theRight.Array(J);
7fd59977 330 I++;
331 J++;
332 }
3b010a74 333}
334
335void math_Vector::Subtract (const math_Vector& theLeft, const math_Vector& theRight)
336{
2d2b3d53 337 Standard_DimensionError_Raise_if ((Length() != theRight.Length()) || (theRight.Length() != theLeft.Length()),
338 "math_Vector::Subtract() - input vectors have wrong dimensions");
3b010a74 339
18434846 340 Standard_Integer I = theLeft.Lower();
341 Standard_Integer J = theRight.Lower();
342 for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
3b010a74 343 {
344 Array(Index) = theLeft.Array(I) - theRight.Array(J);
7fd59977 345 I++;
346 J++;
347 }
3b010a74 348}
7fd59977 349
3b010a74 350void math_Vector::Multiply(const math_Matrix& theLeft, const math_Vector& theRight)
351{
2d2b3d53 352 Standard_DimensionError_Raise_if ((Length() != theLeft.RowNumber())
353 || (theLeft.ColNumber() != theRight.Length()),
354 "math_Vector::Multiply() - input matrix and/or vector have wrong dimensions");
7fd59977 355
18434846 356 Standard_Integer Index = Lower();
3b010a74 357 for(Standard_Integer I = theLeft.LowerRowIndex; I <= theLeft.UpperRowIndex; I++)
358 {
7fd59977 359 Array(Index) = 0.0;
18434846 360 Standard_Integer K = theRight.Lower();
3b010a74 361 for(Standard_Integer J = theLeft.LowerColIndex; J <= theLeft.UpperColIndex; J++)
362 {
363 Array(Index) = Array(Index) + theLeft.Array(I, J) * theRight.Array(K);
7fd59977 364 K++;
365 }
366 Index++;
367 }
3b010a74 368}
7fd59977 369
3b010a74 370void math_Vector::Multiply(const math_Vector& theLeft, const math_Matrix& theRight)
371{
2d2b3d53 372 Standard_DimensionError_Raise_if ((Length() != theRight.ColNumber())
373 || (theLeft.Length() != theRight.RowNumber()),
374 "math_Vector::Multiply() - input matrix and/or vector have wrong dimensions");
7fd59977 375
18434846 376 Standard_Integer Index = Lower();
3b010a74 377 for(Standard_Integer J = theRight.LowerColIndex; J <= theRight.UpperColIndex; J++)
378 {
7fd59977 379 Array(Index) = 0.0;
18434846 380 Standard_Integer K = theLeft.Lower();
3b010a74 381 for(Standard_Integer I = theRight.LowerRowIndex; I <= theRight.UpperRowIndex; I++)
382 {
383 Array(Index) = Array(Index) + theLeft.Array(K) * theRight.Array(I, J);
7fd59977 384 K++;
385 }
386 Index++;
387 }
3b010a74 388}
7fd59977 389
3b010a74 390void math_Vector::TMultiply(const math_Matrix& theTLeft, const math_Vector& theRight)
391{
2d2b3d53 392 Standard_DimensionError_Raise_if ((Length() != theTLeft.ColNumber())
393 || (theTLeft.RowNumber() != theRight.Length()),
394 "math_Vector::TMultiply() - input matrix and/or vector have wrong dimensions");
7fd59977 395
18434846 396 Standard_Integer Index = Lower();
3b010a74 397 for(Standard_Integer I = theTLeft.LowerColIndex; I <= theTLeft.UpperColIndex; I++)
398 {
7fd59977 399 Array(Index) = 0.0;
18434846 400 Standard_Integer K = theRight.Lower();
3b010a74 401 for(Standard_Integer J = theTLeft.LowerRowIndex; J <= theTLeft.UpperRowIndex; J++)
402 {
403 Array(Index) = Array(Index) + theTLeft.Array(J, I) * theRight.Array(K);
7fd59977 404 K++;
405 }
406 Index++;
407 }
3b010a74 408}
7fd59977 409
3b010a74 410void math_Vector::TMultiply(const math_Vector& theLeft, const math_Matrix& theTRight)
411{
2d2b3d53 412 Standard_DimensionError_Raise_if ((Length() != theTRight.RowNumber())
413 || (theLeft.Length() != theTRight.ColNumber()),
414 "math_Vector::TMultiply() - input matrix and/or vector have wrong dimensions");
7fd59977 415
18434846 416 Standard_Integer Index = Lower();
3b010a74 417 for(Standard_Integer J = theTRight.LowerRowIndex; J <= theTRight.UpperRowIndex; J++)
418 {
7fd59977 419 Array(Index) = 0.0;
18434846 420 Standard_Integer K = theLeft.Lower();
3b010a74 421 for(Standard_Integer I = theTRight.LowerColIndex;
422 I <= theTRight.UpperColIndex; I++)
423 {
424 Array(Index) = Array(Index) + theLeft.Array(K) * theTRight.Array(J, I);
425 K++;
7fd59977 426 }
427 Index++;
428 }
3b010a74 429}
7fd59977 430
3b010a74 431Standard_Real math_Vector::Multiplied(const math_Vector& theRight) const
432{
7fd59977 433 Standard_Real Result = 0;
434
2d2b3d53 435 Standard_DimensionError_Raise_if (Length() != theRight.Length(),
436 "math_Vector::Multiplied() - input vector has wrong dimensions");
7fd59977 437
18434846 438 Standard_Integer I = theRight.Lower();
439 for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
3b010a74 440 {
441 Result = Result + Array(Index) * theRight.Array(I);
7fd59977 442 I++;
443 }
444 return Result;
3b010a74 445}
7fd59977 446
3b010a74 447math_Vector math_Vector::Opposite()
448{
18434846 449 math_Vector Result(Lower(), Upper());
450 for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
3b010a74 451 {
7fd59977 452 Result.Array(Index) = - Array(Index);
453 }
454 return Result;
3b010a74 455}
456
457math_Vector math_Vector::Multiplied(const math_Matrix& theRight)const
458{
2d2b3d53 459 Standard_DimensionError_Raise_if (Length() != theRight.RowNumber(),
460 "math_Vector::Multiplied() - input matrix has wrong dimensions");
3b010a74 461
462 math_Vector Result(theRight.LowerColIndex, theRight.UpperColIndex);
463 for(Standard_Integer J2 = theRight.LowerColIndex; J2 <= theRight.UpperColIndex; J2++)
464 {
18434846 465 Result.Array(J2) = 0.0;
466 Standard_Integer theI2 = theRight.LowerRowIndex;
467 for(Standard_Integer I = Lower(); I <= Upper(); I++)
468 {
469 Result.Array(J2) = Result.Array(J2) + Array(I) * theRight.Array(theI2, J2);
470 theI2++;
471 }
7fd59977 472 }
473 return Result;
3b010a74 474}
7fd59977 475
3b010a74 476void math_Vector::Multiply(const Standard_Real theLeft, const math_Vector& theRight)
7fd59977 477{
2d2b3d53 478 Standard_DimensionError_Raise_if ((Length() != theRight.Length()),
479 "math_Vector::Multiply() - input vector has wrong dimensions");
18434846 480 for(Standard_Integer I = Lower(); I <= Upper(); I++)
3b010a74 481 {
482 Array(I) = theLeft * theRight.Array(I);
7fd59977 483 }
484}
485
3b010a74 486math_Vector& math_Vector::Initialized(const math_Vector& theOther)
487{
2d2b3d53 488 Standard_DimensionError_Raise_if (Length() != theOther.Length(),
489 "math_Vector::Initialized() - input vector has wrong dimensions");
18434846 490 memmove (&Array.ChangeFirst(), &theOther.Array.First(), sizeof(Standard_Real) * Array.Length());
7fd59977 491 return *this;
492}
493
3b010a74 494void math_Vector::Dump(Standard_OStream& theO) const
7fd59977 495{
3b010a74 496 theO << "math_Vector of Length = " << Length() << "\n";
18434846 497 for(Standard_Integer Index = Lower(); Index <= Upper(); Index++)
3b010a74 498 {
499 theO << "math_Vector(" << Index << ") = " << Array(Index) << "\n";
7fd59977 500 }
501}
3b010a74 502