remove beed for "normalize"

This commit is contained in:
Jörn-Michael Miehe 2023-01-23 14:38:49 +00:00
parent 47d7815067
commit 33b8a66b23
3 changed files with 81 additions and 68 deletions

View file

@ -13,7 +13,7 @@
@dblclick.left="remove_rect" @dblclick.left="remove_rect"
> >
<Rect <Rect
v-for="(rect, index) in rectangles_array" v-for="(rect, index) in rectangles"
:key="'rect' + index" :key="'rect' + index"
:rectangle="rect" :rectangle="rect"
/> />
@ -56,35 +56,24 @@ export default class RectPad extends Vue {
private dragging = false; private dragging = false;
private drag_rect?: Rectangle; private drag_rect?: Rectangle;
private drag_origin = new Vector2D(); private drag_origin = new Vector2D();
private rectangles_array: Rectangle[] = []; public rectangles: Rectangle[] = [];
private get preview_visible(): boolean { private get preview_visible(): boolean {
return this.drawing || this.dragging; return this.drawing || this.dragging;
} }
private get preview_rectangle(): Rectangle { private get preview_rectangle(): Rectangle {
return new Rectangle( return new Rectangle(this.preview_corner1, this.preview_corner2);
this.preview_corner1,
this.preview_corner2
).normalize();
}
public get rectangles(): Rectangle[] {
return this.rectangles_array; //.map((rect) => rect.normalize());
}
public set rectangles(rects: Rectangle[]) {
this.rectangles_array = rects; //.map((rect) => rect.normalize());
} }
private pop_rectangle(point: Vector2D): Rectangle | undefined { private pop_rectangle(point: Vector2D): Rectangle | undefined {
const idx = this.rectangles_array.findIndex((rect) => rect.contains(point)); const idx = this.rectangles.findIndex((rect) => rect.contains(point));
if (idx === -1) { if (idx === -1) {
return; return;
} }
return this.rectangles_array.splice(idx, 1)[0]; return this.rectangles.splice(idx, 1)[0];
} }
private draw_start(event: MouseEvent) { private draw_start(event: MouseEvent) {
@ -108,7 +97,7 @@ export default class RectPad extends Vue {
return; return;
} }
this.rectangles_array.push(this.preview_rectangle); this.rectangles.push(this.preview_rectangle);
} }
private drag_start(event: MouseEvent) { private drag_start(event: MouseEvent) {
@ -136,7 +125,7 @@ export default class RectPad extends Vue {
} }
this.dragging = false; this.dragging = false;
this.rectangles_array.push(this.preview_rectangle); this.rectangles.push(this.preview_rectangle);
} }
private on_mousemove(event: MouseEvent) { private on_mousemove(event: MouseEvent) {

View file

@ -1,39 +1,34 @@
export class Vector2D { export class Vector2D {
private _x: number; public readonly x: number;
private _y: number; public readonly y: number;
constructor(x = 0, y = 0) { constructor(x = 0, y = 0) {
this._x = x; this.x = x;
this._y = y; this.y = y;
}
public get x(): number {
return this._x;
}
public get y(): number {
return this._y;
} }
public plus(other: Vector2D): Vector2D { public plus(other: Vector2D): Vector2D {
return new Vector2D(this._x + other._x, this._y + other._y); return new Vector2D(this.x + other.x, this.y + other.y);
} }
public minus(other: Vector2D): Vector2D { public minus(other: Vector2D): Vector2D {
return new Vector2D(this._x - other._x, this._y - other._y); return new Vector2D(this.x - other.x, this.y - other.y);
} }
} }
export class Rectangle { export class Rectangle {
private _corner_1: Vector2D; private readonly corner_1: Vector2D;
private _corner_2: Vector2D; private readonly corner_2: Vector2D;
constructor(corner_1: Vector2D, corner_2: Vector2D) { constructor(corner_1: Vector2D, corner_2: Vector2D) {
this._corner_1 = corner_1; this.corner_1 = corner_1;
this._corner_2 = corner_2; this.corner_2 = corner_2;
} }
public get origin(): Vector2D { public get origin(): Vector2D {
return this._corner_1; return new Vector2D(
Math.min(this.corner_1.x, this.corner_2.x),
Math.min(this.corner_1.y, this.corner_2.y),
)
} }
public get left(): number { public get left(): number {
@ -45,11 +40,14 @@ export class Rectangle {
} }
public get corner(): Vector2D { public get corner(): Vector2D {
return this._corner_2; return new Vector2D(
Math.max(this.corner_1.x, this.corner_2.x),
Math.max(this.corner_1.y, this.corner_2.y),
)
} }
public get size(): Vector2D { public get size(): Vector2D {
return this._corner_2.minus(this._corner_1); return this.corner.minus(this.origin);
} }
public get width(): number { public get width(): number {
@ -65,33 +63,9 @@ export class Rectangle {
} }
public contains(point: Vector2D): boolean { public contains(point: Vector2D): boolean {
const test_rect = this.normalize(); return point.x >= this.origin.x &&
point.y >= this.origin.y &&
return point.x >= test_rect._corner_1.x && point.x <= this.corner.x &&
point.y >= test_rect._corner_1.y && point.y <= this.corner.y
point.x <= test_rect._corner_2.x &&
point.y <= test_rect._corner_2.y
}
public normalize(): Rectangle {
let left = this.left;
let top = this.top;
let width = this.width;
let height = this.height;
if (width < 0) {
width *= -1;
left -= width;
}
if (height < 0) {
height *= -1;
top -= height;
}
const corner_tl = new Vector2D(left, top);
const size = new Vector2D(width, height);
return new Rectangle(corner_tl, corner_tl.plus(size));
} }
} }

View file

@ -1,4 +1,4 @@
import { Vector2D } from '@/components/rects/rectangles'; import { Rectangle, Vector2D } from '@/components/rects/rectangles';
import { expect } from "chai"; import { expect } from "chai";
describe("Vector Tests", () => { describe("Vector Tests", () => {
@ -21,3 +21,53 @@ describe("Vector Tests", () => {
expect(v2.y).to.equal(-2); expect(v2.y).to.equal(-2);
}); });
}); });
describe("Vector Tests", () => {
const v1 = new Vector2D(1, 2);
const v2 = new Vector2D(4, 6);
const r1 = new Rectangle(v1, v2);
const r2 = new Rectangle(v2, v1);
it("should create a rectangle", () => {
expect(r1.left).to.equal(1);
expect(r1.top).to.equal(2);
expect(r1.width).to.equal(3);
expect(r1.height).to.equal(4);
});
it("should create the same rectangle backwards", () => {
expect(r2.left).to.equal(1);
expect(r2.top).to.equal(2);
expect(r2.width).to.equal(3);
expect(r2.height).to.equal(4);
});
it("should create the same rectangle transposed", () => {
const v1t = new Vector2D(v1.x, v2.y);
const v2t = new Vector2D(v2.x, v1.y);
const rt = new Rectangle(v1t, v2t);
expect(rt.left).to.equal(1);
expect(rt.top).to.equal(2);
expect(rt.width).to.equal(3);
expect(rt.height).to.equal(4);
});
it("should contain itself", () => {
expect(r1.contains(v1)).true;
expect(r1.contains(v2)).true;
expect(r1.contains(r1.origin)).true;
expect(r1.contains(r1.corner)).true;
const vmid = new Vector2D((v1.x + v2.x) / 2, (v1.y + v2.y) / 2);
expect(r1.contains(vmid)).true;
});
it("should not contain certain points", () => {
expect(r1.contains(new Vector2D(0, 0))).false;
expect(r1.contains(new Vector2D(100, 100))).false;
});
});