|
@@ -1,139 +1,148 @@
|
|
-import { LineSegmentModel } from "../../line-segment-component/models/line-segment-model";
|
|
|
|
import { ELEMENTS_CLASS } from "../../../core/enums/elements-class-enum";
|
|
import { ELEMENTS_CLASS } from "../../../core/enums/elements-class-enum";
|
|
import { GeometricObject } from "../../../core/models/objects/geometric-object";
|
|
import { GeometricObject } from "../../../core/models/objects/geometric-object";
|
|
import { IntersectionModel } from "../../intersection-component/models/intersection-model";
|
|
import { IntersectionModel } from "../../intersection-component/models/intersection-model";
|
|
export class CircumferenceModel extends GeometricObject {
|
|
export class CircumferenceModel extends GeometricObject {
|
|
- constructor(center, radius) {
|
|
|
|
- super();
|
|
|
|
- this.center = center;
|
|
|
|
- this.radius = radius;
|
|
|
|
- this._coordinates = [];
|
|
|
|
- this._coordinates[0] = this.center.posX;
|
|
|
|
- this._coordinates[1] = this.center.posY;
|
|
|
|
- this._coordinates[2] = this.radius.posX;
|
|
|
|
- this._coordinates[3] = this.radius.posY;
|
|
|
|
- super.setClass(ELEMENTS_CLASS.CIRCUMFERENCE);
|
|
|
|
|
|
+ constructor(center, radius, id) {
|
|
|
|
+ super(id);
|
|
|
|
+ this.center = center;
|
|
|
|
+ this.radius = radius;
|
|
|
|
+ this._coordinates = [];
|
|
|
|
+ this._coordinates[0] = this.center.posX;
|
|
|
|
+ this._coordinates[1] = this.center.posY;
|
|
|
|
+ this._coordinates[2] = this.radius.posX;
|
|
|
|
+ this._coordinates[3] = this.radius.posY;
|
|
|
|
+ super.setClass(ELEMENTS_CLASS.CIRCUMFERENCE);
|
|
|
|
+ }
|
|
|
|
+ getRadius() {
|
|
|
|
+ this._coordinates[0] = this.center.posX;
|
|
|
|
+ this._coordinates[1] = this.center.posY;
|
|
|
|
+ this._coordinates[2] = this.radius.posX;
|
|
|
|
+ this._coordinates[3] = this.radius.posY;
|
|
|
|
+ const legA = this._coordinates[2] - this._coordinates[0];
|
|
|
|
+ const legB = this._coordinates[3] - this._coordinates[1];
|
|
|
|
+ const radius = Math.sqrt(Math.pow(legA, 2) + Math.pow(legB, 2));
|
|
|
|
+ return radius;
|
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
|
- getRadius() {
|
|
|
|
- this._coordinates[0] = this.center.posX;
|
|
|
|
- this._coordinates[1] = this.center.posY;
|
|
|
|
- this._coordinates[2] = this.radius.posX;
|
|
|
|
- this._coordinates[3] = this.radius.posY;
|
|
|
|
- const legA = this._coordinates[2] - this._coordinates[0];
|
|
|
|
- const legB = this._coordinates[3] - this._coordinates[1];
|
|
|
|
- const radius = Math.sqrt(Math.pow(legA, 2) + Math.pow(legB, 2));
|
|
|
|
- return radius;
|
|
|
|
- }
|
|
|
|
|
|
+ getStraight() {
|
|
|
|
+ const dx = this.radius.posX - this.center.posX;
|
|
|
|
+ const dy = this.radius.posY - this.center.posY;
|
|
|
|
+ const c = Math.sqrt(dy * dy + dx * dx);
|
|
|
|
+ return [dx, dy, c];
|
|
|
|
+ }
|
|
|
|
|
|
- getStraight() {
|
|
|
|
- const aX = this.center.posX;
|
|
|
|
- const aY = this.center.posY;
|
|
|
|
- const bX = this.radius.posX;
|
|
|
|
- const bY = this.radius.posY;
|
|
|
|
- const a = bY - aY;
|
|
|
|
- const b = aX - bX;
|
|
|
|
- const c = a * aX + b * aY;
|
|
|
|
- return [a, b, c];
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- getDirection() {
|
|
|
|
- const aX = this.center.posX;
|
|
|
|
- const aY = this.center.posY;
|
|
|
|
- const bX = this.radius.posX;
|
|
|
|
- const bY = this.radius.posY;
|
|
|
|
- const a = bX - aX;
|
|
|
|
- const b = bY - aY;
|
|
|
|
- return [a, b];
|
|
|
|
- }
|
|
|
|
- getIntersection(geometricObject) {
|
|
|
|
- switch (geometricObject.elementClass) {
|
|
|
|
- case ELEMENTS_CLASS.LINE_SEGMENT:
|
|
|
|
- return this.getIntersectionByLine(geometricObject);
|
|
|
|
- case ELEMENTS_CLASS.CIRCUMFERENCE:
|
|
|
|
- return this.getIntersectionByCircumference(geometricObject);
|
|
|
|
- default:
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
|
|
+ getDirection() {
|
|
|
|
+ const aX = this.center.posX;
|
|
|
|
+ const aY = this.center.posY;
|
|
|
|
+ const bX = this.radius.posX;
|
|
|
|
+ const bY = this.radius.posY;
|
|
|
|
+ const a = bX - aX;
|
|
|
|
+ const b = bY - aY;
|
|
|
|
+ return [a, b];
|
|
|
|
+ }
|
|
|
|
+ getIntersection(geometricObject) {
|
|
|
|
+ switch (geometricObject.elementClass) {
|
|
|
|
+ case ELEMENTS_CLASS.LINE_SEGMENT:
|
|
|
|
+ return this.getIntersectionByLine(geometricObject);
|
|
|
|
+ case ELEMENTS_CLASS.CIRCUMFERENCE:
|
|
|
|
+ return this.getIntersectionsByCircumference(geometricObject);
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
- getIntersectionByCircumference(circumference) {
|
|
|
|
- const rM = new LineSegmentModel(this.center, this.radius);
|
|
|
|
- const sM = new LineSegmentModel(circumference.center, circumference.radius);
|
|
|
|
- const r = rM.getStraight();
|
|
|
|
- const s = sM.getStraight();
|
|
|
|
- const a1 = r[0];
|
|
|
|
- const b1 = r[1];
|
|
|
|
- const c1 = r[2];
|
|
|
|
- const a2 = s[0];
|
|
|
|
- const b2 = s[1];
|
|
|
|
- const c2 = s[2];
|
|
|
|
- const determinant = a1 * b2 - a2 * b1;
|
|
|
|
- if (determinant == 0) {
|
|
|
|
- return new IntersectionModel(
|
|
|
|
- Number.MAX_SAFE_INTEGER,
|
|
|
|
- Number.MAX_SAFE_INTEGER,
|
|
|
|
- undefined,
|
|
|
|
- this,
|
|
|
|
- circumference
|
|
|
|
- );
|
|
|
|
- } else {
|
|
|
|
- const x = (b2 * c1 - b1 * c2) / determinant;
|
|
|
|
- const y = (a1 * c2 - a2 * c1) / determinant;
|
|
|
|
- return new IntersectionModel(x, y, undefined, this, circumference);
|
|
|
|
- }
|
|
|
|
- return
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+ }
|
|
|
|
+ distance(center) {
|
|
|
|
+ const dx = center.posX - this.center.posX;
|
|
|
|
+ const dy = center.posY - this.center.posY;
|
|
|
|
+ const dist = Math.sqrt(dy * dy + dx * dx);
|
|
|
|
+ return dist;
|
|
|
|
+ }
|
|
|
|
+ getIntersectionsByCircumference(circumference) {
|
|
|
|
+ // if (this.cente().igual(cd.C()))
|
|
|
|
+ // return null; // duas circ. com mesmo raio => devolva "null" (ambiguidade!)
|
|
|
|
+ const r1 = this.getRadius(); // raio circ. atual
|
|
|
|
+ const r2 = circumference.getRadius(); // raio circ. "cd"
|
|
|
|
+ const d = this.distance(circumference); // distancia entre os raios das circ.
|
|
|
|
+ if (r1 + r2 < d || Math.abs(r1 - r2) > d) return null;
|
|
|
|
+ const A = this.center; // pega o centro da circunferencia atual
|
|
|
|
+ const B = circumference.center; // pega o centro da circunferencia "cd"
|
|
|
|
+ const x = B.posX - A.posX;
|
|
|
|
+ const y = B.posY - A.posY;
|
|
|
|
+ let cos = x / Math.sqrt(x * x + y * y); //(B.posX-A.posX)/Math.sqrt(x*x + y*y); // cos a = <z,w>/(|z||w|)
|
|
|
|
+ let sen = Math.sqrt(1 - cos * cos);
|
|
|
|
+ if (A.posY > B.posY) sen = -sen;
|
|
|
|
+ let u1 = B.posX - A.posX;
|
|
|
|
+ let v1 = B.posY - A.posY;
|
|
|
|
+ let u = u1 * cos + v1 * sen;
|
|
|
|
+ let v = -u1 * sen + v1 * cos;
|
|
|
|
+ const rA = this.getRadius();
|
|
|
|
+ const rB = circumference.getRadius();
|
|
|
|
+ u = (u * u - rB * rB + rA * rA) / (2 * u);
|
|
|
|
+ v = Math.sqrt(rA * rA - u * u);
|
|
|
|
+ v1 = v;
|
|
|
|
+ let v2 = -v;
|
|
|
|
+ let x1 = u * cos - v1 * sen;
|
|
|
|
+ let y1 = u * sen + v1 * cos;
|
|
|
|
+ let x2 = u * cos - v2 * sen;
|
|
|
|
+ let y2 = u * sen + v2 * cos;
|
|
|
|
+ x1 = A.posX + x1;
|
|
|
|
+ y1 = A.posY + y1;
|
|
|
|
+ x2 = A.posX + x2;
|
|
|
|
+ y2 = A.posY + y2;
|
|
|
|
+ return [
|
|
|
|
+ new IntersectionModel(x1, y1, undefined, this, circumference, true, 0),
|
|
|
|
+ new IntersectionModel(x2, y2, undefined, this, circumference, true, 1)
|
|
|
|
+ ];
|
|
|
|
+ }
|
|
|
|
|
|
- getIntersectionByLine(lineSegment) {
|
|
|
|
- const r = this.getStraight();
|
|
|
|
- const s = lineSegment.getStraight();
|
|
|
|
- const a1 = r[0];
|
|
|
|
- const b1 = r[1];
|
|
|
|
- const c1 = r[2];
|
|
|
|
- const a2 = s[0];
|
|
|
|
- const b2 = s[1];
|
|
|
|
- const c2 = s[2];
|
|
|
|
- const determinant = a1 * b2 - a2 * b1;
|
|
|
|
- if (determinant == 0) {
|
|
|
|
- return new IntersectionModel(
|
|
|
|
- Number.MAX_SAFE_INTEGER,
|
|
|
|
- Number.MAX_SAFE_INTEGER,
|
|
|
|
- undefined,
|
|
|
|
- this,
|
|
|
|
- lineSegment
|
|
|
|
- );
|
|
|
|
- } else {
|
|
|
|
- const x = (b2 * c1 - b1 * c2) / determinant;
|
|
|
|
- const y = (a1 * c2 - a2 * c1) / determinant;
|
|
|
|
- return new IntersectionModel(x, y, undefined, this, lineSegment);
|
|
|
|
- }
|
|
|
|
|
|
+ getIntersectionByLine(lineSegment) {
|
|
|
|
+ const r = this.getStraight();
|
|
|
|
+ const s = lineSegment.getStraight();
|
|
|
|
+ const a1 = r[0];
|
|
|
|
+ const b1 = r[1];
|
|
|
|
+ const c1 = r[2];
|
|
|
|
+ const a2 = s[0];
|
|
|
|
+ const b2 = s[1];
|
|
|
|
+ const c2 = s[2];
|
|
|
|
+ const determinant = a1 * b2 - a2 * b1;
|
|
|
|
+ if (determinant == 0) {
|
|
|
|
+ return [
|
|
|
|
+ new IntersectionModel(
|
|
|
|
+ Number.MAX_SAFE_INTEGER,
|
|
|
|
+ Number.MAX_SAFE_INTEGER,
|
|
|
|
+ undefined,
|
|
|
|
+ this,
|
|
|
|
+ lineSegment
|
|
|
|
+ )
|
|
|
|
+ ];
|
|
|
|
+ } else {
|
|
|
|
+ const x = (b2 * c1 - b1 * c2) / determinant;
|
|
|
|
+ const y = (a1 * c2 - a2 * c1) / determinant;
|
|
|
|
+ return [new IntersectionModel(x, y, undefined, this, lineSegment)];
|
|
}
|
|
}
|
|
|
|
+ }
|
|
|
|
|
|
|
|
+ insideSegment(intersecX, intersecY) {
|
|
|
|
+ const valuesR = this.getDirection();
|
|
|
|
+ const dirX = valuesR[0];
|
|
|
|
+ const dirY = valuesR[1];
|
|
|
|
+ const cInterA = dirX * intersecX + dirY * intersecY;
|
|
|
|
|
|
- insideSegment(intersecX, intersecY) {
|
|
|
|
- const valuesR = this.getDirection();
|
|
|
|
- const dirX = valuesR[0];
|
|
|
|
- const dirY = valuesR[1];
|
|
|
|
- const cInterA = dirX * intersecX + dirY * intersecY;
|
|
|
|
-
|
|
|
|
- // comparaca cv do ponto A > cv da intersec => vazio
|
|
|
|
- const cRA = dirX * this.center.posX + dirY * this.center.posY;
|
|
|
|
|
|
+ // comparaca cv do ponto A > cv da intersec => vazio
|
|
|
|
+ const cRA = dirX * this.center.posX + dirY * this.center.posY;
|
|
|
|
|
|
- if (cInterA < cRA) {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // comparaca cv do ponto B < cv da intersec => vazio
|
|
|
|
- const cRB = dirX * this.radius.posX + dirY * this.radius.posY;
|
|
|
|
|
|
+ if (cInterA < cRA) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
|
|
- if (cInterA > cRB) {
|
|
|
|
- this.posX = Number.MAX_SAFE_INTEGER;
|
|
|
|
- this.posY = Number.MAX_SAFE_INTEGER;
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
|
|
+ // comparaca cv do ponto B < cv da intersec => vazio
|
|
|
|
+ const cRB = dirX * this.radius.posX + dirY * this.radius.posY;
|
|
|
|
|
|
- return true;
|
|
|
|
|
|
+ if (cInterA > cRB) {
|
|
|
|
+ this.posX = Number.MAX_SAFE_INTEGER;
|
|
|
|
+ this.posY = Number.MAX_SAFE_INTEGER;
|
|
|
|
+ return false;
|
|
}
|
|
}
|
|
|
|
|
|
-}
|
|
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+}
|