Pārlūkot izejas kodu

Merge branch 'feature/intersection-circumference' into develop

Victor Luiz Domingues 4 gadi atpakaļ
vecāks
revīzija
da142c457d

+ 132 - 123
src/app/components/circumference-component/models/circumference-model.js

@@ -1,139 +1,148 @@
-import { LineSegmentModel } from "../../line-segment-component/models/line-segment-model";
 import { ELEMENTS_CLASS } from "../../../core/enums/elements-class-enum";
 import { GeometricObject } from "../../../core/models/objects/geometric-object";
 import { IntersectionModel } from "../../intersection-component/models/intersection-model";
 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;
+  }
+}

+ 22 - 13
src/app/components/intersection-component/drawers/intersection-drawer.js

@@ -61,21 +61,30 @@ export class IntersectionDrawer extends Drawer {
     return objects.getByKonvaObject(konvaObject)[0];
   }
   drawPoint() {
-    const intersectionPoint = this.aggregatorA.genericObject.getIntersection(
+    const intersectionPoints = this.aggregatorA.genericObject.getIntersection(
       this.aggregatorB.genericObject
     );
-    intersectionPoint.update();
-    const point = PointDrawer.drawPoint(intersectionPoint, false, false, true);
-    const aggregator = new DrawerAggregator(
-      this,
-      intersectionPoint,
-      point.konvaObject,
-      ELEMENTS_CLASS.INTERSECTION_POINT
-    );
-    this.point = point.geometricObject;
-    super.addAggregator(aggregator);
-    this.aggregatorB.addAggregator(aggregator);
-    this.aggregatorA.addAggregator(aggregator);
+    for (let index = 0; index < intersectionPoints.length; index++) {
+      const intersectionPoint = intersectionPoints[index];
+      intersectionPoint.update();
+      const point = PointDrawer.drawPoint(
+        intersectionPoint,
+        false,
+        false,
+        true
+      );
+
+      const aggregator = new DrawerAggregator(
+        this,
+        intersectionPoint,
+        point.konvaObject,
+        ELEMENTS_CLASS.INTERSECTION_POINT
+      );
+      this.point = point.geometricObject;
+      super.addAggregator(aggregator);
+      this.aggregatorB.addAggregator(aggregator);
+      this.aggregatorA.addAggregator(aggregator);
+    }
   }
   isValidObject(konvaObject) {
     switch (konvaObject.attrs.class) {

+ 31 - 16
src/app/components/intersection-component/models/intersection-model.js

@@ -2,30 +2,45 @@ import { PointModel } from "../../point-component/models/point-model";
 import { ELEMENTS_CLASS } from "../../../core/enums/elements-class-enum";
 
 export class IntersectionModel extends PointModel {
-  constructor(posX, posY, label, r, s) {
-    super(posX, posY, label);
+  constructor(posX, posY, label, r, s, visible, index, id) {
+    super(posX, posY, label, id);
     this.r = r;
     this.s = s;
     super.setClass(ELEMENTS_CLASS.INTERSECTION_POINT);
+    this.visible = visible;
+    this.index = index;
   }
 
   update(aggregator, event) {
-    const intersection = this.r.getIntersection(this.s);
-    this.posX = parseFloat(intersection.posX.toFixed(2));
-    this.posY = parseFloat(intersection.posY.toFixed(2));
-    if (!this.r.insideSegment(this.posX, this.posY)) {
-      this.posX = Number.MAX_SAFE_INTEGER;
-      this.posY = Number.MAX_SAFE_INTEGER;
-      this.visible = false;
+    this.visible = true;
+    const intersections = this.r.getIntersection(this.s);
+    if (intersections.length == 1) {
+      const intersection = intersections[0];
+      this.posX = parseFloat(intersection.posX.toFixed(2));
+      this.posY = parseFloat(intersection.posY.toFixed(2));
+      if (!this.r.insideSegment(this.posX, this.posY)) {
+        this.posX = Number.MAX_SAFE_INTEGER;
+        this.posY = Number.MAX_SAFE_INTEGER;
+        this.visible = false;
+        return;
+      }
+      if (!this.s.insideSegment(this.posX, this.posY)) {
+        this.posX = Number.MAX_SAFE_INTEGER;
+        this.posY = Number.MAX_SAFE_INTEGER;
+        this.visible = false;
+        return;
+      }
       return;
     }
-
-    if (!this.s.insideSegment(this.posX, this.posY)) {
-      this.posX = Number.MAX_SAFE_INTEGER;
-      this.posY = Number.MAX_SAFE_INTEGER;
-      this.visible = false;
-      return;
+    if (intersections.length > 1) {
+      for (let index = 0; index < intersections.length; index++) {
+        const intersection = intersections[index];
+        if (this.index == intersection.index) {
+          this.posX = parseFloat(intersection.posX.toFixed(2));
+          this.posY = parseFloat(intersection.posY.toFixed(2));
+        }
+        continue;
+      }
     }
-    this.visible = true;
   }
 }

+ 22 - 18
src/app/components/line-segment-component/models/line-segment-model.js

@@ -2,8 +2,8 @@ import { GeometricObject } from "../../../core/models/objects/geometric-object";
 import { IntersectionModel } from "../../intersection-component/models/intersection-model";
 import { ELEMENTS_CLASS } from "../../../core/enums/elements-class-enum";
 export class LineSegmentModel extends GeometricObject {
-  constructor(pointA, pointB, label) {
-    super();
+  constructor(pointA, pointB, label, id) {
+    super(id);
     this.pointA = pointA;
     this.pointB = pointB;
     this.setLabel(label);
@@ -50,17 +50,19 @@ export class LineSegmentModel extends GeometricObject {
     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
-      );
+      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);
+      return [new IntersectionModel(x, y, undefined, this, lineSegment)];
     }
   }
 
@@ -75,17 +77,19 @@ export class LineSegmentModel extends GeometricObject {
     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
-      );
+      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 [new IntersectionModel(x, y, undefined, this, circumference)];
     }
   }
 

+ 1 - 1
src/app/components/point-component/drawers/point-drawer.js

@@ -53,7 +53,7 @@ export class PointDrawer extends SelectableDrawer {
   }
 
   update(aggregator, event) {
-    aggregator.konvaObject.children.forEach(function (element) {
+    aggregator.konvaObject.children.forEach(function(element) {
       if (element.attrs.class == ELEMENTS_CLASS.POINT) {
         aggregator.genericObject.update(element, event);
       }

+ 2 - 2
src/app/components/point-component/models/point-model.js

@@ -1,8 +1,8 @@
 import { GeometricObject } from "../../../core/models/objects/geometric-object";
 import { ELEMENTS_CLASS } from "../../../core/enums/elements-class-enum";
 export class PointModel extends GeometricObject {
-  constructor(posX, posY, label) {
-    super();
+  constructor(posX, posY, label, id) {
+    super(id);
     this.posX = posX;
     this.posY = posY;
     this.setLabel(label);

+ 9 - 0
src/app/core/application/identifier.js

@@ -0,0 +1,9 @@
+export class Identifier {
+  constructor() {
+    this.number = 1;
+  }
+  next() {
+    return this.number++;
+  }
+}
+export const identifier = new Identifier();

+ 2 - 2
src/app/core/models/objects/dynamic-object.js

@@ -1,8 +1,8 @@
 import { GenericObject } from "./generic-object";
 
 export class DynamicObject extends GenericObject {
-  constructor() {
-    super();
+  constructor(id) {
+    super(id);
     this.label;
     this.dependencies = [];
     this.elementClass;

+ 11 - 1
src/app/core/models/objects/generic-object.js

@@ -1 +1,11 @@
-export class GenericObject {}
+import { identifier } from "../../application/identifier";
+
+export class GenericObject {
+  constructor(id) {
+    if (id == undefined) {
+      this.id = identifier.next();
+    } else {
+      this.id = id;
+    }
+  }
+}

+ 2 - 2
src/app/core/models/objects/geometric-object.js

@@ -1,8 +1,8 @@
 import { DynamicObject } from "./dynamic-object";
 
 export class GeometricObject extends DynamicObject {
-  constructor() {
-    super();
+  constructor(id) {
+    super(id);
     this.borderColor;
     this.backgroundColor;
     this.edgeThinckness;