1 /** 2 * Contains the definition of a Vector comprising 4 doubles and associated transformations. 3 * 4 * @author Richard Greenlees 5 * @author Kai Burjack 6 * @author F. Neurath 7 */ 8 module doml.vector_4d; 9 10 import Math = doml.math; 11 12 import doml.vector_4i; 13 import doml.vector_3d; 14 import doml.vector_3i; 15 import doml.vector_2d; 16 import doml.vector_2i; 17 18 import doml.matrix_4d; 19 import doml.matrix_4x3d; 20 21 import doml.quaternion_d; 22 23 /* 24 * The MIT License 25 * 26 * Copyright (c) 2015-2021 Richard Greenlees 27 ^%$^# Translated by jordan4ibanez 28 * 29 * Permission is hereby granted, free of charge, to any person obtaining a copy 30 * of this software and associated documentation files (the "Software"), to deal 31 * in the Software without restriction, including without limitation the rights 32 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 33 * copies of the Software, and to permit persons to whom the Software is 34 * furnished to do so, subject to the following conditions: 35 * 36 * The above copyright notice and this permission notice shall be included in 37 * all copies or substantial portions of the Software. 38 * 39 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 40 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 41 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 42 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 43 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 44 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 45 * THE SOFTWARE. 46 */ 47 48 /** 49 * Contains the definition of a Vector comprising 4 doubles and associated transformations. 50 * 51 * @author Richard Greenlees 52 * @author Kai Burjack 53 * @author F. Neurath 54 */ 55 struct Vector4d { 56 57 /** 58 * The x component of the vector. 59 */ 60 double x = 0.0; 61 /** 62 * The y component of the vector. 63 */ 64 double y = 0.0; 65 /** 66 * The z component of the vector. 67 */ 68 double z = 0.0; 69 /** 70 * The w component of the vector. 71 */ 72 double w = 1.0; 73 74 /** 75 * Create a new {@link Vector4d} with the same values as <code>v</code>. 76 * 77 * @param v 78 * the {@link Vector4d} to copy the values from 79 */ 80 this(Vector4d v) { 81 this.x = v.x; 82 this.y = v.y; 83 this.z = v.z; 84 this.w = v.w; 85 } 86 87 /** 88 * Create a new {@link Vector4d} with the same values as <code>v</code>. 89 * 90 * @param v 91 * the {@link Vector4i} to copy the values from 92 */ 93 this(Vector4i v) { 94 this.x = v.x; 95 this.y = v.y; 96 this.z = v.z; 97 this.w = v.w; 98 } 99 100 /** 101 * Create a new {@link Vector4d} with the first three components from the 102 * given <code>v</code> and the given <code>w</code>. 103 * 104 * @param v 105 * the {@link Vector3d} 106 * @param w 107 * the w component 108 */ 109 this(Vector3d v, double w) { 110 this.x = v.x; 111 this.y = v.y; 112 this.z = v.z; 113 this.w = w; 114 } 115 116 /** 117 * Create a new {@link Vector4d} with the first three components from the 118 * given <code>v</code> and the given <code>w</code>. 119 * 120 * @param v 121 * the {@link Vector3i} 122 * @param w 123 * the w component 124 */ 125 this(Vector3i v, double w) { 126 this.x = v.x; 127 this.y = v.y; 128 this.z = v.z; 129 this.w = w; 130 } 131 132 /** 133 * Create a new {@link Vector4d} with the first two components from the 134 * given <code>v</code> and the given <code>z</code> and <code>w</code>. 135 * 136 * @param v 137 * the {@link Vector2d} 138 * @param z 139 * the z component 140 * @param w 141 * the w component 142 */ 143 this(Vector2d v, double z, double w) { 144 this.x = v.x; 145 this.y = v.y; 146 this.z = z; 147 this.w = w; 148 } 149 150 /** 151 * Create a new {@link Vector4d} with the first two components from the 152 * given <code>v</code> and the given <code>z</code> and <code>w</code>. 153 * 154 * @param v 155 * the {@link Vector2i} 156 * @param z 157 * the z component 158 * @param w 159 * the w component 160 */ 161 this(Vector2i v, double z, double w) { 162 this.x = v.x; 163 this.y = v.y; 164 this.z = z; 165 this.w = w; 166 } 167 168 /** 169 * Create a new {@link Vector4d} and initialize all four components with the given value. 170 * 171 * @param d 172 * the value of all four components 173 */ 174 this(double d) { 175 this.x = d; 176 this.y = d; 177 this.z = d; 178 this.w = d; 179 } 180 181 /** 182 * Create a new {@link Vector4d} with the given component values. 183 * 184 * @param x 185 * the x component 186 * @param y 187 * the y component 188 * @param z 189 * the z component 190 * @param w 191 * the w component 192 */ 193 this(double x, double y, double z, double w) { 194 this.x = x; 195 this.y = y; 196 this.z = z; 197 this.w = w; 198 } 199 200 /** 201 * Create a new {@link Vector4d} and initialize its four components from the first 202 * four elements of the given array. 203 * 204 * @param xyzw 205 * the array containing at least four elements 206 */ 207 this(double[] xyzw) { 208 this.x = xyzw[0]; 209 this.y = xyzw[1]; 210 this.z = xyzw[2]; 211 this.w = xyzw[3]; 212 } 213 214 215 /** 216 * Set this {@link Vector4d} to the values of the given <code>v</code>. 217 * 218 * @param v 219 * the vector whose values will be copied into this 220 * @return this 221 */ 222 ref public Vector4d set(Vector4d v) return { 223 this.x = v.x; 224 this.y = v.y; 225 this.z = v.z; 226 this.w = v.w; 227 return this; 228 } 229 230 /** 231 * Set this {@link Vector4d} to the values of the given <code>v</code>. 232 * 233 * @param v 234 * the vector whose values will be copied into this 235 * @return this 236 */ 237 ref public Vector4d set(Vector4i v) return { 238 this.x = v.x; 239 this.y = v.y; 240 this.z = v.z; 241 this.w = v.w; 242 return this; 243 } 244 245 /** 246 * Set the x, y, and z components of this to the components of 247 * <code>v</code> and the w component to <code>w</code>. 248 * 249 * @param v 250 * the {@link Vector3d} to copy 251 * @param w 252 * the w component 253 * @return this 254 */ 255 ref public Vector4d set(Vector3d v, double w) return { 256 this.x = v.x; 257 this.y = v.y; 258 this.z = v.z; 259 this.w = w; 260 return this; 261 } 262 263 /** 264 * Set the x, y, and z components of this to the components of 265 * <code>v</code> and the w component to <code>w</code>. 266 * 267 * @param v 268 * the {@link Vector3i} to copy 269 * @param w 270 * the w component 271 * @return this 272 */ 273 ref public Vector4d set(Vector3i v, double w) return { 274 this.x = v.x; 275 this.y = v.y; 276 this.z = v.z; 277 this.w = w; 278 return this; 279 } 280 281 282 /** 283 * Set the x and y components from the given <code>v</code> 284 * and the z and w components to the given <code>z</code> and <code>w</code>. 285 * 286 * @param v 287 * the {@link Vector2d} 288 * @param z 289 * the z component 290 * @param w 291 * the w component 292 * @return this 293 */ 294 ref public Vector4d set(Vector2d v, double z, double w) return { 295 this.x = v.x; 296 this.y = v.y; 297 this.z = z; 298 this.w = w; 299 return this; 300 } 301 302 /** 303 * Set the x and y components from the given <code>v</code> 304 * and the z and w components to the given <code>z</code> and <code>w</code>. 305 * 306 * @param v 307 * the {@link Vector2i} 308 * @param z 309 * the z component 310 * @param w 311 * the w component 312 * @return this 313 */ 314 ref public Vector4d set(Vector2i v, double z, double w) return { 315 this.x = v.x; 316 this.y = v.y; 317 this.z = z; 318 this.w = w; 319 return this; 320 } 321 322 /** 323 * Set the x, y, z, and w components to the supplied value. 324 * 325 * @param d 326 * the value of all four components 327 * @return this 328 */ 329 ref public Vector4d set(double d) return { 330 this.x = d; 331 this.y = d; 332 this.z = d; 333 this.w = d; 334 return this; 335 } 336 337 /** 338 * Set the x, y, z, and w components to the supplied values. 339 * 340 * @param x 341 * the x component 342 * @param y 343 * the y component 344 * @param z 345 * the z component 346 * @param w 347 * the w component 348 * @return this 349 */ 350 ref public Vector4d set(double x, double y, double z, double w) return { 351 this.x = x; 352 this.y = y; 353 this.z = z; 354 this.w = w; 355 return this; 356 } 357 358 /** 359 * Set the x, y, z components to the supplied values. 360 * 361 * @param x 362 * the x component 363 * @param y 364 * the y component 365 * @param z 366 * the z component 367 * @return this 368 */ 369 ref public Vector4d set(double x, double y, double z) return { 370 this.x = x; 371 this.y = y; 372 this.z = z; 373 return this; 374 } 375 376 /** 377 * Set the four components of this vector to the first four elements of the given array. 378 * 379 * @param xyzw 380 * the array containing at least four elements 381 * @return this 382 */ 383 ref public Vector4d set(double[] xyzw) return { 384 this.x = xyzw[0]; 385 this.y = xyzw[1]; 386 this.z = xyzw[2]; 387 this.w = xyzw[3]; 388 return this; 389 } 390 391 392 /** 393 * Set the value of the specified component of this vector. 394 * 395 * @param component 396 * the component whose value to set, within <code>[0..3]</code> 397 * @param value 398 * the value to set 399 * @return this 400 * @throws IllegalArgumentException if <code>component</code> is not within <code>[0..3]</code> 401 */ 402 ref public Vector4d setComponent(int component, double value) return { 403 switch (component) { 404 case 0: 405 x = value; 406 break; 407 case 1: 408 y = value; 409 break; 410 case 2: 411 z = value; 412 break; 413 case 3: 414 w = value; 415 break; 416 default: {} 417 } 418 return this; 419 } 420 421 /** 422 * Subtract the supplied vector from this one. 423 * 424 * @param v 425 * the vector to subtract 426 * @return this 427 */ 428 ref public Vector4d sub(Vector4d v) return { 429 this.x = x - v.x; 430 this.y = y - v.y; 431 this.z = z - v.z; 432 this.w = w - v.w; 433 return this; 434 } 435 436 /** 437 * Subtract the supplied vector from this one and store the result in <code>dest</code>. 438 * 439 * @param v 440 * the vector to subtract 441 * @param dest 442 * will hold the result 443 * @return dest 444 */ 445 public Vector4d sub(Vector4d v, ref Vector4d dest) { 446 dest.x = x - v.x; 447 dest.y = y - v.y; 448 dest.z = z - v.z; 449 dest.w = w - v.w; 450 return dest; 451 } 452 453 /** 454 * Subtract <code>(x, y, z, w)</code> from this. 455 * 456 * @param x 457 * the x component to subtract 458 * @param y 459 * the y component to subtract 460 * @param z 461 * the z component to subtract 462 * @param w 463 * the w component to subtract 464 * @return this 465 */ 466 ref public Vector4d sub(double x, double y, double z, double w) return { 467 this.x = this.x - x; 468 this.y = this.y - y; 469 this.z = this.z - z; 470 this.w = this.w - w; 471 return this; 472 } 473 474 public Vector4d sub(double x, double y, double z, double w, ref Vector4d dest) { 475 dest.x = this.x - x; 476 dest.y = this.y - y; 477 dest.z = this.z - z; 478 dest.w = this.w - w; 479 return dest; 480 } 481 482 /** 483 * Add the supplied vector to this one. 484 * 485 * @param v 486 * the vector to add 487 * @return this 488 */ 489 ref public Vector4d add(Vector4d v) return { 490 this.x = x + v.x; 491 this.y = y + v.y; 492 this.z = z + v.z; 493 this.w = w + v.w; 494 return this; 495 } 496 497 public Vector4d add(Vector4d v, ref Vector4d dest) { 498 dest.x = x + v.x; 499 dest.y = y + v.y; 500 dest.z = z + v.z; 501 dest.w = w + v.w; 502 return dest; 503 } 504 505 /** 506 * Add <code>(x, y, z, w)</code> to this. 507 * 508 * @param x 509 * the x component to add 510 * @param y 511 * the y component to add 512 * @param z 513 * the z component to add 514 * @param w 515 * the w component to add 516 * @return this 517 */ 518 ref public Vector4d add(double x, double y, double z, double w) return { 519 this.x = this.x + x; 520 this.y = this.y + y; 521 this.z = this.z + z; 522 this.w = this.w + w; 523 return this; 524 } 525 526 public Vector4d add(double x, double y, double z, double w, ref Vector4d dest) { 527 dest.x = this.x + x; 528 dest.y = this.y + y; 529 dest.z = this.z + z; 530 dest.w = this.w + w; 531 return dest; 532 } 533 534 /** 535 * Add the component-wise multiplication of <code>a * b</code> to this vector. 536 * 537 * @param a 538 * the first multiplicand 539 * @param b 540 * the second multiplicand 541 * @return this 542 */ 543 ref public Vector4d fma(Vector4d a, Vector4d b) return { 544 this.x = Math.fma(a.x, b.x, x); 545 this.y = Math.fma(a.y, b.y, y); 546 this.z = Math.fma(a.z, b.z, z); 547 this.w = Math.fma(a.w, b.w, w); 548 return this; 549 } 550 551 /** 552 * Add the component-wise multiplication of <code>a * b</code> to this vector. 553 * 554 * @param a 555 * the first multiplicand 556 * @param b 557 * the second multiplicand 558 * @return this 559 */ 560 ref public Vector4d fma(double a, Vector4d b) return { 561 this.x = Math.fma(a, b.x, x); 562 this.y = Math.fma(a, b.y, y); 563 this.z = Math.fma(a, b.z, z); 564 this.w = Math.fma(a, b.w, w); 565 return this; 566 } 567 568 public Vector4d fma(Vector4d a, Vector4d b, ref Vector4d dest) { 569 dest.x = Math.fma(a.x, b.x, x); 570 dest.y = Math.fma(a.y, b.y, y); 571 dest.z = Math.fma(a.z, b.z, z); 572 dest.w = Math.fma(a.w, b.w, w); 573 return dest; 574 } 575 576 public Vector4d fma(double a, Vector4d b, ref Vector4d dest) { 577 dest.x = Math.fma(a, b.x, x); 578 dest.y = Math.fma(a, b.y, y); 579 dest.z = Math.fma(a, b.z, z); 580 dest.w = Math.fma(a, b.w, w); 581 return dest; 582 } 583 584 /** 585 * Add the component-wise multiplication of <code>this * a</code> to <code>b</code> 586 * and store the result in <code>this</code>. 587 * 588 * @param a 589 * the multiplicand 590 * @param b 591 * the addend 592 * @return this 593 */ 594 ref public Vector4d mulAdd(Vector4d a, Vector4d b) return { 595 this.x = Math.fma(x, a.x, b.x); 596 this.y = Math.fma(y, a.y, b.y); 597 this.z = Math.fma(z, a.z, b.z); 598 return this; 599 } 600 601 /** 602 * Add the component-wise multiplication of <code>this * a</code> to <code>b</code> 603 * and store the result in <code>this</code>. 604 * 605 * @param a 606 * the multiplicand 607 * @param b 608 * the addend 609 * @return this 610 */ 611 ref public Vector4d mulAdd(double a, Vector4d b) return { 612 this.x = Math.fma(x, a, b.x); 613 this.y = Math.fma(y, a, b.y); 614 this.z = Math.fma(z, a, b.z); 615 return this; 616 } 617 618 public Vector4d mulAdd(Vector4d a, Vector4d b, ref Vector4d dest) { 619 dest.x = Math.fma(x, a.x, b.x); 620 dest.y = Math.fma(y, a.y, b.y); 621 dest.z = Math.fma(z, a.z, b.z); 622 return dest; 623 } 624 625 public Vector4d mulAdd(double a, Vector4d b, ref Vector4d dest) { 626 dest.x = Math.fma(x, a, b.x); 627 dest.y = Math.fma(y, a, b.y); 628 dest.z = Math.fma(z, a, b.z); 629 return dest; 630 } 631 632 /** 633 * Multiply this {@link Vector4d} component-wise by the given {@link Vector4d}. 634 * 635 * @param v 636 * the vector to multiply by 637 * @return this 638 */ 639 ref public Vector4d mul(Vector4d v) return { 640 this.x = x * v.x; 641 this.y = y * v.y; 642 this.z = z * v.z; 643 this.w = w * v.w; 644 return this; 645 } 646 647 public Vector4d mul(Vector4d v, ref Vector4d dest) { 648 dest.x = x * v.x; 649 dest.y = y * v.y; 650 dest.z = z * v.z; 651 dest.w = w * v.w; 652 return dest; 653 } 654 655 /** 656 * Divide this {@link Vector4d} component-wise by the given {@link Vector4d}. 657 * 658 * @param v 659 * the vector to divide by 660 * @return this 661 */ 662 ref public Vector4d div(Vector4d v) return { 663 this.x = x / v.x; 664 this.y = y / v.y; 665 this.z = z / v.z; 666 this.w = w / v.w; 667 return this; 668 } 669 670 public Vector4d div(Vector4d v, ref Vector4d dest) { 671 dest.x = x / v.x; 672 dest.y = y / v.y; 673 dest.z = z / v.z; 674 dest.w = w / v.w; 675 return dest; 676 } 677 678 /** 679 * Multiply the given matrix <code>mat</code> with this {@link Vector4d}. 680 * 681 * @param mat 682 * the matrix to multiply by 683 * @return this 684 */ 685 ref public Vector4d mul(Matrix4d mat) return { 686 if ((mat.properties & Matrix4d.PROPERTY_AFFINE) != 0) 687 mulAffine(mat, this); 688 else 689 mulGeneric(mat, this); 690 return this; 691 } 692 693 public Vector4d mul(Matrix4d mat, ref Vector4d dest) { 694 if ((mat.properties & Matrix4d.PROPERTY_AFFINE) != 0) 695 return mulAffine(mat, dest); 696 return mulGeneric(mat, dest); 697 } 698 699 /** 700 * Multiply the transpose of the given matrix <code>mat</code> with this Vector4f and store the result in 701 * <code>this</code>. 702 * 703 * @param mat 704 * the matrix whose transpose to multiply the vector with 705 * @return this 706 */ 707 ref public Vector4d mulTranspose(Matrix4d mat) return { 708 if ((mat.properties & Matrix4d.PROPERTY_AFFINE) != 0) 709 mulAffineTranspose(mat, this); 710 else 711 mulGenericTranspose(mat, this); 712 return this; 713 } 714 public Vector4d mulTranspose(Matrix4d mat, ref Vector4d dest) { 715 if ((mat.properties & Matrix4d.PROPERTY_AFFINE) != 0) 716 return mulAffineTranspose(mat, dest); 717 return mulGenericTranspose(mat, dest); 718 } 719 720 public Vector4d mulAffine(Matrix4d mat, ref Vector4d dest) { 721 double rx = Math.fma(mat.m00, x, Math.fma(mat.m10, y, Math.fma(mat.m20, z, mat.m30 * w))); 722 double ry = Math.fma(mat.m01, x, Math.fma(mat.m11, y, Math.fma(mat.m21, z, mat.m31 * w))); 723 double rz = Math.fma(mat.m02, x, Math.fma(mat.m12, y, Math.fma(mat.m22, z, mat.m32 * w))); 724 dest.x = rx; 725 dest.y = ry; 726 dest.z = rz; 727 dest.w = w; 728 return dest; 729 } 730 731 private Vector4d mulGeneric(Matrix4d mat, ref Vector4d dest) { 732 double rx = Math.fma(mat.m00, x, Math.fma(mat.m10, y, Math.fma(mat.m20, z, mat.m30 * w))); 733 double ry = Math.fma(mat.m01, x, Math.fma(mat.m11, y, Math.fma(mat.m21, z, mat.m31 * w))); 734 double rz = Math.fma(mat.m02, x, Math.fma(mat.m12, y, Math.fma(mat.m22, z, mat.m32 * w))); 735 double rw = Math.fma(mat.m03, x, Math.fma(mat.m13, y, Math.fma(mat.m23, z, mat.m33 * w))); 736 dest.x = rx; 737 dest.y = ry; 738 dest.z = rz; 739 dest.w = rw; 740 return dest; 741 } 742 743 public Vector4d mulAffineTranspose(Matrix4d mat, ref Vector4d dest) { 744 double x = this.x, y = this.y, z = this.z, w = this.w; 745 dest.x = Math.fma(mat.m00, x, Math.fma(mat.m01, y, mat.m02 * z)); 746 dest.y = Math.fma(mat.m10, x, Math.fma(mat.m11, y, mat.m12 * z)); 747 dest.z = Math.fma(mat.m20, x, Math.fma(mat.m21, y, mat.m22 * z)); 748 dest.w = Math.fma(mat.m30, x, Math.fma(mat.m31, y, mat.m32 * z + w)); 749 return dest; 750 } 751 private Vector4d mulGenericTranspose(Matrix4d mat, ref Vector4d dest) { 752 double x = this.x, y = this.y, z = this.z, w = this.w; 753 dest.x = Math.fma(mat.m00, x, Math.fma(mat.m01, y, Math.fma(mat.m02, z, mat.m03 * w))); 754 dest.y = Math.fma(mat.m10, x, Math.fma(mat.m11, y, Math.fma(mat.m12, z, mat.m13 * w))); 755 dest.z = Math.fma(mat.m20, x, Math.fma(mat.m21, y, Math.fma(mat.m22, z, mat.m23 * w))); 756 dest.w = Math.fma(mat.m30, x, Math.fma(mat.m31, y, Math.fma(mat.m32, z, mat.m33 * w))); 757 return dest; 758 } 759 760 /** 761 * Multiply the given matrix mat with this Vector4d and store the result in 762 * <code>this</code>. 763 * 764 * @param mat 765 * the matrix to multiply the vector with 766 * @return this 767 */ 768 ref public Vector4d mul(Matrix4x3d mat) return { 769 double rx = Math.fma(mat.m00, x, Math.fma(mat.m10, y, Math.fma(mat.m20, z, mat.m30 * w))); 770 double ry = Math.fma(mat.m01, x, Math.fma(mat.m11, y, Math.fma(mat.m21, z, mat.m31 * w))); 771 double rz = Math.fma(mat.m02, x, Math.fma(mat.m12, y, Math.fma(mat.m22, z, mat.m32 * w))); 772 this.x = rx; 773 this.y = ry; 774 this.z = rz; 775 return this; 776 } 777 778 public Vector4d mul(Matrix4x3d mat, ref Vector4d dest) { 779 double rx = Math.fma(mat.m00, x, Math.fma(mat.m10, y, Math.fma(mat.m20, z, mat.m30 * w))); 780 double ry = Math.fma(mat.m01, x, Math.fma(mat.m11, y, Math.fma(mat.m21, z, mat.m31 * w))); 781 double rz = Math.fma(mat.m02, x, Math.fma(mat.m12, y, Math.fma(mat.m22, z, mat.m32 * w))); 782 dest.x = rx; 783 dest.y = ry; 784 dest.z = rz; 785 dest.w = w; 786 return dest; 787 } 788 789 public Vector4d mulProject(Matrix4d mat, ref Vector4d dest) { 790 double invW = 1.0 / Math.fma(mat.m03, x, Math.fma(mat.m13, y, Math.fma(mat.m23, z, mat.m33 * w))); 791 double rx = Math.fma(mat.m00, x, Math.fma(mat.m10, y, Math.fma(mat.m20, z, mat.m30 * w))) * invW; 792 double ry = Math.fma(mat.m01, x, Math.fma(mat.m11, y, Math.fma(mat.m21, z, mat.m31 * w))) * invW; 793 double rz = Math.fma(mat.m02, x, Math.fma(mat.m12, y, Math.fma(mat.m22, z, mat.m32 * w))) * invW; 794 dest.x = rx; 795 dest.y = ry; 796 dest.z = rz; 797 dest.w = 1.0; 798 return dest; 799 } 800 801 /** 802 * Multiply the given matrix <code>mat</code> with this Vector4d, perform perspective division. 803 * 804 * @param mat 805 * the matrix to multiply this vector by 806 * @return this 807 */ 808 ref public Vector4d mulProject(Matrix4d mat) return { 809 double invW = 1.0 / Math.fma(mat.m03, x, Math.fma(mat.m13, y, Math.fma(mat.m23, z, mat.m33 * w))); 810 double rx = Math.fma(mat.m00, x, Math.fma(mat.m10, y, Math.fma(mat.m20, z, mat.m30 * w))) * invW; 811 double ry = Math.fma(mat.m01, x, Math.fma(mat.m11, y, Math.fma(mat.m21, z, mat.m31 * w))) * invW; 812 double rz = Math.fma(mat.m02, x, Math.fma(mat.m12, y, Math.fma(mat.m22, z, mat.m32 * w))) * invW; 813 this.x = rx; 814 this.y = ry; 815 this.z = rz; 816 this.w = 1.0; 817 return this; 818 } 819 820 public Vector3d mulProject(Matrix4d mat, ref Vector3d dest) { 821 double invW = 1.0 / Math.fma(mat.m03, x, Math.fma(mat.m13, y, Math.fma(mat.m23, z, mat.m33 * w))); 822 double rx = Math.fma(mat.m00, x, Math.fma(mat.m10, y, Math.fma(mat.m20, z, mat.m30 * w))) * invW; 823 double ry = Math.fma(mat.m01, x, Math.fma(mat.m11, y, Math.fma(mat.m21, z, mat.m31 * w))) * invW; 824 double rz = Math.fma(mat.m02, x, Math.fma(mat.m12, y, Math.fma(mat.m22, z, mat.m32 * w))) * invW; 825 dest.x = rx; 826 dest.y = ry; 827 dest.z = rz; 828 return dest; 829 } 830 831 /** 832 * Multiply this Vector4d by the given scalar value. 833 * 834 * @param scalar 835 * the scalar to multiply by 836 * @return this 837 */ 838 ref public Vector4d mul(double scalar) return { 839 this.x = x * scalar; 840 this.y = y * scalar; 841 this.z = z * scalar; 842 this.w = w * scalar; 843 return this; 844 } 845 846 public Vector4d mul(double scalar, ref Vector4d dest) { 847 dest.x = x * scalar; 848 dest.y = y * scalar; 849 dest.z = z * scalar; 850 dest.w = w * scalar; 851 return dest; 852 } 853 854 /** 855 * Divide this Vector4d by the given scalar value. 856 * 857 * @param scalar 858 * the scalar to divide by 859 * @return this 860 */ 861 ref public Vector4d div(double scalar) return { 862 double inv = 1.0 / scalar; 863 this.x = x * inv; 864 this.y = y * inv; 865 this.z = z * inv; 866 this.w = w * inv; 867 return this; 868 } 869 870 public Vector4d div(double scalar, ref Vector4d dest) { 871 double inv = 1.0 / scalar; 872 dest.x = x * inv; 873 dest.y = y * inv; 874 dest.z = z * inv; 875 dest.w = w * inv; 876 return dest; 877 } 878 879 /** 880 * Transform this vector by the given quaternion <code>quat</code> and store the result in <code>this</code>. 881 * 882 * @see Quaterniond#transform(Vector4d) 883 * 884 * @param quat 885 * the quaternion to transform this vector 886 * @return this 887 */ 888 ref public Vector4d rotate(Quaterniond quat) return { 889 quat.transform(this, this); 890 return this; 891 } 892 893 public Vector4d rotate(Quaterniond quat, ref Vector4d dest) { 894 quat.transform(this, dest); 895 return dest; 896 } 897 898 /** 899 * Rotate this vector the specified radians around the given rotation axis. 900 * 901 * @param angle 902 * the angle in radians 903 * @param x 904 * the x component of the rotation axis 905 * @param y 906 * the y component of the rotation axis 907 * @param z 908 * the z component of the rotation axis 909 * @return this 910 */ 911 ref public Vector4d rotateAxis(double angle, double x, double y, double z) return { 912 if (y == 0.0 && z == 0.0 && Math.absEqualsOne(x)) 913 rotateX(x * angle, this); 914 else if (x == 0.0 && z == 0.0 && Math.absEqualsOne(y)) 915 rotateY(y * angle, this); 916 else if (x == 0.0 && y == 0.0 && Math.absEqualsOne(z)) 917 rotateZ(z * angle, this); 918 else 919 rotateAxisInternal(angle, x, y, z, this); 920 return this; 921 } 922 923 public Vector4d rotateAxis(double angle, double aX, double aY, double aZ, ref Vector4d dest) { 924 if (aY == 0.0 && aZ == 0.0 && Math.absEqualsOne(aX)) 925 return rotateX(aX * angle, dest); 926 else if (aX == 0.0 && aZ == 0.0 && Math.absEqualsOne(aY)) 927 return rotateY(aY * angle, dest); 928 else if (aX == 0.0 && aY == 0.0 && Math.absEqualsOne(aZ)) 929 return rotateZ(aZ * angle, dest); 930 return rotateAxisInternal(angle, aX, aY, aZ, dest); 931 } 932 private Vector4d rotateAxisInternal(double angle, double aX, double aY, double aZ, ref Vector4d dest) { 933 double hangle = angle * 0.5; 934 double sinAngle = Math.sin(hangle); 935 double qx = aX * sinAngle, qy = aY * sinAngle, qz = aZ * sinAngle; 936 double qw = Math.cosFromSin(sinAngle, hangle); 937 double w2 = qw * qw, x2 = qx * qx, y2 = qy * qy, z2 = qz * qz, zw = qz * qw; 938 double xy = qx * qy, xz = qx * qz, yw = qy * qw, yz = qy * qz, xw = qx * qw; 939 double nx = (w2 + x2 - z2 - y2) * x + (-zw + xy - zw + xy) * y + (yw + xz + xz + yw) * z; 940 double ny = (xy + zw + zw + xy) * x + ( y2 - z2 + w2 - x2) * y + (yz + yz - xw - xw) * z; 941 double nz = (xz - yw + xz - yw) * x + ( yz + yz + xw + xw) * y + (z2 - y2 - x2 + w2) * z; 942 dest.x = nx; 943 dest.y = ny; 944 dest.z = nz; 945 return dest; 946 } 947 948 /** 949 * Rotate this vector the specified radians around the X axis. 950 * 951 * @param angle 952 * the angle in radians 953 * @return this 954 */ 955 ref public Vector4d rotateX(double angle) return { 956 double sin = Math.sin(angle), cos = Math.cosFromSin(sin, angle); 957 double y = this.y * cos - this.z * sin; 958 double z = this.y * sin + this.z * cos; 959 this.y = y; 960 this.z = z; 961 return this; 962 } 963 964 public Vector4d rotateX(double angle, ref Vector4d dest) { 965 double sin = Math.sin(angle), cos = Math.cosFromSin(sin, angle); 966 double y = this.y * cos - this.z * sin; 967 double z = this.y * sin + this.z * cos; 968 dest.x = this.x; 969 dest.y = y; 970 dest.z = z; 971 dest.w = this.w; 972 return dest; 973 } 974 975 /** 976 * Rotate this vector the specified radians around the Y axis. 977 * 978 * @param angle 979 * the angle in radians 980 * @return this 981 */ 982 ref public Vector4d rotateY(double angle) return { 983 double sin = Math.sin(angle), cos = Math.cosFromSin(sin, angle); 984 double x = this.x * cos + this.z * sin; 985 double z = -this.x * sin + this.z * cos; 986 this.x = x; 987 this.z = z; 988 return this; 989 } 990 991 public Vector4d rotateY(double angle, ref Vector4d dest) { 992 double sin = Math.sin(angle), cos = Math.cosFromSin(sin, angle); 993 double x = this.x * cos + this.z * sin; 994 double z = -this.x * sin + this.z * cos; 995 dest.x = x; 996 dest.y = this.y; 997 dest.z = z; 998 dest.w = this.w; 999 return dest; 1000 } 1001 1002 /** 1003 * Rotate this vector the specified radians around the Z axis. 1004 * 1005 * @param angle 1006 * the angle in radians 1007 * @return this 1008 */ 1009 ref public Vector4d rotateZ(double angle) return { 1010 double sin = Math.sin(angle), cos = Math.cosFromSin(sin, angle); 1011 double x = this.x * cos - this.y * sin; 1012 double y = this.x * sin + this.y * cos; 1013 this.x = x; 1014 this.y = y; 1015 return this; 1016 } 1017 1018 public Vector4d rotateZ(double angle, ref Vector4d dest) { 1019 double sin = Math.sin(angle), cos = Math.cosFromSin(sin, angle); 1020 double x = this.x * cos - this.y * sin; 1021 double y = this.x * sin + this.y * cos; 1022 dest.x = x; 1023 dest.y = y; 1024 dest.z = this.z; 1025 dest.w = this.w; 1026 return dest; 1027 } 1028 1029 public double lengthSquared() { 1030 return Math.fma(x, x, Math.fma(y, y, Math.fma(z, z, w * w))); 1031 } 1032 1033 /** 1034 * Get the length squared of a 4-dimensional double-precision vector. 1035 * 1036 * @param x The vector's x component 1037 * @param y The vector's y component 1038 * @param z The vector's z component 1039 * @param w The vector's w component 1040 * 1041 * @return the length squared of the given vector 1042 * 1043 * @author F. Neurath 1044 */ 1045 public static double lengthSquared(double x, double y, double z, double w) { 1046 return Math.fma(x, x, Math.fma(y, y, Math.fma(z, z, w * w))); 1047 } 1048 1049 public double length() { 1050 return Math.sqrt(Math.fma(x, x, Math.fma(y, y, Math.fma(z, z, w * w)))); 1051 } 1052 1053 /** 1054 * Get the length of a 4-dimensional double-precision vector. 1055 * 1056 * @param x The vector's x component 1057 * @param y The vector's y component 1058 * @param z The vector's z component 1059 * @param w The vector's w component 1060 * 1061 * @return the length of the given vector 1062 * 1063 * @author F. Neurath 1064 */ 1065 public static double length(double x, double y, double z, double w) { 1066 return Math.sqrt(Math.fma(x, x, Math.fma(y, y, Math.fma(z, z, w * w)))); 1067 } 1068 1069 /** 1070 * Normalizes this vector. 1071 * 1072 * @return this 1073 */ 1074 ref public Vector4d normalize() return { 1075 double invLength = 1.0 / length(); 1076 this.x = x * invLength; 1077 this.y = y * invLength; 1078 this.z = z * invLength; 1079 this.w = w * invLength; 1080 return this; 1081 } 1082 1083 public Vector4d normalize(ref Vector4d dest) { 1084 double invLength = 1.0 / length(); 1085 dest.x = x * invLength; 1086 dest.y = y * invLength; 1087 dest.z = z * invLength; 1088 dest.w = w * invLength; 1089 return dest; 1090 } 1091 1092 /** 1093 * Scale this vector to have the given length. 1094 * 1095 * @param length 1096 * the desired length 1097 * @return this 1098 */ 1099 ref public Vector4d normalize(double length) return { 1100 double invLength = 1.0 / this.length * length; 1101 this.x = x * invLength; 1102 this.y = y * invLength; 1103 this.z = z * invLength; 1104 this.w = w * invLength; 1105 return this; 1106 } 1107 1108 public Vector4d normalize(double length, ref Vector4d dest) { 1109 double invLength = 1.0 / this.length * length; 1110 dest.x = x * invLength; 1111 dest.y = y * invLength; 1112 dest.z = z * invLength; 1113 dest.w = w * invLength; 1114 return dest; 1115 } 1116 1117 /** 1118 * Normalize this vector by computing only the norm of <code>(x, y, z)</code>. 1119 * 1120 * @return this 1121 */ 1122 ref public Vector4d normalize3() return { 1123 double invLength = Math.invsqrt(Math.fma(x, x, Math.fma(y, y, z * z))); 1124 this.x = x * invLength; 1125 this.y = y * invLength; 1126 this.z = z * invLength; 1127 this.w = w * invLength; 1128 return this; 1129 } 1130 1131 public Vector4d normalize3(ref Vector4d dest) { 1132 double invLength = Math.invsqrt(Math.fma(x, x, Math.fma(y, y, z * z))); 1133 dest.x = x * invLength; 1134 dest.y = y * invLength; 1135 dest.z = z * invLength; 1136 dest.w = w * invLength; 1137 return dest; 1138 } 1139 1140 public double distance(Vector4d v) { 1141 double dx = this.x - v.x; 1142 double dy = this.y - v.y; 1143 double dz = this.z - v.z; 1144 double dw = this.w - v.w; 1145 return Math.sqrt(Math.fma(dx, dx, Math.fma(dy, dy, Math.fma(dz, dz, dw * dw)))); 1146 } 1147 1148 public double distance(double x, double y, double z, double w) { 1149 double dx = this.x - x; 1150 double dy = this.y - y; 1151 double dz = this.z - z; 1152 double dw = this.w - w; 1153 return Math.sqrt(Math.fma(dx, dx, Math.fma(dy, dy, Math.fma(dz, dz, dw * dw)))); 1154 } 1155 1156 public double distanceSquared(Vector4d v) { 1157 double dx = this.x - v.x; 1158 double dy = this.y - v.y; 1159 double dz = this.z - v.z; 1160 double dw = this.w - v.w; 1161 return Math.fma(dx, dx, Math.fma(dy, dy, Math.fma(dz, dz, dw * dw))); 1162 } 1163 1164 public double distanceSquared(double x, double y, double z, double w) { 1165 double dx = this.x - x; 1166 double dy = this.y - y; 1167 double dz = this.z - z; 1168 double dw = this.w - w; 1169 return Math.fma(dx, dx, Math.fma(dy, dy, Math.fma(dz, dz, dw * dw))); 1170 } 1171 1172 /** 1173 * Return the distance between <code>(x1, y1, z1, w1)</code> and <code>(x2, y2, z2, w2)</code>. 1174 * 1175 * @param x1 1176 * the x component of the first vector 1177 * @param y1 1178 * the y component of the first vector 1179 * @param z1 1180 * the z component of the first vector 1181 * @param w1 1182 * the w component of the first vector 1183 * @param x2 1184 * the x component of the second vector 1185 * @param y2 1186 * the y component of the second vector 1187 * @param z2 1188 * the z component of the second vector 1189 * @param w2 1190 * the 2 component of the second vector 1191 * @return the euclidean distance 1192 */ 1193 public static double distance(double x1, double y1, double z1, double w1, double x2, double y2, double z2, double w2) { 1194 double dx = x1 - x2; 1195 double dy = y1 - y2; 1196 double dz = z1 - z2; 1197 double dw = w1 - w2; 1198 return Math.sqrt(Math.fma(dx, dx, Math.fma(dy, dy, Math.fma(dz, dz, dw * dw)))); 1199 } 1200 1201 /** 1202 * Return the squared distance between <code>(x1, y1, z1, w1)</code> and <code>(x2, y2, z2, w2)</code>. 1203 * 1204 * @param x1 1205 * the x component of the first vector 1206 * @param y1 1207 * the y component of the first vector 1208 * @param z1 1209 * the z component of the first vector 1210 * @param w1 1211 * the w component of the first vector 1212 * @param x2 1213 * the x component of the second vector 1214 * @param y2 1215 * the y component of the second vector 1216 * @param z2 1217 * the z component of the second vector 1218 * @param w2 1219 * the w component of the second vector 1220 * @return the euclidean distance squared 1221 */ 1222 public static double distanceSquared(double x1, double y1, double z1, double w1, double x2, double y2, double z2, double w2) { 1223 double dx = x1 - x2; 1224 double dy = y1 - y2; 1225 double dz = z1 - z2; 1226 double dw = w1 - w2; 1227 return Math.fma(dx, dx, Math.fma(dy, dy, Math.fma(dz, dz, dw * dw))); 1228 } 1229 1230 public double dot(Vector4d v) { 1231 return Math.fma(this.x, v.x, Math.fma(this.y, v.y, Math.fma(this.z, v.z, this.w * v.w))); 1232 } 1233 1234 public double dot(double x, double y, double z, double w) { 1235 return Math.fma(this.x, x, Math.fma(this.y, y, Math.fma(this.z, z, this.w * w))); 1236 } 1237 1238 public double angleCos(Vector4d v) { 1239 double length1Squared = Math.fma(x, x, Math.fma(y, y, Math.fma(z, z, w * w))); 1240 double length2Squared = Math.fma(v.x, v.x, Math.fma(v.y, v.y, Math.fma(v.z, v.z, v.w * v.w))); 1241 double dot = Math.fma(x, v.x, Math.fma(y, v.y, Math.fma(z, v.z, w * v.w))); 1242 return dot / Math.sqrt(length1Squared * length2Squared); 1243 } 1244 1245 public double angle(Vector4d v) { 1246 double cos = angleCos(v); 1247 // This is because sometimes cos goes above 1 or below -1 because of lost precision 1248 cos = cos < 1 ? cos : 1; 1249 cos = cos > -1 ? cos : -1; 1250 return Math.acos(cos); 1251 } 1252 1253 /** 1254 * Set all components to zero. 1255 * 1256 * @return this 1257 */ 1258 ref public Vector4d zero() return { 1259 this.x = 0; 1260 this.y = 0; 1261 this.z = 0; 1262 this.w = 0; 1263 return this; 1264 } 1265 1266 /** 1267 * Negate this vector. 1268 * 1269 * @return this 1270 */ 1271 ref public Vector4d negate() return { 1272 this.x = -x; 1273 this.y = -y; 1274 this.z = -z; 1275 this.w = -w; 1276 return this; 1277 } 1278 1279 public Vector4d negate(ref Vector4d dest) { 1280 dest.x = -x; 1281 dest.y = -y; 1282 dest.z = -z; 1283 dest.w = -w; 1284 return dest; 1285 } 1286 1287 /** 1288 * Set the components of this vector to be the component-wise minimum of this and the other vector. 1289 * 1290 * @param v 1291 * the other vector 1292 * @return this 1293 */ 1294 ref public Vector4d min(Vector4d v) return { 1295 this.x = x < v.x ? x : v.x; 1296 this.y = y < v.y ? y : v.y; 1297 this.z = z < v.z ? z : v.z; 1298 this.w = w < v.w ? w : v.w; 1299 return this; 1300 } 1301 1302 public Vector4d min(Vector4d v, ref Vector4d dest) { 1303 dest.x = x < v.x ? x : v.x; 1304 dest.y = y < v.y ? y : v.y; 1305 dest.z = z < v.z ? z : v.z; 1306 dest.w = w < v.w ? w : v.w; 1307 return dest; 1308 } 1309 1310 /** 1311 * Set the components of this vector to be the component-wise maximum of this and the other vector. 1312 * 1313 * @param v 1314 * the other vector 1315 * @return this 1316 */ 1317 ref public Vector4d max(Vector4d v) return { 1318 this.x = x > v.x ? x : v.x; 1319 this.y = y > v.y ? y : v.y; 1320 this.z = z > v.z ? z : v.z; 1321 this.w = w > v.w ? w : v.w; 1322 return this; 1323 } 1324 1325 public Vector4d max(Vector4d v, ref Vector4d dest) { 1326 dest.x = x > v.x ? x : v.x; 1327 dest.y = y > v.y ? y : v.y; 1328 dest.z = z > v.z ? z : v.z; 1329 dest.w = w > v.w ? w : v.w; 1330 return dest; 1331 } 1332 1333 public int hashCode() { 1334 immutable int prime = 31; 1335 int result = 1; 1336 long temp; 1337 temp = Math.doubleToLongBits(w); 1338 result = prime * result + cast(int) (temp ^ (temp >>> 32)); 1339 temp = Math.doubleToLongBits(x); 1340 result = prime * result + cast(int) (temp ^ (temp >>> 32)); 1341 temp = Math.doubleToLongBits(y); 1342 result = prime * result + cast(int) (temp ^ (temp >>> 32)); 1343 temp = Math.doubleToLongBits(z); 1344 result = prime * result + cast(int) (temp ^ (temp >>> 32)); 1345 return result; 1346 } 1347 1348 1349 public bool equals(Vector4d v, double delta) { 1350 if (this == v) 1351 return true; 1352 if (!Math.equals(x, v.x, delta)) 1353 return false; 1354 if (!Math.equals(y, v.y, delta)) 1355 return false; 1356 if (!Math.equals(z, v.z, delta)) 1357 return false; 1358 if (!Math.equals(w, v.w, delta)) 1359 return false; 1360 return true; 1361 } 1362 1363 public bool equals(Vector4d other) { 1364 if (this == other) 1365 return true; 1366 if (!this.x == other.x) 1367 return false; 1368 if (!this.y == other.y) 1369 return false; 1370 if (!this.z == other.z) 1371 return false; 1372 if (!this.w == other.w) 1373 return false; 1374 return true; 1375 } 1376 1377 public bool equals(double x, double y, double z, double w) { 1378 if (Math.doubleToLongBits(this.x) != Math.doubleToLongBits(x)) 1379 return false; 1380 if (Math.doubleToLongBits(this.y) != Math.doubleToLongBits(y)) 1381 return false; 1382 if (Math.doubleToLongBits(this.z) != Math.doubleToLongBits(z)) 1383 return false; 1384 if (Math.doubleToLongBits(this.w) != Math.doubleToLongBits(w)) 1385 return false; 1386 return true; 1387 } 1388 1389 public Vector4d smoothStep(Vector4d v, double t, ref Vector4d dest) { 1390 double t2 = t * t; 1391 double t3 = t2 * t; 1392 dest.x = (x + x - v.x - v.x) * t3 + (3.0 * v.x - 3.0 * x) * t2 + x * t + x; 1393 dest.y = (y + y - v.y - v.y) * t3 + (3.0 * v.y - 3.0 * y) * t2 + y * t + y; 1394 dest.z = (z + z - v.z - v.z) * t3 + (3.0 * v.z - 3.0 * z) * t2 + z * t + z; 1395 dest.w = (w + w - v.w - v.w) * t3 + (3.0 * v.w - 3.0 * w) * t2 + w * t + w; 1396 return dest; 1397 } 1398 1399 public Vector4d hermite(Vector4d t0, Vector4d v1, Vector4d t1, double t, ref Vector4d dest) { 1400 double t2 = t * t; 1401 double t3 = t2 * t; 1402 dest.x = (x + x - v1.x - v1.x + t1.x + t0.x) * t3 + (3.0 * v1.x - 3.0 * x - t0.x - t0.x - t1.x) * t2 + x * t + x; 1403 dest.y = (y + y - v1.y - v1.y + t1.y + t0.y) * t3 + (3.0 * v1.y - 3.0 * y - t0.y - t0.y - t1.y) * t2 + y * t + y; 1404 dest.z = (z + z - v1.z - v1.z + t1.z + t0.z) * t3 + (3.0 * v1.z - 3.0 * z - t0.z - t0.z - t1.z) * t2 + z * t + z; 1405 dest.w = (w + w - v1.w - v1.w + t1.w + t0.w) * t3 + (3.0 * v1.w - 3.0 * w - t0.w - t0.w - t1.w) * t2 + w * t + w; 1406 return dest; 1407 } 1408 1409 /** 1410 * Linearly interpolate <code>this</code> and <code>other</code> using the given interpolation factor <code>t</code> 1411 * and store the result in <code>this</code>. 1412 * <p> 1413 * If <code>t</code> is <code>0.0</code> then the result is <code>this</code>. If the interpolation factor is <code>1.0</code> 1414 * then the result is <code>other</code>. 1415 * 1416 * @param other 1417 * the other vector 1418 * @param t 1419 * the interpolation factor between 0.0 and 1.0 1420 * @return this 1421 */ 1422 ref public Vector4d lerp(Vector4d other, double t) return { 1423 this.x = Math.fma(other.x - x, t, x); 1424 this.y = Math.fma(other.y - y, t, y); 1425 this.z = Math.fma(other.z - z, t, z); 1426 this.w = Math.fma(other.w - w, t, w); 1427 return this; 1428 } 1429 1430 public Vector4d lerp(Vector4d other, double t, ref Vector4d dest) { 1431 dest.x = Math.fma(other.x - x, t, x); 1432 dest.y = Math.fma(other.y - y, t, y); 1433 dest.z = Math.fma(other.z - z, t, z); 1434 dest.w = Math.fma(other.w - w, t, w); 1435 return dest; 1436 } 1437 1438 public double get(int component) { 1439 switch (component) { 1440 case 0: 1441 return x; 1442 case 1: 1443 return y; 1444 case 2: 1445 return z; 1446 case 3: 1447 return w; 1448 default: 1449 return 0; // do nothing 1450 } 1451 } 1452 1453 public Vector4i get(int mode, ref Vector4i dest) { 1454 dest.x = Math.roundUsing(this.x, mode); 1455 dest.y = Math.roundUsing(this.y, mode); 1456 dest.z = Math.roundUsing(this.z, mode); 1457 dest.w = Math.roundUsing(this.w, mode); 1458 return dest; 1459 } 1460 1461 public Vector4d get(ref Vector4d dest) { 1462 dest.x = this.x; 1463 dest.y = this.y; 1464 dest.z = this.z; 1465 dest.w = this.w; 1466 return dest; 1467 } 1468 1469 public int maxComponent() { 1470 double absX = Math.abs(x); 1471 double absY = Math.abs(y); 1472 double absZ = Math.abs(z); 1473 double absW = Math.abs(w); 1474 if (absX >= absY && absX >= absZ && absX >= absW) { 1475 return 0; 1476 } else if (absY >= absZ && absY >= absW) { 1477 return 1; 1478 } else if (absZ >= absW) { 1479 return 2; 1480 } 1481 return 3; 1482 } 1483 1484 public int minComponent() { 1485 double absX = Math.abs(x); 1486 double absY = Math.abs(y); 1487 double absZ = Math.abs(z); 1488 double absW = Math.abs(w); 1489 if (absX < absY && absX < absZ && absX < absW) { 1490 return 0; 1491 } else if (absY < absZ && absY < absW) { 1492 return 1; 1493 } else if (absZ < absW) { 1494 return 2; 1495 } 1496 return 3; 1497 } 1498 1499 /** 1500 * Set each component of this vector to the largest (closest to positive 1501 * infinity) {@code double} value that is less than or equal to that 1502 * component and is equal to a mathematical integer. 1503 * 1504 * @return this 1505 */ 1506 ref public Vector4d floor() return { 1507 this.x = Math.floor(x); 1508 this.y = Math.floor(y); 1509 this.z = Math.floor(z); 1510 this.w = Math.floor(w); 1511 return this; 1512 } 1513 1514 public Vector4d floor(ref Vector4d dest) { 1515 dest.x = Math.floor(x); 1516 dest.y = Math.floor(y); 1517 dest.z = Math.floor(z); 1518 dest.w = Math.floor(w); 1519 return dest; 1520 } 1521 1522 /** 1523 * Set each component of this vector to the smallest (closest to negative 1524 * infinity) {@code double} value that is greater than or equal to that 1525 * component and is equal to a mathematical integer. 1526 * 1527 * @return this 1528 */ 1529 ref public Vector4d ceil() return { 1530 this.x = Math.ceil(x); 1531 this.y = Math.ceil(y); 1532 this.z = Math.ceil(z); 1533 this.w = Math.ceil(w); 1534 return this; 1535 } 1536 1537 public Vector4d ceil(ref Vector4d dest) { 1538 dest.x = Math.ceil(x); 1539 dest.y = Math.ceil(y); 1540 dest.z = Math.ceil(z); 1541 dest.w = Math.ceil(w); 1542 return dest; 1543 } 1544 1545 /** 1546 * Set each component of this vector to the closest double that is equal to 1547 * a mathematical integer, with ties rounding to positive infinity. 1548 * 1549 * @return this 1550 */ 1551 ref public Vector4d round() return { 1552 this.x = Math.round(x); 1553 this.y = Math.round(y); 1554 this.z = Math.round(z); 1555 this.w = Math.round(w); 1556 return this; 1557 } 1558 1559 public Vector4d round(ref Vector4d dest) { 1560 dest.x = Math.round(x); 1561 dest.y = Math.round(y); 1562 dest.z = Math.round(z); 1563 dest.w = Math.round(w); 1564 return dest; 1565 } 1566 1567 public bool isFinite() { 1568 return Math.isFinite(x) && Math.isFinite(y) && Math.isFinite(z) && Math.isFinite(w); 1569 } 1570 1571 /** 1572 * Compute the absolute of each of this vector's components. 1573 * 1574 * @return this 1575 */ 1576 ref public Vector4d absolute() return { 1577 this.x = Math.abs(x); 1578 this.y = Math.abs(y); 1579 this.z = Math.abs(z); 1580 this.w = Math.abs(w); 1581 return this; 1582 } 1583 1584 public Vector4d absolute(ref Vector4d dest) { 1585 dest.x = Math.abs(x); 1586 dest.y = Math.abs(y); 1587 dest.z = Math.abs(z); 1588 dest.w = Math.abs(w); 1589 return dest; 1590 } 1591 }