|
@@ -13,6 +13,8 @@ import {
|
|
|
SSize
|
|
|
} from "./";
|
|
|
import { SCompositeType } from "./enums/SCompositeType";
|
|
|
+import { SArrow } from "./types/SArrow";
|
|
|
+import { SArrowStyleType } from "./enums/SArrowStyleType";
|
|
|
|
|
|
/**
|
|
|
* Painter
|
|
@@ -648,4 +650,230 @@ export class SPainter extends SObject {
|
|
|
toPx(p: number): number {
|
|
|
return p / this.engine.state.matrix.a;
|
|
|
} // Function painterToView()
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 绘制带箭头的线段
|
|
|
+ *
|
|
|
+ * @param line 线段
|
|
|
+ * @param style 线段两端样式
|
|
|
+ */
|
|
|
+ drawArrowLine(line: SLine, style?: SArrow): void {
|
|
|
+ this.engine.drawLine(line);
|
|
|
+ if (style) {
|
|
|
+ if (style.begin) {
|
|
|
+ if (style.begin == SArrowStyleType.Basic) {
|
|
|
+ this.drawBasicArrow(line, false);
|
|
|
+ } else if (style.begin == SArrowStyleType.Triangle) {
|
|
|
+ this.drawTriangleArrow(line, false);
|
|
|
+ } else if (style.begin == SArrowStyleType.Diamond) {
|
|
|
+ this.drawDiamondArrow(line, false);
|
|
|
+ } else if (style.begin == SArrowStyleType.Square) {
|
|
|
+ this.drawSquareArrow(line, false);
|
|
|
+ } else if (style.begin == SArrowStyleType.Circle) {
|
|
|
+ this.drawCircleArrow(line, false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (style.end) {
|
|
|
+ if (style.end == SArrowStyleType.Basic) {
|
|
|
+ this.drawBasicArrow(line, true);
|
|
|
+ } else if (style.end == SArrowStyleType.Triangle) {
|
|
|
+ this.drawTriangleArrow(line, true);
|
|
|
+ } else if (style.end == SArrowStyleType.Diamond) {
|
|
|
+ this.drawDiamondArrow(line, true);
|
|
|
+ } else if (style.end == SArrowStyleType.Square) {
|
|
|
+ this.drawSquareArrow(line, true);
|
|
|
+ } else if (style.end == SArrowStyleType.Circle) {
|
|
|
+ this.drawCircleArrow(line, true);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } // Function drawArrowLine()
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 私有计算方法-绘制线段末端标准箭头
|
|
|
+ *
|
|
|
+ * @param line 要加末端样式的线段
|
|
|
+ * @param isEnd 是否为结束位置
|
|
|
+ * */
|
|
|
+ private drawBasicArrow(line: SLine, isEnd: boolean = true): void {
|
|
|
+ // 定义箭头长度
|
|
|
+ const d = 5;
|
|
|
+ // 箭头横坐标
|
|
|
+ const x1 = d * Math.cos(Math.PI / 4);
|
|
|
+ // 箭头纵坐标
|
|
|
+ const y1 = d * Math.sin(Math.PI / 4);
|
|
|
+ // 线段与x轴夹角
|
|
|
+ const fo = Math.atan(line.dy / line.dx);
|
|
|
+ const ang = line.dx > 0 ? fo : fo + Math.PI;
|
|
|
+ // 是否为终点画箭头
|
|
|
+ if (isEnd) {
|
|
|
+ this.save();
|
|
|
+ this.translate(line.x2, line.y2);
|
|
|
+ this.rotate(ang);
|
|
|
+ this.engine.drawPolyline([
|
|
|
+ new SPoint(-x1, y1),
|
|
|
+ new SPoint(0, 0),
|
|
|
+ new SPoint(-x1, -y1)
|
|
|
+ ]);
|
|
|
+ this.restore();
|
|
|
+ } else {
|
|
|
+ this.save();
|
|
|
+ this.translate(line.x1, line.y1);
|
|
|
+ this.rotate(ang);
|
|
|
+ this.engine.drawPolyline([
|
|
|
+ new SPoint(x1, y1),
|
|
|
+ new SPoint(0, 0),
|
|
|
+ new SPoint(x1, -y1)
|
|
|
+ ]);
|
|
|
+ this.restore();
|
|
|
+ }
|
|
|
+ } // Function drawArrow()
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 私有计算方法-绘制线段末端三角形箭头
|
|
|
+ *
|
|
|
+ * @param line 要加末端样式的线段
|
|
|
+ * @param isEnd 是否为结束位置
|
|
|
+ * */
|
|
|
+ private drawTriangleArrow(line: SLine, isEnd: boolean = true): void {
|
|
|
+ // 定义箭头长度
|
|
|
+ const d = 5;
|
|
|
+ // 箭头横坐标
|
|
|
+ const x1 = d * Math.cos(Math.PI / 12);
|
|
|
+ // 箭头纵坐标
|
|
|
+ const y1 = d * Math.sin(Math.PI / 12);
|
|
|
+ // 线段与x轴夹角
|
|
|
+ const fo = Math.atan(line.dy / line.dx);
|
|
|
+ const ang = line.dx > 0 ? fo : fo + Math.PI;
|
|
|
+ // 是否为终点画箭头
|
|
|
+ if (isEnd) {
|
|
|
+ this.save();
|
|
|
+ this.translate(line.x2, line.y2);
|
|
|
+ this.rotate(ang);
|
|
|
+ this.engine.drawPolygon([
|
|
|
+ new SPoint(-x1, y1),
|
|
|
+ new SPoint(0, 0),
|
|
|
+ new SPoint(-x1, -y1)
|
|
|
+ ]);
|
|
|
+ this.restore();
|
|
|
+ } else {
|
|
|
+ this.save();
|
|
|
+ this.translate(line.x1, line.y1);
|
|
|
+ this.rotate(ang);
|
|
|
+ this.engine.drawPolygon([
|
|
|
+ new SPoint(x1, y1),
|
|
|
+ new SPoint(0, 0),
|
|
|
+ new SPoint(x1, -y1)
|
|
|
+ ]);
|
|
|
+ this.restore();
|
|
|
+ }
|
|
|
+ } // Function drawTriangleArrow()
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 私有计算方法-绘制线段末端菱形箭头
|
|
|
+ *
|
|
|
+ * @param line 要加末端样式的线段
|
|
|
+ * @param isEnd 是否为结束位置
|
|
|
+ * */
|
|
|
+ private drawDiamondArrow(line: SLine, isEnd: boolean = true): void {
|
|
|
+ // 定义箭头长度
|
|
|
+ const d = 5;
|
|
|
+ // 箭头横坐标
|
|
|
+ const x1 = d * Math.cos(Math.PI / 4);
|
|
|
+ // 箭头纵坐标
|
|
|
+ const y1 = d * Math.sin(Math.PI / 4);
|
|
|
+ // 线段与x轴夹角
|
|
|
+ const fo = Math.atan(line.dy / line.dx);
|
|
|
+ const ang = line.dx > 0 ? fo : fo + Math.PI;
|
|
|
+ // 是否为终点画箭头
|
|
|
+ if (isEnd) {
|
|
|
+ this.save();
|
|
|
+ this.translate(line.x2, line.y2);
|
|
|
+ this.rotate(ang);
|
|
|
+ this.engine.drawPolygon([
|
|
|
+ new SPoint(-x1, y1),
|
|
|
+ new SPoint(0, 0),
|
|
|
+ new SPoint(-x1, -y1),
|
|
|
+ new SPoint(-Math.sqrt(2) * d, 0)
|
|
|
+ ]);
|
|
|
+ this.restore();
|
|
|
+ } else {
|
|
|
+ this.save();
|
|
|
+ this.translate(line.x1, line.y1);
|
|
|
+ this.rotate(ang);
|
|
|
+ this.engine.drawPolygon([
|
|
|
+ new SPoint(x1, y1),
|
|
|
+ new SPoint(0, 0),
|
|
|
+ new SPoint(x1, -y1),
|
|
|
+ new SPoint(Math.sqrt(2) * d, 0)
|
|
|
+ ]);
|
|
|
+ this.restore();
|
|
|
+ }
|
|
|
+ } // Function drawDiamondArrow()
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 私有计算方法-绘制线段末端方形箭头
|
|
|
+ *
|
|
|
+ * @param line 要加末端样式的线段
|
|
|
+ * @param isEnd 是否为结束位置
|
|
|
+ * */
|
|
|
+ private drawSquareArrow(line: SLine, isEnd: boolean = true): void {
|
|
|
+ // 定义箭头长度
|
|
|
+ const d = 5;
|
|
|
+ // 线段与x轴夹角
|
|
|
+ const fo = Math.atan(line.dy / line.dx);
|
|
|
+ const ang = line.dx > 0 ? fo : fo + Math.PI;
|
|
|
+ // 是否为终点画箭头
|
|
|
+ if (isEnd) {
|
|
|
+ this.save();
|
|
|
+ this.translate(line.x2, line.y2);
|
|
|
+ this.rotate(ang);
|
|
|
+ this.engine.drawPolygon([
|
|
|
+ new SPoint(-d, d / 2),
|
|
|
+ new SPoint(0, d / 2),
|
|
|
+ new SPoint(0, -d / 2),
|
|
|
+ new SPoint(-d, -d / 2)
|
|
|
+ ]);
|
|
|
+ this.restore();
|
|
|
+ } else {
|
|
|
+ this.save();
|
|
|
+ this.translate(line.x1, line.y1);
|
|
|
+ this.rotate(ang);
|
|
|
+ this.engine.drawPolygon([
|
|
|
+ new SPoint(0, d / 2),
|
|
|
+ new SPoint(d, d / 2),
|
|
|
+ new SPoint(d, -d / 2),
|
|
|
+ new SPoint(0, -d / 2)
|
|
|
+ ]);
|
|
|
+ this.restore();
|
|
|
+ }
|
|
|
+ } // Function drawSquareArrow()
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 私有计算方法-绘制线段末端圆形箭头
|
|
|
+ *
|
|
|
+ * @param line 要加末端样式的线段
|
|
|
+ * @param isEnd 是否为结束位置
|
|
|
+ * */
|
|
|
+ private drawCircleArrow(line: SLine, isEnd: boolean = true): void {
|
|
|
+ // 定义箭头长度
|
|
|
+ const d = 5;
|
|
|
+ // 线段与x轴夹角
|
|
|
+ const fo = Math.atan(line.dy / line.dx);
|
|
|
+ const ang = line.dx > 0 ? fo : fo + Math.PI;
|
|
|
+ // 是否为终点画箭头
|
|
|
+ if (isEnd) {
|
|
|
+ this.save();
|
|
|
+ this.translate(line.x2, line.y2);
|
|
|
+ this.rotate(ang);
|
|
|
+ this.engine.drawCircle(-d / 2, 0, d / 2);
|
|
|
+ this.restore();
|
|
|
+ } else {
|
|
|
+ this.save();
|
|
|
+ this.translate(line.x1, line.y1);
|
|
|
+ this.rotate(ang);
|
|
|
+ this.engine.drawCircle(d / 2, 0, d / 2);
|
|
|
+ this.restore();
|
|
|
+ }
|
|
|
+ } // Function drawCircleArrow()
|
|
|
} // Class SPainter
|