/src/org/mt4j/util/math/Vector3D.java

http://mt4j.googlecode.com/ · Java · 1103 lines · 381 code · 118 blank · 604 comment · 34 complexity · cf6d0dced76205a50442e321441fb772 MD5 · raw file

  1. /***********************************************************************
  2. * mt4j Copyright (c) 2008 - 2009 C.Ruff, Fraunhofer-Gesellschaft All rights reserved.
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. *
  17. ***********************************************************************/
  18. package org.mt4j.util.math;
  19. import java.awt.Point;
  20. /**
  21. * ************************************************
  22. * Homogenous 3D vector class with 4 components, X, Y, Z and W.
  23. *
  24. * @author Christopher Ruff
  25. * ************************************************
  26. */
  27. public class Vector3D {
  28. /** The w. */
  29. public float x, y, z, w;
  30. /** The type. */
  31. private transient int type;
  32. /** The Constant VECTOR. */
  33. public static final int VECTOR = 0;
  34. /** The Constant VERTEX. */
  35. public static final int VERTEX = 1;
  36. /** The Constant BEZIERVERTEX. */
  37. public static final int BEZIERVERTEX = 2;
  38. /** Zero vector (0,0,0). */
  39. public static final Vector3D ZERO_VECTOR = new Vector3D(0,0,0);
  40. /** Defines positive X axis. */
  41. public static final Vector3D X_AXIS = new Vector3D(1, 0, 0);
  42. /** Defines positive Y axis. */
  43. public static final Vector3D Y_AXIS = new Vector3D(0, 1, 0);
  44. /** Defines positive Z axis. */
  45. public static final Vector3D Z_AXIS = new Vector3D(0, 0, 1);
  46. /**
  47. * Instantiates a new vector3 d.
  48. */
  49. public Vector3D() {
  50. this(0,0,0,1);
  51. }
  52. /**
  53. * Instantiates a new vector3 d.
  54. *
  55. * @param x the x
  56. * @param y the y
  57. */
  58. public Vector3D(float x, float y){
  59. this(x,y,0);
  60. }
  61. /**
  62. * Instantiates a new vector3 d.
  63. *
  64. * @param x the x
  65. * @param y the y
  66. * @param z the z
  67. */
  68. public Vector3D(float x, float y, float z){
  69. this(x,y,z,1);
  70. }
  71. /**
  72. * Instantiates a new vector3 d.
  73. *
  74. * @param x the x
  75. * @param y the y
  76. * @param z the z
  77. * @param w the w
  78. */
  79. public Vector3D(float x, float y, float z, float w){
  80. this.x = x;
  81. this.y = y;
  82. this.z = z;
  83. this.w = w;
  84. this.setType(Vector3D.VECTOR);
  85. }
  86. /**
  87. * Instantiates a new vector3 d.
  88. *
  89. * @param v the v
  90. */
  91. public Vector3D(Vector3D v) {
  92. this(v.getX(),v.getY(),v.getZ(),v.getW());
  93. }
  94. /**
  95. * Gets the deep vertex array copy.
  96. * Uses the getCopy() method on each vector.
  97. *
  98. * @param vertices the vertices
  99. *
  100. * @return the deep vertex array copy
  101. */
  102. public static Vector3D[] getDeepVertexArrayCopy(Vector3D[] vertices){
  103. Vector3D[] copy = new Vector3D[vertices.length];
  104. for (int i = 0; i < vertices.length; i++) {
  105. Vector3D vertex = vertices[i];
  106. copy[i] = vertex.getCopy();
  107. }
  108. return copy;
  109. }
  110. /**
  111. * Applies a transformation on the vector
  112. * defined by the given tranformation matrix.
  113. *
  114. * @param transformMatrix the transform matrix
  115. */
  116. public void transform(Matrix transformMatrix){
  117. transformMatrix.mult(this);
  118. }
  119. //TODO reicht es den W coord des Vectors auf 0 zu setzen?
  120. //FIXME eigentlich sollte man direction vectoren wie normale
  121. //transformieren also mit transformNormal, aber so gehts auch meistens..why?
  122. /**
  123. * Transforms a direction vector, not a point.
  124. * Ignores the translation part of the matrix
  125. *
  126. * @param transformMatrix the transform matrix
  127. */
  128. public void transformDirectionVector(Matrix transformMatrix){
  129. Matrix m = new Matrix(transformMatrix);
  130. m.removeTranslationFromMatrix();
  131. this.transform(m);
  132. }
  133. /**
  134. * Transforms a normal or direction vector.
  135. * This is done by multiplying the vector with the
  136. * inverse transpose of the matrix.
  137. * <p>
  138. * <strong>NOTE</strong>: this is not cheap because a new matrix is created (copied)
  139. * inverted and then transposed.<p>
  140. * (If you can supply a precomputed inverted matrix yourself, write
  141. * yourself a method that doesent do the invert() call :))
  142. *
  143. * @param transformMatrix the transform matrix
  144. */
  145. public void transformNormal(Matrix transformMatrix){
  146. Matrix inverse = transformMatrix.invert();
  147. // this.setW(0);
  148. try {
  149. Matrix transpose = inverse.transpose();
  150. transpose.mult(this,this);
  151. } catch (Exception e) {
  152. e.printStackTrace();
  153. }
  154. }
  155. /**
  156. * Multiplicates all Vector3D of the Vector3D array with the given
  157. * transformation matrix, thus transforming them.
  158. * Make a deepcopy of the vectors first if you dont want the originals being altered!
  159. *
  160. * @param transformMatrix the transform matrix
  161. * @param points the points
  162. *
  163. * @return the transformed vector array
  164. */
  165. public static Vector3D[] transFormArrayLocal(Matrix transformMatrix, Vector3D[] points){
  166. for (Vector3D v : points)
  167. v.transform(transformMatrix);
  168. return points;
  169. }
  170. /**
  171. * Translate.
  172. *
  173. * @param directionVector the direction vector
  174. */
  175. public void translate(Vector3D directionVector){
  176. this.transform(Matrix.getTranslationMatrix(directionVector.getX(), directionVector.getY(), directionVector.getZ()));
  177. }
  178. /**
  179. * translates an array of Vector3D by the given amounts in the directionvector.
  180. *
  181. * @param inputArray the input array
  182. * @param directionVector the direction vector
  183. *
  184. * @return the vector3 d[]
  185. */
  186. public static Vector3D[] translateVectorArray(Vector3D[] inputArray, Vector3D directionVector){
  187. return Vector3D.transFormArrayLocal(Matrix.getTranslationMatrix(directionVector.getX(), directionVector.getY(), directionVector.getZ())
  188. , inputArray);
  189. }
  190. /**
  191. * Rotate x.
  192. *
  193. * @param rotationPoint the rotation point
  194. * @param degree the degree
  195. */
  196. public void rotateX(Vector3D rotationPoint, float degree ){
  197. this.transform(Matrix.getXRotationMatrix(rotationPoint, degree));
  198. }
  199. /**
  200. * rotates the Vector3D array around the rotationpoint by the given degree.
  201. *
  202. * @param rotationPoint the rotation point
  203. * @param degree the degree
  204. * @param inputArray the input array
  205. *
  206. * @return the rotated vector3D array
  207. */
  208. public static Vector3D[] rotateXVectorArray(Vector3D[] inputArray, Vector3D rotationPoint, float degree ){
  209. return Vector3D.transFormArrayLocal(Matrix.getXRotationMatrix(rotationPoint, degree),inputArray);
  210. }
  211. /**
  212. * Rotate y.
  213. *
  214. * @param rotationPoint the rotation point
  215. * @param degree the degree
  216. */
  217. public void rotateY(Vector3D rotationPoint, float degree ){
  218. this.transform(Matrix.getYRotationMatrix(rotationPoint, degree));
  219. }
  220. /**
  221. * rotates the Vector3D array around the rotationpoint by the given degree.
  222. *
  223. * @param rotationPoint the rotation point
  224. * @param degree the degree
  225. * @param inputArray the input array
  226. *
  227. * @return the rotated vector3D array
  228. */
  229. public static Vector3D[] rotateYVectorArray(Vector3D[] inputArray, Vector3D rotationPoint, float degree ){
  230. return Vector3D.transFormArrayLocal(Matrix.getYRotationMatrix(rotationPoint, degree), inputArray);
  231. }
  232. /**
  233. * Rotate z.
  234. *
  235. * @param rotationPoint the rotation point
  236. * @param degree the degree
  237. */
  238. public void rotateZ(Vector3D rotationPoint, float degree ){
  239. this.transform(Matrix.getZRotationMatrix(rotationPoint, degree));
  240. }
  241. /**
  242. * Rotates the vector by the given angle around the X axis.
  243. *
  244. * @param theta the theta
  245. *
  246. * @return itself
  247. */
  248. public final Vector3D rotateX(float theta) {
  249. float co = (float) Math.cos(theta);
  250. float si = (float) Math.sin(theta);
  251. float zz = co * z - si * y;
  252. y = si * z + co * y;
  253. z = zz;
  254. return this;
  255. }
  256. /**
  257. * Rotates the vector by the given angle around the Y axis.
  258. *
  259. * @param theta the theta
  260. *
  261. * @return itself
  262. */
  263. public final Vector3D rotateY(float theta) {
  264. float co = (float) Math.cos(theta);
  265. float si = (float) Math.sin(theta);
  266. float xx = co * x - si * z;
  267. z = si * x + co * z;
  268. x = xx;
  269. return this;
  270. }
  271. /**
  272. * Rotates the vector by the given angle around the Z axis.
  273. * RADIANS EXPECTED!
  274. * @param theta the theta
  275. *
  276. * @return itself
  277. */
  278. public final Vector3D rotateZ(float theta) {
  279. // /*
  280. float co = (float) Math.cos(theta);
  281. float si = (float) Math.sin(theta);
  282. float xx = co * x - si * y;
  283. y = si * x + co * y;
  284. x = xx;
  285. return this;
  286. // */
  287. }
  288. /**
  289. * rotates the Vector3D array around the rotationpoint by the given degree.
  290. *
  291. * @param rotationPoint the rotation point
  292. * @param degree the degree
  293. * @param inputArray the input array
  294. *
  295. * @return the rotated vector3D array
  296. */
  297. public static Vector3D[] rotateZVectorArray(Vector3D[] inputArray, Vector3D rotationPoint, float degree ){
  298. return Vector3D.transFormArrayLocal(Matrix.getZRotationMatrix(rotationPoint, degree), inputArray);
  299. }
  300. /**
  301. * Scale the vector by factor.
  302. *
  303. * @param scalar the scalar
  304. *
  305. * @return the vector after scaling
  306. */
  307. public Vector3D scaleLocal(float scalar) {
  308. this.setXYZ(this.x * scalar, this.y * scalar, this.z * scalar ) ;
  309. return this;
  310. }
  311. public Vector3D divideLocal(float scalar) {
  312. scalar = 1f/scalar;
  313. x *= scalar;
  314. y *= scalar;
  315. z *= scalar;
  316. return this;
  317. }
  318. /**
  319. * Gets the scaled.
  320. *
  321. * @param scalar the scalar
  322. *
  323. * @return the scaled
  324. *
  325. * a new scaled vector
  326. */
  327. public Vector3D getScaled(float scalar) {
  328. return new Vector3D(this.x * scalar, this.y * scalar, this.z * scalar);
  329. }
  330. /**
  331. * scales the Vector3D[] around the scalingpoint by the given factor evenly in the X and Y direction.
  332. *
  333. * @param inputArray the input array
  334. * @param scalingPoint the scaling point
  335. * @param factor the factor
  336. *
  337. * @return the resulting vector array
  338. */
  339. public static Vector3D[] scaleVectorArray(Vector3D[] inputArray, Vector3D scalingPoint, float factor) {
  340. return Vector3D.transFormArrayLocal(Matrix.getScalingMatrix(scalingPoint, factor,factor,factor), inputArray);
  341. }
  342. /**
  343. * scales the Vector3D[] around the scalingpoint by the factors given for each dimension.
  344. *
  345. * @param inputArray the input array
  346. * @param scalingPoint the scaling point
  347. * @param X the x
  348. * @param Y the y
  349. * @param Z the z
  350. *
  351. * @return the resulting vector array
  352. */
  353. public static Vector3D[] scaleVectorArray(Vector3D[] inputArray, Vector3D scalingPoint, float X, float Y, float Z) {
  354. return Vector3D.transFormArrayLocal(Matrix.getScalingMatrix(scalingPoint, X, Y, Z), inputArray);
  355. }
  356. /**
  357. * Add a vector to this vector.
  358. *
  359. * @param v the v
  360. *
  361. * @return the vector after the addition
  362. */
  363. public Vector3D addLocal(Vector3D v) {
  364. this.setX(x + v.getX());
  365. this.setY(y + v.getY());
  366. this.setZ(z + v.getZ());
  367. return this;
  368. }
  369. /**
  370. * Gets the added.
  371. *
  372. * @param v the v
  373. *
  374. * @return an new Vector with the result of the addition
  375. */
  376. public Vector3D getAdded(Vector3D v){
  377. return new Vector3D(x + v.getX() , y + v.getY(), z + v.getZ());
  378. }
  379. /**
  380. * NOTE: texture coordinates of the calling vector are kept.
  381. *
  382. * @param v the v
  383. *
  384. * @return an new Vector with the result of the subtraction
  385. */
  386. public Vector3D getSubtracted(Vector3D v){
  387. return new Vector3D(x - v.getX() , y - v.getY(), z - v.getZ());
  388. }
  389. /**
  390. * Subtract a vector from this vector.
  391. *
  392. * @param v the v
  393. *
  394. * @return TODO
  395. */
  396. public Vector3D subtractLocal(Vector3D v) {
  397. this.setX(x - v.getX());
  398. this.setY(y - v.getY());
  399. this.setZ(z - v.getZ());
  400. return this;
  401. }
  402. /**
  403. * Scales vector uniformly by factor -1 ( v = -v ), overrides coordinates
  404. * with result.
  405. *
  406. * @return itself
  407. */
  408. public Vector3D invertLocal() {
  409. x *= -1;
  410. y *= -1;
  411. z *= -1;
  412. return this;
  413. }
  414. /**
  415. * Scales vector uniformly by factor -1 ( v = -v ), overrides coordinates
  416. * with result.
  417. *
  418. * @return itself
  419. */
  420. public Vector3D getInverted() {
  421. return new Vector3D(x*-1, y*-1, z*-1);
  422. }
  423. /**
  424. * Interpolates the vector towards the given target vector, using linear
  425. * interpolation.
  426. *
  427. * @param v target vector
  428. * @param f interpolation factor (should be in the range 0..1)
  429. *
  430. * @return result as new vector
  431. */
  432. public final Vector3D getInterpolatedTo(Vector3D v, float f) {
  433. return new Vector3D(x + (v.x - x) * f, y + (v.y - y) * f, z + (v.z - z)
  434. * f);
  435. }
  436. /**
  437. * Copy the vector.
  438. *
  439. * @return a copy of the vector
  440. */
  441. public Vector3D getCopy() {
  442. return new Vector3D(x, y, z, w);
  443. }
  444. /**
  445. * Calculate the magnitude (length) of the vector.
  446. *
  447. * @return the magnitude of the vector
  448. */
  449. public float length() {
  450. return (float) Math.sqrt(x*x + y*y + z*z);
  451. }
  452. /**
  453. * Calculates only the squared magnitude/length of the vector. Useful for
  454. * inverse square law applications and/or for speed reasons or if the real
  455. * eucledian distance is not required (e.g. sorting).
  456. *
  457. * @return squared magnitude (x^2 + y^2 + z^2)
  458. */
  459. public float lengthSquared() {
  460. return x * x + y * y + z * z;
  461. }
  462. /**
  463. * Calculate the cross product with another vector. And returns
  464. * a new vector as the result.
  465. *
  466. * @param v the v
  467. *
  468. * @return the cross product, a new vector
  469. */
  470. public Vector3D getCross(Vector3D v) {
  471. float crossX = y * v.getZ() - v.getY() * z;
  472. float crossY = z * v.getX() - v.getZ() * x;
  473. float crossZ = x * v.getY() - v.getX() * y;
  474. return new Vector3D(crossX,crossY,crossZ);
  475. }
  476. /**
  477. * Calcs the cross and sets the new values to this vector.
  478. *
  479. * @param v the v
  480. *
  481. * @return the Vector after the cross operation
  482. */
  483. public Vector3D crossLocal(Vector3D v) {
  484. float crossX = y * v.getZ() - v.getY() * z;
  485. float crossY = z * v.getX() - v.getZ() * x;
  486. float crossZ = x * v.getY() - v.getX() * y;
  487. this.setXYZ(crossX, crossY, crossZ);
  488. return this;
  489. }
  490. /**
  491. * Calculate the dot product with another vector.
  492. *
  493. * @param v the v
  494. *
  495. * @return the dot product
  496. */
  497. public float dot(Vector3D v) {
  498. return this.x * v.x + this.y * v.y + this.z * v.z;
  499. } //(x * v.x + y * v.y + z * v.z);
  500. /**
  501. * Normalize the vector to length 1 (make it a unit vector).
  502. *
  503. * @return the same vector after normalization
  504. */
  505. public Vector3D normalizeLocal() {
  506. // float m = length();
  507. // if (m > 0) {
  508. // this.setX(x / m);
  509. // this.setY(y / m);
  510. // this.setZ(z / m);
  511. // }
  512. float length = length();
  513. if (length != 0) {
  514. float scalar = length;
  515. scalar = 1f/scalar;
  516. x *= scalar;
  517. y *= scalar;
  518. z *= scalar;
  519. }
  520. return this;
  521. }
  522. /**
  523. * Normalize the vector to length 1 (make it a unit vector).
  524. *
  525. * @return a NEW vector after normalization of this vector
  526. */
  527. public Vector3D getNormalized() {
  528. Vector3D n = this;
  529. float length = length();
  530. if (length != 0) {
  531. float scalar = length;
  532. scalar = 1f/scalar;
  533. n = new Vector3D(this.x*scalar, this.y*scalar, this.z*scalar);
  534. }
  535. return n;
  536. }
  537. /**
  538. * Limits the vector to the given length .
  539. *
  540. * @param lim new maximum magnitude
  541. * @return the limited vector
  542. */
  543. public final Vector3D limitLocal(float lim) {
  544. if (this.lengthSquared() > lim * lim) {
  545. normalizeLocal();
  546. scaleLocal(lim);
  547. }
  548. return this;
  549. }
  550. /**
  551. * Creates a copy of the vector with its magnitude limited to the length
  552. * given.
  553. *
  554. * @param lim new maximum magnitude
  555. *
  556. * @return result as new vector
  557. */
  558. public final Vector3D getLimited(float lim) {
  559. if (this.lengthSquared() > lim * lim) {
  560. Vector3D norm = this.getCopy();
  561. norm.normalizeLocal();
  562. norm.scaleLocal(lim);
  563. return norm;
  564. }
  565. return new Vector3D(this);
  566. }
  567. /**
  568. * Rotates the vector around the giving axis.
  569. *
  570. * @param axis rotation axis vector
  571. * @param theta rotation angle (in radians)
  572. *
  573. * @return itself
  574. */
  575. public final Vector3D rotateAroundAxisLocal(Vector3D axis, float theta) {
  576. float ux = axis.x * x;
  577. float uy = axis.x * y;
  578. float uz = axis.x * z;
  579. float vx = axis.y * x;
  580. float vy = axis.y * y;
  581. float vz = axis.y * z;
  582. float wx = axis.z * x;
  583. float wy = axis.z * y;
  584. float wz = axis.z * z;
  585. double si = Math.sin(theta);
  586. double co = Math.cos(theta);
  587. float xx = (float) (axis.x
  588. * (ux + vy + wz)
  589. + (x * (axis.y * axis.y + axis.z * axis.z) - axis.x * (vy + wz))
  590. * co + (-wy + vz) * si);
  591. float yy = (float) (axis.y
  592. * (ux + vy + wz)
  593. + (y * (axis.x * axis.x + axis.z * axis.z) - axis.y * (ux + wz))
  594. * co + (wx - uz) * si);
  595. float zz = (float) (axis.z
  596. * (ux + vy + wz)
  597. + (z * (axis.x * axis.x + axis.y * axis.y) - axis.z * (ux + vy))
  598. * co + (-vx + uy) * si);
  599. x = xx;
  600. y = yy;
  601. z = zz;
  602. return this;
  603. }
  604. /**
  605. * Calculate the Euclidean distance between two points (considering a point as a vector object).
  606. *
  607. * @param v2 another vector
  608. * @param v1 the v1
  609. *
  610. * @return the Euclidean distance between v1 and v2
  611. */
  612. public static float distance (Vector3D v1, Vector3D v2) {
  613. float dx = v1.getX() - v2.getX();
  614. float dy = v1.getY() - v2.getY();
  615. float dz = v1.getZ() - v2.getZ();
  616. return (float) Math.sqrt(dx*dx + dy*dy + dz*dz);
  617. }
  618. /**
  619. * Calculate the Euclidean distance between two points (considering a point as a vector object).
  620. *
  621. * @param v2 the v2
  622. *
  623. * @return the float
  624. */
  625. public float distance(Vector3D v2){
  626. float dx = this.getX() - v2.getX();
  627. float dy = this.getY() - v2.getY();
  628. float dz = this.getZ() - v2.getZ();
  629. return (float) Math.sqrt(dx*dx + dy*dy + dz*dz);
  630. }
  631. /**
  632. * Calculate the Euclidean distance between two points (considering a point as a vector object).
  633. *
  634. * @param v2 another vector
  635. * @param v1 the v1
  636. *
  637. * @return the Euclidean distance between v1 and v2
  638. */
  639. public static float distance2D (Vector3D v1, Vector3D v2) {
  640. float dx = v1.getX() - v2.getX();
  641. float dy = v1.getY() - v2.getY();
  642. return (float) Math.sqrt(dx*dx + dy*dy );
  643. }
  644. /**
  645. * Calculate the Euclidean distance between two points (considering a point as a vector object).
  646. * Disregards the Z component of the vectors and is thus a little faster.
  647. *
  648. * @param v2 another vector
  649. *
  650. * @return the Euclidean distance between this and v2
  651. */
  652. public float distance2D (Vector3D v2) {
  653. float dx = this.getX() - v2.getX();
  654. float dy = this.getY() - v2.getY();
  655. return (float) Math.sqrt(dx*dx + dy*dy );
  656. }
  657. /**
  658. * Calculate the Euclidean distance between two points (considering a point as a vector object).
  659. *
  660. * @param v2 another vector
  661. * @param v1 the v1
  662. *
  663. * @return the Euclidean distance between v1 and v2 squared
  664. */
  665. public static float distanceSquared (Vector3D v1, Vector3D v2) {
  666. if (v2 != null) {
  667. float dx = v1.x - v2.x;
  668. float dy = v1.y - v2.y;
  669. float dz = v1.z - v2.z;
  670. return dx * dx + dy * dy + dz * dz;
  671. } else {
  672. return Float.NaN;
  673. }
  674. }
  675. /**
  676. * Calculate the angle between two vectors, using the dot product.
  677. *
  678. * @param v2 another vector
  679. * @param v1 the v1
  680. *
  681. * @return the angle between the vectors in radians
  682. */
  683. // FIXME this produces an not 0.0 angle for equal vectors sometimes..why?
  684. public static float angleBetween(Vector3D v1, Vector3D v2) {
  685. // Vector3D v1Copy = v1.getCopy();
  686. // Vector3D v2Copy = v2.getCopy();
  687. //
  688. // v1Copy.normalize();
  689. // v2Copy.normalize();
  690. //
  691. // float dotP = v1Copy.dot(v2Copy);
  692. // System.out.println("Dot:" + dotP);
  693. // float theta = (float)Math.acos(dotP);
  694. // float dot = v1.dot(v2);
  695. // float theta = FastMath.acos(dot / (v1.length() * v2.length()));
  696. // return theta;
  697. return v1.angleBetween(v2);
  698. }
  699. /**
  700. * Calculate the angle between two vectors, using the dot product.
  701. *
  702. * @param v2 another vector
  703. *
  704. * @return the angle between the vectors in radians
  705. */
  706. // FIXME this produces an not 0.0 angle for equal vectors sometimes..why?
  707. public float angleBetween(Vector3D v2) {
  708. float dot = this.dot(v2);
  709. float theta = ToolsMath.acos(dot / (this.length() * v2.length()));
  710. return theta;
  711. }
  712. /**
  713. * sets a new X coordinate value for the vector.
  714. *
  715. * @param x the x
  716. */
  717. public void setX(float x) {
  718. this.x = x;
  719. }
  720. /**
  721. * sets a new Y coordinate value for the vector.
  722. *
  723. * @param y the y
  724. */
  725. public void setY(float y) {
  726. this.y = y;
  727. }
  728. /**
  729. * sets a new Z coordinate value for the vector.
  730. *
  731. * @param z the z
  732. */
  733. public void setZ(float z) {
  734. this.z = z;
  735. }
  736. /**
  737. * sets new values for the vector.
  738. *
  739. * @param x the x
  740. * @param y the y
  741. * @param z the z
  742. */
  743. public void setXYZ(float x, float y, float z){
  744. this.x = x;
  745. this.y = y;
  746. this.z = z;
  747. }
  748. /**
  749. * sets new values for the vector.
  750. *
  751. * @param x the x
  752. * @param y the y
  753. * @param z the z
  754. * @param w the w
  755. */
  756. public void setXYZW(float x, float y, float z, float w){
  757. this.setXYZ(x, y, z);
  758. this.w = w;
  759. }
  760. /**
  761. * Converts the 3D homogenous vector to a 2D jawa.awt.point, throwing away the Z-Value
  762. *
  763. * @return the point
  764. */
  765. public Point getJava2DPoint(){
  766. return new Point(Math.round(x),Math.round(y));
  767. }
  768. /**
  769. * Gets the y.
  770. *
  771. * @return the Y value of the 3D Vector
  772. */
  773. public float getY(){
  774. return y;
  775. }
  776. /**
  777. * Gets the z.
  778. *
  779. * @return the Z value of the 3D Vector
  780. */
  781. public float getZ(){
  782. return z;
  783. }
  784. /**
  785. * Gets the x.
  786. *
  787. * @return the X value of the 3D Vector
  788. */
  789. public float getX(){
  790. return x;
  791. }
  792. /**
  793. * Gets the w.
  794. *
  795. * @return the W
  796. *
  797. * the W value of the 3D Vector
  798. */
  799. public float getW() {
  800. return w;
  801. }
  802. /**
  803. * Sets the w.
  804. *
  805. * @param w the new w
  806. */
  807. public void setW(float w) {
  808. this.w = w;
  809. }
  810. /**
  811. * Sets the.
  812. *
  813. * @param i the i
  814. * @param value the value
  815. */
  816. public void set(int i, float value){
  817. if (i == 0)
  818. x = value;
  819. else if(i == 1)
  820. y = value;
  821. else if(i == 2)
  822. z = value;
  823. else if(i == 3)
  824. w = value;
  825. else{
  826. System.err.println("illegal vector dimension");
  827. }
  828. }
  829. ///
  830. /**
  831. * Returns an integer in case of:
  832. * <br>VECTOR = 0;
  833. * <br>VERTEX = 1;
  834. * <br>BEZIERVERTEX = 2;.
  835. *
  836. * @return the type
  837. *
  838. * the integer identifying this object
  839. */
  840. public int getType() {
  841. return type;
  842. }
  843. /**
  844. * Sets the type. This should only be called
  845. * by extending classes to determine their type.
  846. *
  847. * @param type the type
  848. */
  849. protected void setType(int type) {
  850. this.type = type;
  851. }
  852. /**
  853. * Checks if the two vectors have the same components (XYZW).
  854. * <br>Does NOT check for object identity equality!
  855. *
  856. * @param vector3D the vector3 d
  857. *
  858. * @return true, if equals vector
  859. */
  860. public boolean equalsVector(Vector3D vector3D){
  861. return ( this.getX() == vector3D.getX()
  862. && this.getY() == vector3D.getY()
  863. && this.getZ() == vector3D.getZ()
  864. && this.getW() == vector3D.getW()
  865. );
  866. }
  867. /**
  868. * Checks if the two vectors have the same components (XYZW) in the range of a
  869. * specified tolerance.
  870. * <br>Does NOT check for object identity equality!
  871. * <br>NOTE: checks each component of the vector individually, so the overall difference
  872. * might be greater than the given tolerance!
  873. *
  874. * @param vec the vec
  875. * @param tolerance the tolerance
  876. *
  877. * @return true, if equals vector with tolerance
  878. */
  879. public boolean equalsVectorWithTolerance(Vector3D vec, float tolerance){
  880. return ( Math.abs(this.getX() - vec.getX()) <= tolerance
  881. && Math.abs(this.getY() - vec.getY()) <= tolerance
  882. && Math.abs(this.getZ() - vec.getZ()) <= tolerance
  883. && Math.abs(this.getW() - vec.getW()) <= tolerance
  884. );
  885. }
  886. /**
  887. * Saves this Vector3f into the given float[] object.
  888. *
  889. * @param floats The float[] to take this Vector3f. If null, a new float[3] is
  890. * created.
  891. *
  892. * @return The array, with X, Y, Z float values in that order
  893. */
  894. public float[] toArray(float[] floats) {
  895. if (floats == null) {
  896. floats = new float[3];
  897. }
  898. floats[0] = x;
  899. floats[1] = y;
  900. floats[2] = z;
  901. return floats;
  902. }
  903. /**
  904. * Sets the values of another vector.
  905. *
  906. * @param otherVector the new values
  907. *
  908. * @return the vector3 d
  909. */
  910. public Vector3D setValues(Vector3D otherVector){
  911. this.x = otherVector.x;
  912. this.y = otherVector.y;
  913. this.z = otherVector.z;
  914. this.w = otherVector.w;
  915. return this;
  916. }
  917. /* (non-Javadoc)
  918. * @see java.lang.Object#toString()
  919. */
  920. public String toString(){
  921. return " X:" + this.getX() + " Y:" + this.getY() + " Z:" + this.getZ() + " W:" + this.getW();
  922. }
  923. // //TODO CHECK IF THIS WORKS; TOO
  924. // /*
  925. // /**
  926. // * Transform the provided vector by the matrix and place it back in
  927. // * the vector.
  928. // *
  929. // * @param vec The vector to be transformed
  930. // * @param mat The matrix to do the transforming with
  931. // * @param out The vector to be put the result in
  932. // */
  933. // private void transform(Tuple3f vec, Matrix4f mat, Tuple3d out)
  934. // {
  935. // float a = vec.x;
  936. // float b = vec.y;
  937. // float c = vec.z;
  938. //
  939. // out.x = mat.m00 * a + mat.m01 * b + mat.m02 * c + mat.m03;
  940. // out.y = mat.m10 * a + mat.m11 * b + mat.m12 * c + mat.m13;
  941. // out.z = mat.m20 * a + mat.m21 * b + mat.m22 * c + mat.m23;
  942. // }
  943. //
  944. // /**
  945. // * Transform the provided vector by the matrix and place it back in
  946. // * the vector. The fourth element is assumed to be zero for normal
  947. // * transformations.
  948. // *
  949. // * @param vec The vector to be transformed
  950. // * @param mat The matrix to do the transforming with
  951. // * @param out The vector to be put the result in
  952. // */
  953. // private void transformNormal(Tuple3d vec, Matrix4f mat, Tuple3d out)
  954. // {
  955. // float a = (float)vec.x;
  956. // float b = (float)vec.y;
  957. // float c = (float)vec.z;
  958. //
  959. // out.x = mat.m00 * a + mat.m01 * b + mat.m02 * c;
  960. // out.y = mat.m10 * a + mat.m11 * b + mat.m12 * c;
  961. // out.z = mat.m20 * a + mat.m21 * b + mat.m22 * c;
  962. // }
  963. //
  964. // /**
  965. // * Transform the provided vector by the matrix and place it back in
  966. // * the vector. The fourth element is assumed to be zero for normal
  967. // * transformations.
  968. // *
  969. // * @param vec The vector to be transformed
  970. // * @param mat The matrix to do the transforming with
  971. // * @param out The vector to be put the result in
  972. // */
  973. // private void transformNormal(Tuple3f vec, Matrix4f mat, Tuple3d out)
  974. // {
  975. // float a = vec.x;
  976. // float b = vec.y;
  977. // float c = vec.z;
  978. //
  979. // out.x = mat.m00 * a + mat.m01 * b + mat.m02 * c;
  980. // out.y = mat.m10 * a + mat.m11 * b + mat.m12 * c;
  981. // out.z = mat.m20 * a + mat.m21 * b + mat.m22 * c;
  982. // }
  983. //}
  984. // */
  985. }