add rotation utils
This commit is contained in:
parent
7969bdb706
commit
c7a3580f9f
|
|
@ -104,4 +104,35 @@ export class Vector {
|
||||||
y: a.y + (b.y - a.y) * t,
|
y: a.y + (b.y - a.y) * t,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotates a vector by a given angle (in radians)
|
||||||
|
* @param {Point} v - The vector to rotate
|
||||||
|
* @param {number} angle - The angle in radians
|
||||||
|
* @returns {Point} The rotated vector
|
||||||
|
*/
|
||||||
|
static rotate(v: Point, angle: number): Point {
|
||||||
|
const cos = Math.cos(angle);
|
||||||
|
const sin = Math.sin(angle);
|
||||||
|
return {
|
||||||
|
x: v.x * cos - v.y * sin,
|
||||||
|
y: v.x * sin + v.y * cos,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rotates a point around a pivot point by a given angle (in radians)
|
||||||
|
* @param {Point} point - The point to rotate
|
||||||
|
* @param {Point} pivot - The point to rotate around
|
||||||
|
* @param {number} angle - The angle in radians
|
||||||
|
* @returns {Point} The rotated point
|
||||||
|
*/
|
||||||
|
static rotateAround(point: Point, pivot: Point, angle: number): Point {
|
||||||
|
// Translate to origin
|
||||||
|
const translated = Vector.sub(point, pivot);
|
||||||
|
// Rotate around origin
|
||||||
|
const rotated = Vector.rotate(translated, angle);
|
||||||
|
// Translate back
|
||||||
|
return Vector.add(rotated, pivot);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,23 @@
|
||||||
import { css, html } from './common/tags';
|
import { css, html } from './common/tags';
|
||||||
import { ResizeObserverManager } from './common/resize-observer';
|
import { ResizeObserverManager } from './common/resize-observer';
|
||||||
import type { Point } from './common/types';
|
import type { Point } from './common/types';
|
||||||
|
import { Vector } from './common/Vector';
|
||||||
|
|
||||||
const resizeObserver = new ResizeObserverManager();
|
const resizeObserver = new ResizeObserverManager();
|
||||||
|
|
||||||
export type Shape = 'rectangle' | 'circle' | 'triangle';
|
export type Shape = 'rectangle' | 'circle' | 'triangle';
|
||||||
|
|
||||||
type RotatedDOMRect = DOMRect & {
|
type RotatedDOMRect = DOMRect & {
|
||||||
// In degrees
|
/** in degrees */
|
||||||
rotation: number;
|
rotation: number;
|
||||||
|
|
||||||
// Returns the center point in worldspace coordinates
|
/** Returns the center point in worldspace coordinates */
|
||||||
center(): Point;
|
center(): Point;
|
||||||
|
|
||||||
// Returns the four corners in worldspace coordinates, in clockwise order
|
/** Returns the four corners in worldspace coordinates, in clockwise order */
|
||||||
corners(): [Point, Point, Point, Point];
|
corners(): [Point, Point, Point, Point];
|
||||||
|
|
||||||
// Returns all the vertices in worldspace coordinates
|
/** Returns all the vertices in worldspace coordinates */
|
||||||
vertices(): Point[];
|
vertices(): Point[];
|
||||||
};
|
};
|
||||||
export type MoveEventDetail = { movementX: number; movementY: number };
|
export type MoveEventDetail = { movementX: number; movementY: number };
|
||||||
|
|
@ -322,26 +323,16 @@ export class FolkShape extends HTMLElement {
|
||||||
return [];
|
return [];
|
||||||
},
|
},
|
||||||
|
|
||||||
corners(): [Point, Point, Point, Point] {
|
corners() {
|
||||||
const center = this.center();
|
const center = this.center();
|
||||||
const cos = Math.cos(radians);
|
const radians = (this.rotation * Math.PI) / 180;
|
||||||
const sin = Math.sin(radians);
|
const { x, y, width, height } = this;
|
||||||
|
|
||||||
const halfWidth = this.width / 2;
|
|
||||||
const halfHeight = this.height / 2;
|
|
||||||
|
|
||||||
// Helper to rotate a point around the center
|
|
||||||
const rotatePoint = (dx: number, dy: number): Point => ({
|
|
||||||
x: center.x + dx * cos - dy * sin,
|
|
||||||
y: center.y + dx * sin + dy * cos,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Return vertices in clockwise order: top-left, top-right, bottom-right, bottom-left
|
|
||||||
return [
|
return [
|
||||||
rotatePoint(-halfWidth, -halfHeight), // Top-left
|
Vector.rotateAround({ x, y }, center, radians),
|
||||||
rotatePoint(halfWidth, -halfHeight), // Top-right
|
Vector.rotateAround({ x: x + width, y }, center, radians),
|
||||||
rotatePoint(halfWidth, halfHeight), // Bottom-right
|
Vector.rotateAround({ x: x + width, y: y + height }, center, radians),
|
||||||
rotatePoint(-halfWidth, halfHeight), // Bottom-left
|
Vector.rotateAround({ x, y: y + height }, center, radians),
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue