Pārlūkot izejas kodu

memory allocation correction

improved instability and allocation of intersections

implementation of intersection between line segment and circumference
Victor Luiz Domingues 4 gadi atpakaļ
vecāks
revīzija
6d108f5f18

+ 48 - 21
src/app/components/circumference-component/models/circumference-model.js

@@ -97,31 +97,58 @@ export class CircumferenceModel extends GeometricObject {
     ];
   }
 
+  /**
+   * Get Intersection Poin By Circumference and Line Segment
+   * @param {LineSegmentModel} 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) {
+
+    const pointA = lineSegment.pointA;
+    const pointB = lineSegment.pointB;
+    const center = this.center;
+    const radius = this.getRadius();
+
+    const dx = pointB.posX - pointA.posX;
+    const dy = pointB.posY - pointA.posY;
+
+    const cx = center.posX - pointA.posX;
+    const cy = center.posY - pointA.posY;
+
+    const a = dx * dx + dy * dy;
+    const b = dx * cx + dy * cy;
+    const c = cx * cx + cy * cy - radius * radius;
+
+    const D = b / a;
+    const q = c / a;
+
+    const delta = D * D - q;
+    if (delta < 0) {
       return [
-        new IntersectionModel(
-          Number.MAX_SAFE_INTEGER,
-          Number.MAX_SAFE_INTEGER,
-          undefined,
-          this,
-          lineSegment
-        )
+        new IntersectionModel(Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER, undefined, this, lineSegment, false, 0),
+        new IntersectionModel(Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER, undefined, this, lineSegment, false, 1)
       ];
-    } else {
-      const x = (b2 * c1 - b1 * c2) / determinant;
-      const y = (a1 * c2 - a2 * c1) / determinant;
-      return [new IntersectionModel(x, y, undefined, this, lineSegment)];
     }
+
+    const deltaSqrt = Math.sqrt(delta);
+    const root1 = -D + deltaSqrt;
+    const root2 = -D - deltaSqrt;
+    const x1 = pointA.posX - dx * root1
+    const y1 = pointA.posY - dy * root1;
+
+    if (delta == 0) {
+      return [
+        new IntersectionModel(x1, y1, undefined, this, lineSegment, true, 0),
+        new IntersectionModel(Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER, undefined, this, lineSegment, false, 1)
+      ];
+    }
+    const x2 = pointA.posX - dx * root2;
+    const y2 = pointA.posY - dy * root2;
+
+    return [
+      new IntersectionModel(x1, y1, undefined, this, lineSegment, true, 0),
+      new IntersectionModel(x2, y2, undefined, this, lineSegment, true, 1)
+    ];
+
   }
 
   insideSegment(intersecX, intersecY) {

+ 10 - 4
src/app/components/intersection-component/drawers/intersection-drawer.js

@@ -4,6 +4,7 @@ import { Drawer } from "../../../core/drawers/drawer";
 import { app as App } from "../../../app";
 import { objects } from "../../../core/application/objects";
 import { DrawerAggregator } from "../../../core/drawers/drawer-aggregator";
+import { intersectionService } from "../services/intersection-service";
 
 export class IntersectionDrawer extends Drawer {
   static FIRST_OBJECT_STATE() {
@@ -68,15 +69,16 @@ export class IntersectionDrawer extends Drawer {
     return objects.getByGenericObject(genericObject)[0];
   }
   drawPoint() {
-    const intersectionPoints = this.aggregatorA.genericObject.getIntersection(
+    const intersectionPoints = intersectionService.addIntersections(this.aggregatorA.genericObject.getIntersection(
       this.aggregatorB.genericObject
-    );
+    ));
     this.drawByIntersectionPoints(intersectionPoints);
   }
   drawByIntersectionPoints(intersectionPoints) {
     for (let index = 0; index < intersectionPoints.length; index++) {
       const intersectionPoint = intersectionPoints[index];
       intersectionPoint.update();
+      if (!intersectionPoint.visible) return;
       const point = PointDrawer.drawPoint(
         intersectionPoint,
         false,
@@ -105,9 +107,12 @@ export class IntersectionDrawer extends Drawer {
     }
   }
   update(aggregator, e) {
+
     aggregator.genericObject.update(aggregator, e);
-    if (!aggregator.genericObject.visible) {
+
+    if (!aggregator.genericObject.visible || aggregator.genericObject.posX == Number.MAX_SAFE_INTEGER) {
       if (aggregator.visible) {
+
         aggregator.konvaObject.hide();
         aggregator.aggregators.forEach(a => {
           a.visible = false;
@@ -120,7 +125,8 @@ export class IntersectionDrawer extends Drawer {
     }
     aggregator.konvaObject.x(aggregator.genericObject.posX);
     aggregator.konvaObject.y(aggregator.genericObject.posY);
-    if (!aggregator.visible) {
+    if (!aggregator.visible || aggregator.genericObject.posX == Number.MAX_SAFE_INTEGER) {
+      aggregator.genericObject.visible = true;
       aggregator.konvaObject.show();
       aggregator.aggregators.forEach(a => {
         a.visible = true;

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

@@ -27,14 +27,15 @@ export class IntersectionModel extends PointModel {
    * Update properties of this Intersection
    * @param {DrawerAggregator} aggregator Drawer Aggregator 
    * @param {event} event 
-   */
+  */
   update(aggregator, event) {
-    this.visible = true;
     const intersections = this.r.getIntersection(this.s);
     if (intersections.length == 1) {
+      this.visible = true;
       const intersection = intersections[0];
       this.posX = parseFloat(intersection.posX.toFixed(2));
       this.posY = parseFloat(intersection.posY.toFixed(2));
+      // this.visible = intersection.visible;
       if (!this.r.insideSegment(this.posX, this.posY)) {
         this.posX = Number.MAX_SAFE_INTEGER;
         this.posY = Number.MAX_SAFE_INTEGER;
@@ -54,11 +55,10 @@ export class IntersectionModel extends PointModel {
     if (intersections.length > 1) {
       for (let index = 0; index < intersections.length; index++) {
         const intersection = intersections[index];
-
         if (this.index == index) {
-          console.info(this.posX, intersection.posX);
           this.posX = parseFloat(intersection.posX.toFixed(2));
           this.posY = parseFloat(intersection.posY.toFixed(2));
+          this.visible = intersection.visible;
         }
       }
     }
@@ -81,7 +81,7 @@ export class IntersectionModel extends PointModel {
     const index = map.get("param")[2] - 1;
     const x = (map.get("param")[3]) - 5;
     const y = (map.get("param")[4]) + 5;
-    const visible = map.get("param")[5]
+    const visible = map.get("param")[5] == 1;
     const label = map.get("label");
     const r = list.find(x => x.id == rId);
     const s = list.find(x => x.id == sId);

+ 23 - 0
src/app/components/intersection-component/services/intersection-service.js

@@ -0,0 +1,23 @@
+class IntersectionService {
+    constructor() {
+        this.intersectionsMap = new Map()
+    }
+
+    /**
+     * 
+     * @param {[]} intersections 
+     */
+    addIntersections(intersections) {
+        const key = intersections.map((intersection) => {
+            return `r_${intersection.r.id}_s_${intersection.s.id}`;
+        });
+        if (this.intersectionsMap.has(key)) {
+            this.intersectionsMap.get(key).forEach((x, i) => intersections[i] = x.id);
+            delete this.intersectionsMap.get(key);
+            this.intersectionsMap.delete(key);
+        }
+        this.intersectionsMap.set(key, intersections);
+        return intersections;
+    }
+}
+export const intersectionService = new IntersectionService();

+ 44 - 21
src/app/components/line-segment-component/models/line-segment-model.js

@@ -69,30 +69,53 @@ export class LineSegmentModel extends GeometricObject {
   }
 
   getIntersectionByCircumference(circumference) {
-    const r = this.getStraight();
-    const s = circumference.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) {
+
+    const pointA = this.pointA;
+    const pointB = this.pointB;
+    const center = circumference.center;
+    const radius = circumference.getRadius();
+
+    const dx = pointB.posX - pointA.posX;
+    const dy = pointB.posY - pointA.posY;
+
+    const cx = center.posX - pointA.posX;
+    const cy = center.posY - pointA.posY;
+
+    const a = dx * dx + dy * dy;
+    const b = dx * cx + dy * cy;
+    const c = cx * cx + cy * cy - radius * radius;
+
+    const D = b / a;
+    const q = c / a;
+
+    const delta = D * D - q;
+    if (delta < 0) {
       return [
-        new IntersectionModel(
-          Number.MAX_SAFE_INTEGER,
-          Number.MAX_SAFE_INTEGER,
-          undefined,
-          this,
-          circumference
-        )
+        new IntersectionModel(Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER, undefined, this, circumference, false, 0),
+        new IntersectionModel(Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER, undefined, this, circumference, false, 1)
       ];
-    } else {
-      const x = (b2 * c1 - b1 * c2) / determinant;
-      const y = (a1 * c2 - a2 * c1) / determinant;
-      return [new IntersectionModel(x, y, undefined, this, circumference)];
     }
+
+    const deltaSqrt = Math.sqrt(delta);
+    const root1 = -D + deltaSqrt;
+    const root2 = -D - deltaSqrt;
+    const x1 = pointA.posX - dx * root1
+    const y1 = pointA.posY - dy * root1;
+
+    if (delta == 0) {
+      return [
+        new IntersectionModel(x1, y1, undefined, this, circumference, true, 0),
+        new IntersectionModel(Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER, undefined, this, circumference, false, 1)
+      ];
+    }
+    const x2 = pointA.posX - dx * root2;
+    const y2 = pointA.posY - dy * root2;
+
+    return [
+      new IntersectionModel(x1, y1, undefined, this, circumference, true, 0),
+      new IntersectionModel(x2, y2, undefined, this, circumference, true, 1)
+    ];
+
   }
 
   insideSegment(intersecX, intersecY) {