import Vector from '../../../math/Vector'; import Ray from '../../../utils/Ray'; import Steerable from '../../Steerable'; import RayConfigurationBase from './RayConfigurationBase'; /** * A {@code CentralRayWithWhiskersConfiguration} uses a long central ray and two shorter whiskers. *

* A central ray with short whiskers is often the best initial configuration to try but can make it impossible for the character * to move down tight passages. Also, it is still susceptible to the corner trap, far less than the parallel configuration though. * * @param Type of vector, either 2D or 3D, implementing the {@link Vector} interface * * @author davebaol */ class CentralRayWithWhiskersConfiguration> extends RayConfigurationBase { private rayLength: number; private whiskerLength: number; private whiskerAngle: number; /** * Creates a {@code CentralRayWithWhiskersConfiguration} for the given owner where the central ray has the specified length and * the two whiskers have the specified length and angle. * @param owner the owner of this configuration * @param rayLength the length of the central ray * @param whiskerLength the length of the two whiskers (usually shorter than the central ray) * @param whiskerAngle the angle in radians of the whiskers from the central ray */ public constructor(owner: Steerable, rayLength: number, whiskerLength: number, whiskerAngle: number) { super(owner, 3); this.rayLength = rayLength; this.whiskerLength = whiskerLength; this.whiskerAngle = whiskerAngle; } public updateRays(): Ray[] { const ownerPosition = this.owner.getPosition(); const ownerVelocity = this.owner.getLinearVelocity(); const velocityAngle = this.owner.vectorToAngle(ownerVelocity); // Update central ray this.rays[0].start.copy(ownerPosition); this.rays[0].end.copy(ownerVelocity).nor().scale(this.rayLength).add(ownerPosition); // Update left ray this.rays[1].start.copy(ownerPosition); this.owner.angleToVector(this.rays[1].end, velocityAngle - this.whiskerAngle).scale(this.whiskerLength).add(ownerPosition); // Update right ray this.rays[2].start.copy(ownerPosition); this.owner.angleToVector(this.rays[2].end, velocityAngle + this.whiskerAngle).scale(this.whiskerLength).add(ownerPosition); return this.rays; } /** Returns the length of the central ray. */ public getRayLength(): number { return this.rayLength; } /** Sets the length of the central ray. */ public setRayLength(rayLength: number): void { this.rayLength = rayLength; } /** Returns the length of the two whiskers. */ public getWhiskerLength(): number { return this.whiskerLength; } /** Sets the length of the two whiskers. */ public setWhiskerLength(whiskerLength: number): void { this.whiskerLength = whiskerLength; } /** Returns the angle in radians of the whiskers from the central ray. */ public getWhiskerAngle(): number { return this.whiskerAngle; } /** Sets the angle in radians of the whiskers from the central ray. */ public setWhiskerAngle(whiskerAngle: number): void { this.whiskerAngle = whiskerAngle; } } export default CentralRayWithWhiskersConfiguration;