diff --git a/src/pages/measure/components/MeasureAction.tsx b/src/pages/measure/components/MeasureAction.tsx
index efeea06..e6e71e4 100644
--- a/src/pages/measure/components/MeasureAction.tsx
+++ b/src/pages/measure/components/MeasureAction.tsx
@@ -6,6 +6,7 @@ import { createWebSocket, sharedWsUrl } from "../../../services/socket";
import GridLayer from "./graph/GridLayer";
import StandardLayer from "./graph/StandardLayer";
import RealtimeLayer from "./graph/RealtimeLayer";
+import MarkLayer from "./graph/MarkLayer";
export default function MeasureAction() {
const navigate = useNavigate();
@@ -78,6 +79,18 @@ export default function MeasureAction() {
rows={7}
/>
+
测量步骤
diff --git a/src/pages/measure/components/graph/MarkLayer.tsx b/src/pages/measure/components/graph/MarkLayer.tsx
index 28bb3d8..560e814 100644
--- a/src/pages/measure/components/graph/MarkLayer.tsx
+++ b/src/pages/measure/components/graph/MarkLayer.tsx
@@ -1,31 +1,88 @@
import { useCallback, useEffect, useRef } from "react";
+import { calculatePointOnCircle, findSymmetricPoint } from "../../../../utils";
+
+const marks = [
+ { x: 9.949007022412, y: 0.1650166186941, degree: -80 },
+ { x: 25.35, y: 2.184814802617, degree: -60 },
+ { x: -9.949007022412, y: 0.1650166186941, degree: -100 },
+ { x: -25.35, y: 2.184814802617, degree: -120 },
+];
export default function MarkLayer(props: {
- width: number;
- height: number;
- leftPadding: number;
- rightPadding: number;
- topPadding: number;
- bottomPadding: number;
+ width: number;
+ height: number;
+ leftPadding: number;
+ rightPadding: number;
+ topPadding: number;
+ bottomPadding: number;
+ columns: number;
+ rows: number;
}) {
- const canvasRef = useRef
(null);
- const draw = useCallback((ctx: CanvasRenderingContext2D) => {
- // 使用context对象进行绘图
- ctx.fillStyle = "skyblue"; // 设置填充颜色
- ctx.fillRect(50, 50, 150, 100); // 绘制一个矩形
- }, []);
- useEffect(() => {
- const canvas = canvasRef.current;
- if (!canvas) return;
-
- const context = canvas.getContext("2d");
- if (!context) return;
- draw(context);
- }, [draw]);
-
- return (
-
-
-
- );
+ const xStartPx = props.leftPadding;
+ const xEndPx = props.width - props.rightPadding;
+ const xStepPx = (props.width - props.leftPadding - props.rightPadding) / props.columns;
+ const yStartPx = props.topPadding;
+ // const yEndPx = props.height - props.bottomPadding;
+ const yStepPx = (props.height - props.topPadding - props.bottomPadding) / props.rows;
+
+ const unitPx = xStepPx / 10;
+ const canvasRef = useRef(null);
+
+ const calcPoints = useCallback(
+ (arr: typeof marks) => {
+ return arr.map(p => {
+ const p1 = calculatePointOnCircle(p.x * unitPx, p.y * unitPx, xStepPx / 2, p.degree);
+ const p2 = findSymmetricPoint(p1.x, p1.y, p.x * unitPx, p.y * unitPx);
+ // 角度文本,向外偏移
+ const p3 = calculatePointOnCircle(p.x * unitPx, p.y * unitPx, xStepPx / 2 + 10, p.degree);
+ return [p1, p2, p3];
+ });
+ },
+ [unitPx, xStepPx]
+ );
+
+ const draw = useCallback(
+ (ctx: CanvasRenderingContext2D) => {
+ // 偏移原点
+ const xOffset = (xEndPx - xStartPx) / 2;
+ const yOffset = yStepPx * 2;
+ ctx.translate(xStartPx + xOffset, yStartPx + yOffset);
+
+ ctx.fillStyle = "#333333";
+ ctx.textAlign = "center";
+ ctx.font = "normal 14px system";
+
+ const lines = calcPoints(marks);
+ for (let idx = 0; idx < lines.length; idx++) {
+ const line = lines[idx];
+ ctx.moveTo(line[0].x, line[0].y);
+ ctx.lineTo(line[1].x, line[1].y);
+
+ ctx.save();
+ ctx.translate(line[2].x, line[2].y);
+ ctx.rotate(((marks[idx].degree + 90) * Math.PI) / 180);
+ ctx.fillText(`${-marks[idx].degree}°`, 0, 0);
+ ctx.restore();
+ }
+ ctx.stroke();
+ // ctx.fillStyle = "skyblue"; // 设置填充颜色
+ // ctx.fillRect(50, 50, 150, 100); // 绘制一个矩形
+ },
+ [calcPoints, xEndPx, xStartPx, yStartPx, yStepPx]
+ );
+
+ useEffect(() => {
+ const canvas = canvasRef.current;
+ if (!canvas) return;
+
+ const context = canvas.getContext("2d");
+ if (!context) return;
+ draw(context);
+ }, [draw]);
+
+ return (
+
+
+
+ );
}
diff --git a/src/pages/measure/components/graph/RealtimeLayer.tsx b/src/pages/measure/components/graph/RealtimeLayer.tsx
index 54fbd75..387c5b2 100644
--- a/src/pages/measure/components/graph/RealtimeLayer.tsx
+++ b/src/pages/measure/components/graph/RealtimeLayer.tsx
@@ -72,7 +72,6 @@ export default function RealtimeLayer(props: {
// console.log(data.data);
// setRtPoints(rtPoints.concat([data.data]));
pointArr.push(data.data);
- console.log(pointArr.length);
const canvas = canvasRef.current;
if (!canvas) return;
diff --git a/src/pages/measure/components/graph/StandardLayer.tsx b/src/pages/measure/components/graph/StandardLayer.tsx
index ed243f0..6c6a325 100644
--- a/src/pages/measure/components/graph/StandardLayer.tsx
+++ b/src/pages/measure/components/graph/StandardLayer.tsx
@@ -73,44 +73,44 @@ export default function StandardLayer(props: {
// 绘制标准线
ctx.beginPath();
ctx.strokeStyle = "red";
- // ---- 右侧
+ // ---- 右侧 (从上到下)
let point0 = pointsRight[0];
let point1 = pointsRight[1];
ctx.moveTo(point0[0], point0[1]);
let param = calculateCircleBelow(point0[0], point0[1], point1[0], point1[1], 300 * unitPx);
- console.log(param);
+ // console.log(param);
ctx.arc(
param.center.x,
param.center.y,
300 * unitPx,
- param.anglesForCenter.startAngle,
- param.anglesForCenter.endAngle
+ param.angles.startAngle,
+ param.angles.endAngle
);
point0 = pointsRight[1];
point1 = pointsRight[2];
ctx.moveTo(point0[0], point0[1]);
param = calculateCircleBelow(point0[0], point0[1], point1[0], point1[1], 80 * unitPx);
- console.log(param);
+ // console.log(param);
ctx.arc(
param.center.x,
param.center.y,
80 * unitPx,
- param.anglesForCenter.startAngle,
- param.anglesForCenter.endAngle
+ param.angles.startAngle,
+ param.angles.endAngle
);
point0 = pointsRight[2];
point1 = pointsRight[3];
ctx.moveTo(point0[0], point0[1]);
param = calculateCircleBelow(point0[0], point0[1], point1[0], point1[1], 13 * unitPx);
- console.log(param);
+ // console.log(param);
ctx.arc(
param.center.x,
param.center.y,
13 * unitPx,
- param.anglesForCenter.startAngle,
- param.anglesForCenter.endAngle
+ param.angles.startAngle,
+ param.angles.endAngle
);
point0 = pointsRight[3];
@@ -122,15 +122,15 @@ export default function StandardLayer(props: {
point1 = pointsRight[5];
ctx.moveTo(point0[0], point0[1]);
param = calculateCircleAbove(point0[0], point0[1], point1[0], point1[1], 5 * unitPx);
- console.log(param);
- ctx.arc(param.center.x, param.center.y, 5 * unitPx, param.anglesForCenter.startAngle, param.anglesForCenter.endAngle);
+ // console.log(param);
+ ctx.arc(param.center.x, param.center.y, 5 * unitPx, param.angles.startAngle, param.angles.endAngle);
point0 = pointsRight[5];
point1 = pointsRight[6];
ctx.moveTo(point0[0], point0[1]);
ctx.lineTo(point1[0], point1[1]);
- // ---- 左侧
+ // ---- 左侧 (从下向上)
point0 = pointsLeft[0];
point1 = pointsLeft[1];
ctx.moveTo(point0[0], point0[1]);
@@ -140,8 +140,8 @@ export default function StandardLayer(props: {
point1 = pointsLeft[2];
ctx.moveTo(point0[0], point0[1]);
param = calculateCircleAbove(point0[0], point0[1], point1[0], point1[1], 5 * unitPx);
- console.log(param);
- ctx.arc(param.center.x, param.center.y, 5 * unitPx, param.anglesForCenter.startAngle, param.anglesForCenter.endAngle);
+ // console.log(param);
+ ctx.arc(param.center.x, param.center.y, 5 * unitPx, param.angles.startAngle, param.angles.endAngle);
point0 = pointsLeft[2];
point1 = pointsLeft[3];
@@ -152,43 +152,42 @@ export default function StandardLayer(props: {
point1 = pointsLeft[4];
ctx.moveTo(point0[0], point0[1]);
param = calculateCircleBelow(point0[0], point0[1], point1[0], point1[1], 13 * unitPx);
- console.log(param);
+ // console.log(param);
ctx.arc(
param.center.x,
param.center.y,
13 * unitPx,
- param.anglesForCenter.startAngle,
- param.anglesForCenter.endAngle
+ param.angles.startAngle,
+ param.angles.endAngle
);
point0 = pointsLeft[4];
point1 = pointsLeft[5];
ctx.moveTo(point0[0], point0[1]);
param = calculateCircleBelow(point0[0], point0[1], point1[0], point1[1], 80 * unitPx);
- console.log(param);
+ // console.log(param);
ctx.arc(
param.center.x,
param.center.y,
80 * unitPx,
- param.anglesForCenter.startAngle,
- param.anglesForCenter.endAngle
+ param.angles.startAngle,
+ param.angles.endAngle
);
point0 = pointsLeft[5];
point1 = pointsLeft[6];
ctx.moveTo(point0[0], point0[1]);
param = calculateCircleBelow(point0[0], point0[1], point1[0], point1[1], 300 * unitPx);
- console.log(param);
+ // console.log(param);
ctx.arc(
param.center.x,
param.center.y,
300 * unitPx,
- param.anglesForCenter.startAngle,
- param.anglesForCenter.endAngle
+ param.angles.startAngle,
+ param.angles.endAngle
);
ctx.stroke();
- // ctx.fillRect(100, 100, 150, 100); // 绘制一个矩形
},
[pointsLeft, pointsRight, unitPx, xEndPx, xStartPx, xStepPx, yEndPx, yStartPx, yStepPx]
);
diff --git a/src/utils/index.ts b/src/utils/index.ts
index 6c3a9b8..6d17803 100644
--- a/src/utils/index.ts
+++ b/src/utils/index.ts
@@ -4,6 +4,7 @@ export function formatRemainTime(seconds: number) {
return min.padStart(2, "0") + ":" + sec.padStart(2, "0");
}
+// 根据弧线的两个顶点和半径,能计算出两个圆心和相应的夹角。
export function calculateCircleInfo(x1: number, y1: number, x2: number, y2: number, radius: number) {
// 计算P1到P2的中点
const xm = (x1 + x2) / 2;
@@ -41,12 +42,13 @@ export function calculateCircleInfo(x1: number, y1: number, x2: number, y2: numb
const endAngle2 = calculateAngle(cx2, cy2, x2, y2);
return [
- { center: { x: cx1, y: cy1 }, anglesForCenter: { startAngle: startAngle1, endAngle: endAngle1 } },
- { center: { x: cx2, y: cy2 }, anglesForCenter: { startAngle: startAngle2, endAngle: endAngle2 } },
+ { center: { x: cx1, y: cy1 }, angles: { startAngle: startAngle1, endAngle: endAngle1 } },
+ { center: { x: cx2, y: cy2 }, angles: { startAngle: startAngle2, endAngle: endAngle2 } },
];
}
export type CenterAndAngle = ReturnType;
+// 取圆心偏下的那一组圆心和夹角
export function calculateCircleBelow(x1: number, y1: number, x2: number, y2: number, radius: number) {
const results = calculateCircleInfo(x1, y1, x2, y2, radius);
if (results[0].center.y > results[1].center.y) {
@@ -55,6 +57,7 @@ export function calculateCircleBelow(x1: number, y1: number, x2: number, y2: num
return results[1];
}
}
+// 取圆心偏上的那一组圆心和夹角
export function calculateCircleAbove(x1: number, y1: number, x2: number, y2: number, radius: number) {
const results = calculateCircleInfo(x1, y1, x2, y2, radius);
if (results[0].center.y < results[1].center.y) {
@@ -63,3 +66,22 @@ export function calculateCircleAbove(x1: number, y1: number, x2: number, y2: num
return results[1];
}
}
+// 根据圆心坐标、半径和角度来计算目标点的坐标
+export function calculatePointOnCircle(cx: number, cy: number, radius: number, angleInDegrees: number) {
+ // 将角度从度转换为弧度
+ const angleInRadians = angleInDegrees * (Math.PI / 180);
+
+ // 计算目标点的坐标
+ const x = cx + radius * Math.cos(angleInRadians);
+ const y = cy + radius * Math.sin(angleInRadians);
+
+ return { x, y };
+}
+// 计算一个点相对于原点的对称点坐标
+export function findSymmetricPoint(px: number, py: number, ox = 0, oy = 0) {
+ // 计算对称点的坐标
+ const sx = 2 * ox - px;
+ const sy = 2 * oy - py;
+
+ return { x: sx, y: sy };
+}