728x90
반응형
목표
edge에 가중치를 넣을 수 있게 만들어볼 생각입니다.
결과
우선 Edge 클래스의 필드로 value를 가질 수 있게 했습니다.
export class Edge {
firstEdgePoint: Point;
secondEdgePoint: Point;
firstCenterPoint: Point;
secondCenterPoint: Point;
direction: boolean; // true: first to second, false: second to first
value: number | null;
constructor(
firstEdgePoint: Point,
secondEdgePoint: Point,
firstCenterPoint: Point,
secondCenterPoint: Point,
direction: boolean,
value: number | null
) {
this.firstEdgePoint = firstEdgePoint;
this.secondEdgePoint = secondEdgePoint;
this.firstCenterPoint = firstCenterPoint;
this.secondCenterPoint = secondCenterPoint;
this.direction = direction;
this.value = value;
}
...
가중치가 없는 경우도 대비하여 number 또는 null이 들어갈 수 있도록 했습니다.
가중치가 표시되는 위치는 edge가 수평일때, 왼쪽에서 오른쪽으로 그려지면 가중치를 위쪽에 표시하고
edge가 수직일때는 위에서 아래 방향이면 오른쪽에 표시하도록 했습니다.(방향이 반대가 되면 가중치의 위치도 반대로 표시합니다.)
먼저 edge의 중점을 찾고, 그려질 글씨의 높이와 너비를 계산하여 2로 나눈 만큼 움직이면 다음과 같이 그려집니다.
이제 위에서 정의한 대로 가중치가 표시되는 위치를 조정해보겠습니다.
따라서 가중치가 표시되는 그래프를 그릴 수 있게 되었습니다.
edge를 그리는 코드는 다음과 같습니다.
static drawEdge(ctx: CanvasRenderingContext2D, edge: Edge) {
let startEdgePoint: Point;
let endEdgePoint: Point;
let startCenterPoint: Point;
let endCenterPoint: Point;
if (edge.direction) {
startEdgePoint = edge.firstEdgePoint;
endEdgePoint = edge.secondEdgePoint;
startCenterPoint = edge.firstCenterPoint;
endCenterPoint = edge.secondCenterPoint;
} else {
startEdgePoint = edge.secondEdgePoint;
endEdgePoint = edge.firstEdgePoint;
startCenterPoint = edge.secondCenterPoint;
endCenterPoint = edge.firstCenterPoint;
}
const startToEndAngle = Point.getAngle(startCenterPoint, endCenterPoint);
const endToStartAngle = Point.getAngle(endCenterPoint, startCenterPoint);
const rotatedStart = Point.getRotatedPoint(
new Point(50, 0),
startToEndAngle
);
const rotatedEnd = Point.getRotatedPoint(new Point(50, 0), endToStartAngle);
startEdgePoint = new Point(
rotatedStart.x + startCenterPoint.x,
rotatedStart.y + startCenterPoint.y
);
endEdgePoint = new Point(
rotatedEnd.x + endCenterPoint.x,
rotatedEnd.y + endCenterPoint.y
);
ctx.beginPath();
ctx.strokeStyle = "black";
ctx.lineWidth = 3;
ctx.moveTo(startEdgePoint.x, startEdgePoint.y);
if (edge.value !== null) {
const textPositionX =
Math.max(endEdgePoint.x, startEdgePoint.x) -
Math.abs(endEdgePoint.x - startEdgePoint.x) / 2;
const textPositionY =
Math.max(endEdgePoint.y, startEdgePoint.y) -
Math.abs(endEdgePoint.y - startEdgePoint.y) / 2;
ctx.font = "18px inferit";
const textMeasure = ctx.measureText(edge.value!.toString());
const textWidth = textMeasure.width;
let adjustedX = 0;
let adjustedY = 0;
if (endEdgePoint.x > startEdgePoint.x) {
adjustedY -= textMeasure.actualBoundingBoxAscent * 1.5;
} else if (endEdgePoint.x < startEdgePoint.x) {
adjustedY += textMeasure.actualBoundingBoxAscent * 1.5;
} else {
if (endEdgePoint.y > startEdgePoint.y) {
adjustedX += textWidth;
} else if (endEdgePoint.y < startEdgePoint.y) {
adjustedX -= textWidth;
}
}
ctx.fillText(
edge.value!.toString(),
textPositionX - textWidth / 2 + adjustedX,
textPositionY + textMeasure.fontBoundingBoxAscent / 2.5 + adjustedY
);
}
ctx.lineTo(endEdgePoint.x, endEdgePoint.y);
ctx.stroke();
this.getArrow(ctx, startEdgePoint, endEdgePoint);
}
'기타 > 모각코' 카테고리의 다른 글
[2022 동계 모각코 - 1회차] 회고 (0) | 2022.12.29 |
---|---|
[2022 동계 모각코 - 1회차] 목표 (0) | 2022.12.29 |
[2022 하계 모각코] 6회차 목표 (0) | 2022.08.07 |
[2022 하계 모각코] 5회차 결과 (0) | 2022.08.01 |
[2022 하계 모각코] 5회차 목표 (0) | 2022.07.31 |