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