Browse Source

更新曲线是否选择算法

bill 2 years ago
parent
commit
fffab4c889
3 changed files with 151 additions and 159 deletions
  1. 75 104
      src/graphic/Renderer/Draw.js
  2. 43 17
      src/graphic/Style.js
  3. 33 38
      src/graphic/Util/MathUtil.js

+ 75 - 104
src/graphic/Renderer/Draw.js

@@ -10,7 +10,12 @@ import ElementEvents from "../enum/ElementEvents.js";
 import Constant from "../Constant.js";
 import Constant from "../Constant.js";
 
 
 const help = {
 const help = {
-  getVectorStyle(vector) {
+  getVectorStyle(vector, geoType = vector.geoType) {
+    const geoId = vector?.vectorId
+    if (!geoId) {
+      return Style[geoType]
+    }
+
     const itemsEntry = [
     const itemsEntry = [
       [stateService.getSelectItem(), "Select"],
       [stateService.getSelectItem(), "Select"],
       [stateService.getDraggingItem(), "Dragging"],
       [stateService.getDraggingItem(), "Dragging"],
@@ -19,17 +24,18 @@ const help = {
     return itemsEntry.reduce((prev, [item, attr]) => {
     return itemsEntry.reduce((prev, [item, attr]) => {
       if (
       if (
         item &&
         item &&
-        item.type === VectorType[vector.geoType] &&
-        vector.vectorId === item.vectorId
+        item.type === VectorType[geoType] &&
+        geoId === item.vectorId
       ) {
       ) {
-        return Style[attr][vector.geoType];
-      } else {
-        return prev
+        if (Style[attr] && Style[attr][geoType]) {
+          return Style[attr][geoType];
+        }
       }
       }
-    }, Style[vector.geoType]);
+      return prev
+    }, Style[geoType]);
   },
   },
-  setVectorStyle(ctx, vector) {
-    const styles = help.getVectorStyle(vector);
+  setVectorStyle(ctx, vector, geoType = vector.geoType) {
+    const styles = help.getVectorStyle(vector, geoType);
     for (const style in styles) {
     for (const style in styles) {
       ctx[style] = styles[style];
       ctx[style] = styles[style];
     }
     }
@@ -67,31 +73,29 @@ export default class Draw {
 
 
 
 
   drawRoad(vector, isTemp) {
   drawRoad(vector, isTemp) {
-    this.context.save();
-    this.context.beginPath();
-
-    help.setVectorStyle(this.context, vector)
-
     const startReal = isTemp ? vector.start : dataService.getPoint(vector.startId)
     const startReal = isTemp ? vector.start : dataService.getPoint(vector.startId)
     const endReal = isTemp ? vector.end : dataService.getPoint(vector.endId)
     const endReal = isTemp ? vector.end : dataService.getPoint(vector.endId)
-    const startScreen = coordinate.getScreenXY(startReal);
-    const endScreen = coordinate.getScreenXY(endReal);
+    if (vector?.midDivide?.display) {
+      const ctx = this.context;
+      const startScreen = coordinate.getScreenXY(startReal);
+      const endScreen = coordinate.getScreenXY(endReal);
+
+      ctx.save();
+      help.setVectorStyle(ctx, vector)
+      ctx.beginPath();
+      ctx.moveTo(startScreen.x, startScreen.y);
+      ctx.lineTo(endScreen.x, endScreen.y);
+      ctx.stroke();
+      ctx.restore();
+    }
 
 
     if (!isTemp) {
     if (!isTemp) {
       this.drawText(
       this.drawText(
         { x: (startReal.x + endReal.x) / 2, y: (startReal.y + endReal.y) / 2 },
         { x: (startReal.x + endReal.x) / 2, y: (startReal.y + endReal.y) / 2 },
         vector.vectorId
         vector.vectorId
       );
       );
-    } else {
-      this.context.globalAlpha = 0.3
     }
     }
     this.drawEdge(vector, isTemp);
     this.drawEdge(vector, isTemp);
-
-    this.context.beginPath();
-    this.context.moveTo(startScreen.x, startScreen.y);
-    this.context.lineTo(endScreen.x, endScreen.y);
-    this.context.stroke();
-    this.context.restore();
   }
   }
 
 
   drawCurveRoad(vector, isTemp) {
   drawCurveRoad(vector, isTemp) {
@@ -332,17 +336,11 @@ export default class Draw {
 
 
   drawEdge(vector, isTemp) {
   drawEdge(vector, isTemp) {
     //判断是否与road方向一致。角度足够小,路足够宽,有可能向量方向不一致
     //判断是否与road方向一致。角度足够小,路足够宽,有可能向量方向不一致
-    let start = dataService.getPoint(vector.startId);
-    let end = dataService.getPoint(vector.endId);
-
-    let leftEdge = dataService.getEdge(vector.leftEdgeId);
-    let rightEdge = dataService.getEdge(vector.rightEdgeId);
-    if (isTemp) {
-      start = vector.start;
-      end = vector.end;
-      leftEdge = vector.leftEdge;
-      rightEdge = vector.rightEdge;
-    }
+    const ctx = this.context
+    const start = isTemp ? vector.start : dataService.getPoint(vector.startId);
+    const end = isTemp ? vector.end : dataService.getPoint(vector.endId);
+    const leftEdge = isTemp ? vector.leftEdge : dataService.getEdge(vector.leftEdgeId);
+    const rightEdge = isTemp ? vector.rightEdge : dataService.getEdge(vector.rightEdgeId);
 
 
     const leftFlag = mathUtil.isSameDirForVector(
     const leftFlag = mathUtil.isSameDirForVector(
       start,
       start,
@@ -357,52 +355,27 @@ export default class Draw {
       rightEdge.end
       rightEdge.end
     );
     );
 
 
-    this.context.save();
-    this.context.lineCap = "round"; //线段端点的样式
-    this.context.strokeStyle = Style.Road.strokeStyle;
-
-    const selectItem = stateService.getSelectItem();
-    const draggingItem = stateService.getDraggingItem();
-    const focusItem = stateService.getFocusItem();
-
-    if (selectItem && selectItem.type == VectorType.Road) {
-      if (vector.vectorId == selectItem.vectorId) {
-        this.context.strokeStyle = Style.Select.Road.strokeStyle;
-      }
-    } else if (draggingItem && draggingItem.type == VectorType.Road) {
-      if (vector.vectorId == draggingItem.vectorId) {
-        this.context.strokeStyle = Style.Select.Road.strokeStyle;
-      }
-    } else if (focusItem && focusItem.type == VectorType.Road) {
-      if (vector.vectorId == focusItem.vectorId) {
-        this.context.strokeStyle = Style.Focus.Road.strokeStyle;
-      }
-    }
-
-    let point1, point2;
-
-    this.context.globalAlpha = 0.3;
-    this.context.lineWidth = 1;
+    ctx.save();
+    help.setVectorStyle(ctx, vector, "Edge")
+    isTemp && (ctx.globalAlpha = 0.3);
 
 
     if (leftFlag > 0) {
     if (leftFlag > 0) {
-      this.context.beginPath();
-      point1 = coordinate.getScreenXY(leftEdge.start);
-      point2 = coordinate.getScreenXY(leftEdge.end);
-      this.context.moveTo(point1.x, point1.y);
-      this.context.lineTo(point2.x, point2.y);
-      this.context.stroke();
+      ctx.beginPath();
+      const point1 = coordinate.getScreenXY(leftEdge.start);
+      const point2 = coordinate.getScreenXY(leftEdge.end);
+      ctx.moveTo(point1.x, point1.y);
+      ctx.lineTo(point2.x, point2.y);
+      ctx.stroke();
     }
     }
-
     if (rightFlag > 0) {
     if (rightFlag > 0) {
-      point1 = coordinate.getScreenXY(rightEdge.start);
-      point2 = coordinate.getScreenXY(rightEdge.end);
-      this.context.moveTo(point1.x, point1.y);
-      this.context.lineTo(point2.x, point2.y);
-      this.context.stroke();
+      const point1 = coordinate.getScreenXY(rightEdge.start);
+      const point2 = coordinate.getScreenXY(rightEdge.end);
+      ctx.moveTo(point1.x, point1.y);
+      ctx.lineTo(point2.x, point2.y);
+      ctx.stroke();
     }
     }
 
 
-    this.context.restore();
-
+    ctx.restore();
     this.drawText(
     this.drawText(
       {
       {
         x: (leftEdge.start.x + leftEdge.end.x) / 2,
         x: (leftEdge.start.x + leftEdge.end.x) / 2,
@@ -410,7 +383,6 @@ export default class Draw {
       },
       },
       vector.leftEdgeId
       vector.leftEdgeId
     );
     );
-
     this.drawText(
     this.drawText(
       {
       {
         x: (rightEdge.start.x + rightEdge.end.x) / 2,
         x: (rightEdge.start.x + rightEdge.end.x) / 2,
@@ -421,11 +393,15 @@ export default class Draw {
   }
   }
 
 
   drawPoint(vector) {
   drawPoint(vector) {
+    const ctx = this.context;
+    console.log(vector)
     const pt = coordinate.getScreenXY({ x: vector.x, y: vector.y });
     const pt = coordinate.getScreenXY({ x: vector.x, y: vector.y });
     const selectItem = stateService.getSelectItem();
     const selectItem = stateService.getSelectItem();
     const draggingItem = stateService.getDraggingItem();
     const draggingItem = stateService.getDraggingItem();
     const focusItem = stateService.getFocusItem();
     const focusItem = stateService.getFocusItem();
 
 
+    help.setVectorStyle(ctx, vector)
+
     let radius = Style.Point.radius;
     let radius = Style.Point.radius;
     if (
     if (
       (draggingItem &&
       (draggingItem &&
@@ -435,28 +411,28 @@ export default class Draw {
         selectItem.type == VectorType.Point &&
         selectItem.type == VectorType.Point &&
         vector.vectorId == selectItem.vectorId)
         vector.vectorId == selectItem.vectorId)
     ) {
     ) {
-      this.context.save();
-      this.context.lineWidth = Style.Select.Point.lineWidth * coordinate.ratio;
-      this.context.strokeStyle = Style.Select.Point.strokeStyle;
-      this.context.fillStyle = Style.Select.Point.fillStyle;
+      ctx.save();
+      ctx.lineWidth = Style.Select.Point.lineWidth * coordinate.ratio;
+      ctx.strokeStyle = Style.Select.Point.strokeStyle;
+      ctx.fillStyle = Style.Select.Point.fillStyle;
       radius = Style.Select.Point.radius;
       radius = Style.Select.Point.radius;
     } else if (
     } else if (
       focusItem &&
       focusItem &&
       focusItem.type == VectorType.Point &&
       focusItem.type == VectorType.Point &&
       vector.vectorId == focusItem.vectorId
       vector.vectorId == focusItem.vectorId
     ) {
     ) {
-      this.context.save();
-      this.context.lineWidth = Style.Focus.Point.lineWidth * coordinate.ratio;
-      this.context.strokeStyle = Style.Focus.Point.strokeStyle;
-      this.context.fillStyle = Style.Focus.Point.fillStyle;
+      ctx.save();
+      ctx.lineWidth = Style.Focus.Point.lineWidth * coordinate.ratio;
+      ctx.strokeStyle = Style.Focus.Point.strokeStyle;
+      ctx.fillStyle = Style.Focus.Point.fillStyle;
       radius = Style.Focus.Point.radius;
       radius = Style.Focus.Point.radius;
     }
     }
     // else {
     // else {
     //   return;
     //   return;
     // }
     // }
 
 
-    this.context.beginPath();
-    this.context.arc(
+    ctx.beginPath();
+    ctx.arc(
       pt.x,
       pt.x,
       pt.y,
       pt.y,
       radius * coordinate.ratio,
       radius * coordinate.ratio,
@@ -464,9 +440,9 @@ export default class Draw {
       Math.PI * 2,
       Math.PI * 2,
       true
       true
     );
     );
-    this.context.stroke();
-    this.context.fill();
-    this.context.restore();
+    ctx.stroke();
+    ctx.fill();
+    ctx.restore();
 
 
     this.drawText(vector, vector.vectorId);
     this.drawText(vector, vector.vectorId);
   }
   }
@@ -599,24 +575,19 @@ export default class Draw {
 
 
   // 文字
   // 文字
   drawText(position, txt, angle) {
   drawText(position, txt, angle) {
-    this.context.save();
-    this.setCanvasStyle(Style.Font);
-    if (coordinate.ratio == Constant.ratio) {
-      this.context.font = "12px Microsoft YaHei";
-    } else {
-      this.context.font = "12px Microsoft YaHei";
-    }
-    let pt = coordinate.getScreenXY(position);
+    const ctx = this.context;
+    ctx.save();
+    help.setVectorStyle(null, "Text");
+
+    const pt = coordinate.getScreenXY(position);
     if (angle) {
     if (angle) {
-      this.context.translate(pt.x, pt.y);
-      this.context.rotate(angle);
-      //this.context.strokeText(txt, 0, 0)
-      this.context.fillText(txt, 0, 0);
+      ctx.translate(pt.x, pt.y);
+      ctx.rotate(angle);
+      ctx.fillText(txt, 0, 0);
     } else {
     } else {
-      //this.context.strokeText(txt, pt.x, pt.y)
-      this.context.fillText(txt, pt.x, pt.y);
+      ctx.fillText(txt, pt.x, pt.y);
     }
     }
-    this.context.restore();
+    ctx.restore();
   }
   }
 
 
   drawTag(geometry, styleType, hide) {
   drawTag(geometry, styleType, hide) {

+ 43 - 17
src/graphic/Style.js

@@ -1,23 +1,49 @@
-const Style = {
-  Road: {
+const Road = {
+  strokeStyle: "rgba(255,0,0,0.5)",
+  lineWidth: 4,
+  error: {
     strokeStyle: "rgba(255,0,0,0.5)",
     strokeStyle: "rgba(255,0,0,0.5)",
-    lineWidth: 4,
-    error: {
-      strokeStyle: "rgba(255,0,0,0.5)",
-      fillStyle: "rgba(255,0,0,0.8)",
-    },
-  },
-  Point: {
-    strokeStyle: "green",
-    fillStyle: "rgb(0, 200, 175)",
-    radius: 4,
+    fillStyle: "rgba(255,0,0,0.8)",
   },
   },
-  Tag: {
-    strokeStyle: "rgb(255,255,255,1)",
-    fillStyle: "rgb(255,255,255,1)",
-    strokeStyle_adding: "rgba(243, 255, 0, 0.8)",
-    fillStyle_adding: "rgba(243, 255, 0, 0.8)",
+}
+
+const Tag = {
+  strokeStyle: "rgb(255,255,255,1)",
+  fillStyle: "rgb(255,255,255,1)",
+  strokeStyle_adding: "rgba(243, 255, 0, 0.8)",
+  fillStyle_adding: "rgba(243, 255, 0, 0.8)",
+  lineWidth: 1,
+}
+
+const Font = {
+  font: "14px Microsoft YaHei",
+  fillStyle: "#000000",
+  strokeStyle: "#000000",
+  textAlign: "center",
+  textBaseline: "middle",
+  miterLimit: 10,
+  direction: "ltr",
+}
+
+const Point = {
+  strokeStyle: "green",
+  fillStyle: "rgb(0, 200, 175)",
+  radius: 4,
+}
+
+const Style = {
+  Road,
+  Edge: {
+    ...Road,
     lineWidth: 1,
     lineWidth: 1,
+    globalAlpha: 0.3
+  },
+  Point,
+  Tag,
+  Text: {
+    ...Tag,
+    ...Font,
+    font: "12px Microsoft YaHei"
   },
   },
   Select: {
   Select: {
     Road: {
     Road: {

+ 33 - 38
src/graphic/Util/MathUtil.js

@@ -1251,7 +1251,8 @@ export default class MathUtil {
     return { x, y };
     return { x, y };
   }
   }
 
 
-  getHitInfoForThreeBezier(offsetX, offsetY, curve, rang = 3) {
+  getHitInfoForThreeBezier(position, curve, rang = 3) {
+    const { x: offsetX, y: offsetY } = position
     // 用 x 求出对应的 t,用 t 求相应位置的 y,再比较得出的 y 与 offsetY 之间的差值
     // 用 x 求出对应的 t,用 t 求相应位置的 y,再比较得出的 y 与 offsetY 之间的差值
     const tsx = mathUtil.getThreeBezierT(
     const tsx = mathUtil.getThreeBezierT(
       curve.start.x,
       curve.start.x,
@@ -1270,7 +1271,10 @@ export default class MathUtil {
           curve.end
           curve.end
         );
         );
         if (Math.abs(point.y - offsetY) < rang) {
         if (Math.abs(point.y - offsetY) < rang) {
-          return point;
+          return {
+            position: point,
+            distance: mathUtil.getDistance(point, position)
+          }
         }
         }
       }
       }
     }
     }
@@ -1292,56 +1296,47 @@ export default class MathUtil {
           curve.end
           curve.end
         );
         );
         if (Math.abs(point.x - offsetX) < rang) {
         if (Math.abs(point.x - offsetX) < rang) {
-          return point;
+          return {
+            position: point,
+            distance: mathUtil.getDistance(point, position)
+          }
         }
         }
       }
       }
     }
     }
   }
   }
 
 
   // 二次曲线
   // 二次曲线
-  getHitInfoForTwoBezier(position, curves) {
-    let joinInfo = {
-      position: null,
-      distance: null,
-    };
-    for (let i = 0; i < curves.length; ++i) {
-      const curve = curves[i];
-      let bezierData = [];
-      bezierData.push(curve.start.x);
-      bezierData.push(curve.start.y);
-      bezierData.push(curve.control.x);
-      bezierData.push(curve.control.y);
-      bezierData.push(curve.end.x);
-      bezierData.push(curve.end.y);
-      const { isHit, getInfo } = bezierUtil.measureBezier(...bezierData);
-      const { point } = getInfo(position);
-      const distance = mathUtil.getDistance(position, {
+  getHitInfoForTwoBezier(position, curve) {
+    let bezierData = [];
+    bezierData.push(curve.start.x);
+    bezierData.push(curve.start.y);
+    bezierData.push(curve.control.x);
+    bezierData.push(curve.control.y);
+    bezierData.push(curve.end.x);
+    bezierData.push(curve.end.y);
+    const { isHit, getInfo } = bezierUtil.measureBezier(...bezierData);
+    const { point } = getInfo(position);
+    return {
+      position: point,
+      distance: mathUtil.getDistance(position, {
         x: point[0],
         x: point[0],
         y: point[1],
         y: point[1],
-      });
-      if (joinInfo.distance == null || distance < joinInfo.distance) {
-        joinInfo.distance = mathUtil.getDistance(position, {
-          x: point[0],
-          y: point[1],
-        });
-        joinInfo.position = {
-          x: point[0],
-          y: point[1],
-        };
-      }
-    }
-    return joinInfo;
+      })
+    };
   }
   }
 
 
   getHitInfoForCurves(pos, curves) {
   getHitInfoForCurves(pos, curves) {
+    let joinInfo;
     for (const curve of curves) {
     for (const curve of curves) {
-      if (curve.controls.length === 2) {
-        if (mathUtil.getHitInfoForThreeBezier(pos.x, pos.y, curve)) {
-          return true;
-        }
-      } else {
+      const tempJoinInfo = curve.controls.length === 2
+        ? mathUtil.getHitInfoForThreeBezier(pos, curve, 8)
+        : mathUtil.getHitInfoForTwoBezier(pos.x, curve)
+
+      if (!joinInfo || (tempJoinInfo && tempJoinInfo.distance < joinInfo.distance)) {
+        joinInfo = tempJoinInfo;
       }
       }
     }
     }
+    return joinInfo;
   }
   }
 }
 }