EllipseCurve.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. import { Curve } from '../core/Curve.js';
  2. import { Vector2 } from '../../math/Vector2.js';
  3. class EllipseCurve extends Curve {
  4. constructor( aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation ) {
  5. super();
  6. this.type = 'EllipseCurve';
  7. this.isEllipseCurve = true;
  8. this.aX = aX || 0;
  9. this.aY = aY || 0;
  10. this.xRadius = xRadius || 1;
  11. this.yRadius = yRadius || 1;
  12. this.aStartAngle = aStartAngle || 0;
  13. this.aEndAngle = aEndAngle || 2 * Math.PI;
  14. this.aClockwise = aClockwise || false;
  15. this.aRotation = aRotation || 0;
  16. }
  17. getPoint( t, optionalTarget ) {
  18. const point = optionalTarget || new Vector2();
  19. const twoPi = Math.PI * 2;
  20. let deltaAngle = this.aEndAngle - this.aStartAngle;
  21. const samePoints = Math.abs( deltaAngle ) < Number.EPSILON;
  22. // ensures that deltaAngle is 0 .. 2 PI
  23. while ( deltaAngle < 0 ) deltaAngle += twoPi;
  24. while ( deltaAngle > twoPi ) deltaAngle -= twoPi;
  25. if ( deltaAngle < Number.EPSILON ) {
  26. if ( samePoints ) {
  27. deltaAngle = 0;
  28. } else {
  29. deltaAngle = twoPi;
  30. }
  31. }
  32. if ( this.aClockwise === true && ! samePoints ) {
  33. if ( deltaAngle === twoPi ) {
  34. deltaAngle = - twoPi;
  35. } else {
  36. deltaAngle = deltaAngle - twoPi;
  37. }
  38. }
  39. const angle = this.aStartAngle + t * deltaAngle;
  40. let x = this.aX + this.xRadius * Math.cos( angle );
  41. let y = this.aY + this.yRadius * Math.sin( angle );
  42. if ( this.aRotation !== 0 ) {
  43. const cos = Math.cos( this.aRotation );
  44. const sin = Math.sin( this.aRotation );
  45. const tx = x - this.aX;
  46. const ty = y - this.aY;
  47. // Rotate the point about the center of the ellipse.
  48. x = tx * cos - ty * sin + this.aX;
  49. y = tx * sin + ty * cos + this.aY;
  50. }
  51. return point.set( x, y );
  52. }
  53. copy( source ) {
  54. super.copy( source );
  55. this.aX = source.aX;
  56. this.aY = source.aY;
  57. this.xRadius = source.xRadius;
  58. this.yRadius = source.yRadius;
  59. this.aStartAngle = source.aStartAngle;
  60. this.aEndAngle = source.aEndAngle;
  61. this.aClockwise = source.aClockwise;
  62. this.aRotation = source.aRotation;
  63. return this;
  64. }
  65. toJSON() {
  66. const data = super.toJSON();
  67. data.aX = this.aX;
  68. data.aY = this.aY;
  69. data.xRadius = this.xRadius;
  70. data.yRadius = this.yRadius;
  71. data.aStartAngle = this.aStartAngle;
  72. data.aEndAngle = this.aEndAngle;
  73. data.aClockwise = this.aClockwise;
  74. data.aRotation = this.aRotation;
  75. return data;
  76. }
  77. fromJSON( json ) {
  78. super.fromJSON( json );
  79. this.aX = json.aX;
  80. this.aY = json.aY;
  81. this.xRadius = json.xRadius;
  82. this.yRadius = json.yRadius;
  83. this.aStartAngle = json.aStartAngle;
  84. this.aEndAngle = json.aEndAngle;
  85. this.aClockwise = json.aClockwise;
  86. this.aRotation = json.aRotation;
  87. return this;
  88. }
  89. }
  90. export { EllipseCurve };