157 lines
2.7 KiB
JavaScript
157 lines
2.7 KiB
JavaScript
|
import { Curve } from '../core/Curve.js';
|
||
|
import { Vector2 } from '../../math/Vector2.js';
|
||
|
|
||
|
class EllipseCurve extends Curve {
|
||
|
|
||
|
constructor( aX = 0, aY = 0, xRadius = 1, yRadius = 1, aStartAngle = 0, aEndAngle = Math.PI * 2, aClockwise = false, aRotation = 0 ) {
|
||
|
|
||
|
super();
|
||
|
|
||
|
this.type = 'EllipseCurve';
|
||
|
|
||
|
this.aX = aX;
|
||
|
this.aY = aY;
|
||
|
|
||
|
this.xRadius = xRadius;
|
||
|
this.yRadius = yRadius;
|
||
|
|
||
|
this.aStartAngle = aStartAngle;
|
||
|
this.aEndAngle = aEndAngle;
|
||
|
|
||
|
this.aClockwise = aClockwise;
|
||
|
|
||
|
this.aRotation = aRotation;
|
||
|
|
||
|
}
|
||
|
|
||
|
getPoint( t, optionalTarget ) {
|
||
|
|
||
|
const point = optionalTarget || new Vector2();
|
||
|
|
||
|
const twoPi = Math.PI * 2;
|
||
|
let deltaAngle = this.aEndAngle - this.aStartAngle;
|
||
|
const samePoints = Math.abs( deltaAngle ) < Number.EPSILON;
|
||
|
|
||
|
// ensures that deltaAngle is 0 .. 2 PI
|
||
|
while ( deltaAngle < 0 ) deltaAngle += twoPi;
|
||
|
while ( deltaAngle > twoPi ) deltaAngle -= twoPi;
|
||
|
|
||
|
if ( deltaAngle < Number.EPSILON ) {
|
||
|
|
||
|
if ( samePoints ) {
|
||
|
|
||
|
deltaAngle = 0;
|
||
|
|
||
|
} else {
|
||
|
|
||
|
deltaAngle = twoPi;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
if ( this.aClockwise === true && ! samePoints ) {
|
||
|
|
||
|
if ( deltaAngle === twoPi ) {
|
||
|
|
||
|
deltaAngle = - twoPi;
|
||
|
|
||
|
} else {
|
||
|
|
||
|
deltaAngle = deltaAngle - twoPi;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
const angle = this.aStartAngle + t * deltaAngle;
|
||
|
let x = this.aX + this.xRadius * Math.cos( angle );
|
||
|
let y = this.aY + this.yRadius * Math.sin( angle );
|
||
|
|
||
|
if ( this.aRotation !== 0 ) {
|
||
|
|
||
|
const cos = Math.cos( this.aRotation );
|
||
|
const sin = Math.sin( this.aRotation );
|
||
|
|
||
|
const tx = x - this.aX;
|
||
|
const ty = y - this.aY;
|
||
|
|
||
|
// Rotate the point about the center of the ellipse.
|
||
|
x = tx * cos - ty * sin + this.aX;
|
||
|
y = tx * sin + ty * cos + this.aY;
|
||
|
|
||
|
}
|
||
|
|
||
|
return point.set( x, y );
|
||
|
|
||
|
}
|
||
|
|
||
|
copy( source ) {
|
||
|
|
||
|
super.copy( source );
|
||
|
|
||
|
this.aX = source.aX;
|
||
|
this.aY = source.aY;
|
||
|
|
||
|
this.xRadius = source.xRadius;
|
||
|
this.yRadius = source.yRadius;
|
||
|
|
||
|
this.aStartAngle = source.aStartAngle;
|
||
|
this.aEndAngle = source.aEndAngle;
|
||
|
|
||
|
this.aClockwise = source.aClockwise;
|
||
|
|
||
|
this.aRotation = source.aRotation;
|
||
|
|
||
|
return this;
|
||
|
|
||
|
}
|
||
|
|
||
|
toJSON() {
|
||
|
|
||
|
const data = super.toJSON();
|
||
|
|
||
|
data.aX = this.aX;
|
||
|
data.aY = this.aY;
|
||
|
|
||
|
data.xRadius = this.xRadius;
|
||
|
data.yRadius = this.yRadius;
|
||
|
|
||
|
data.aStartAngle = this.aStartAngle;
|
||
|
data.aEndAngle = this.aEndAngle;
|
||
|
|
||
|
data.aClockwise = this.aClockwise;
|
||
|
|
||
|
data.aRotation = this.aRotation;
|
||
|
|
||
|
return data;
|
||
|
|
||
|
}
|
||
|
|
||
|
fromJSON( json ) {
|
||
|
|
||
|
super.fromJSON( json );
|
||
|
|
||
|
this.aX = json.aX;
|
||
|
this.aY = json.aY;
|
||
|
|
||
|
this.xRadius = json.xRadius;
|
||
|
this.yRadius = json.yRadius;
|
||
|
|
||
|
this.aStartAngle = json.aStartAngle;
|
||
|
this.aEndAngle = json.aEndAngle;
|
||
|
|
||
|
this.aClockwise = json.aClockwise;
|
||
|
|
||
|
this.aRotation = json.aRotation;
|
||
|
|
||
|
return this;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
EllipseCurve.prototype.isEllipseCurve = true;
|
||
|
|
||
|
export { EllipseCurve };
|