polygon 나누는 함수 수정
This commit is contained in:
parent
69568966ba
commit
46ecb8fdee
@ -2,7 +2,7 @@ import { fabric } from 'fabric'
|
|||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
import { QLine } from '@/components/fabric/QLine'
|
import { QLine } from '@/components/fabric/QLine'
|
||||||
import { distanceBetweenPoints, findTopTwoIndexesByDistance, getDirectionByPoint, sortedPointLessEightPoint, sortedPoints } from '@/util/canvas-util'
|
import { distanceBetweenPoints, findTopTwoIndexesByDistance, getDirectionByPoint, sortedPointLessEightPoint, sortedPoints } from '@/util/canvas-util'
|
||||||
import { calculateAngle, dividePolygon, drawHelpLineInHexagon } from '@/util/qpolygon-utils'
|
import { calculateAngle, dividePolygon, drawHelpLineInHexagon, splitPolygonWithLines } from '@/util/qpolygon-utils'
|
||||||
|
|
||||||
export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
||||||
type: 'QPolygon',
|
type: 'QPolygon',
|
||||||
@ -450,6 +450,6 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
divideLine() {
|
divideLine() {
|
||||||
dividePolygon(this)
|
splitPolygonWithLines(this)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { fabric } from 'fabric'
|
|||||||
import { QLine } from '@/components/fabric/QLine'
|
import { QLine } from '@/components/fabric/QLine'
|
||||||
import { calculateIntersection, distanceBetweenPoints, findClosestPoint, getDirectionByPoint } from '@/util/canvas-util'
|
import { calculateIntersection, distanceBetweenPoints, findClosestPoint, getDirectionByPoint } from '@/util/canvas-util'
|
||||||
import { QPolygon } from '@/components/fabric/QPolygon'
|
import { QPolygon } from '@/components/fabric/QPolygon'
|
||||||
|
import polygonSplitter from 'polygon-splitter'
|
||||||
|
|
||||||
const TWO_PI = Math.PI * 2
|
const TWO_PI = Math.PI * 2
|
||||||
|
|
||||||
@ -954,3 +955,127 @@ export default function offsetPolygon(vertices, offset) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const splitPolygonWithLines = (polygon) => {
|
||||||
|
//todo: polygon의 모든 line들 모음 hip, ridge, connectRidge
|
||||||
|
const allLines = [...polygon.hips, ...polygon.ridges, ...polygon.connectRidges]
|
||||||
|
|
||||||
|
polygon.points.forEach((point, index) => {
|
||||||
|
allLines.forEach((line) => {
|
||||||
|
if (line.endPoint.x === point.x && line.endPoint.y === point.y) {
|
||||||
|
const temp = line.startPoint
|
||||||
|
line.startPoint = line.endPoint
|
||||||
|
line.endPoint = temp
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
polygon.points.forEach((point, index) => {
|
||||||
|
const routes = []
|
||||||
|
|
||||||
|
const polygonPoints = [...polygon.points].map((point, index) => {
|
||||||
|
return { ...point, index }
|
||||||
|
})
|
||||||
|
|
||||||
|
// 시작점은 시작 hip라인의 출발점
|
||||||
|
const startPoint = point
|
||||||
|
// 도착점은 마지막 hip라인의 끝나는 점
|
||||||
|
const endPoint = polygon.points[(index + 1) % polygon.points.length]
|
||||||
|
|
||||||
|
const startLine = allLines.find((line) => line.startPoint.x === startPoint.x && line.startPoint.y === startPoint.y)
|
||||||
|
const endLine = allLines.find((line) => line.startPoint.x === endPoint.x && line.startPoint.y === endPoint.y)
|
||||||
|
|
||||||
|
const arrivalPoint = endLine.endPoint
|
||||||
|
routes.push(startLine.startPoint)
|
||||||
|
routes.push(startLine.endPoint)
|
||||||
|
//hip끼리 만나는 경우는 아무것도 안해도됨
|
||||||
|
if (!isSamePoint(startLine.endPoint, arrivalPoint)) {
|
||||||
|
// polygon line까지 추가
|
||||||
|
const allLinesCopy = [...allLines, ...polygon.lines]
|
||||||
|
// hip이 만나지 않는 경우 갈 수 있는 길을 다 돌아야함
|
||||||
|
let currentPoint = startLine.endPoint
|
||||||
|
let currentLine = startLine
|
||||||
|
|
||||||
|
while (!isSamePoint(currentPoint, arrivalPoint)) {
|
||||||
|
// startHip에서 만나는 출발선 두개. 두개의 선을 출발하여 arrivalPoint에 도착할 때 까지 count를 세고, 더 낮은 count를 가진 길을 선택한다.
|
||||||
|
let connectedLines = allLinesCopy.filter(
|
||||||
|
(line) => isSamePoint(line.startPoint, currentPoint) || (isSamePoint(line.endPoint, currentPoint) && line !== currentLine),
|
||||||
|
)
|
||||||
|
|
||||||
|
if (connectedLines.length === 0) {
|
||||||
|
throw new Error('connectedLines is empty')
|
||||||
|
}
|
||||||
|
|
||||||
|
let tempPoints = []
|
||||||
|
|
||||||
|
for (let i = 0; i < connectedLines.length; i++) {
|
||||||
|
if (isSamePoint(connectedLines[i].startPoint, currentPoint)) {
|
||||||
|
tempPoints.push({ point: connectedLines[i].endPoint, index: i, line: connectedLines[i] })
|
||||||
|
} else {
|
||||||
|
tempPoints.push({ point: connectedLines[i].startPoint, index: i, line: connectedLines[i] })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//tempPoints에서 arrivalPoint와 가장 가까운 점을 찾는다.
|
||||||
|
let minDistance = Number.MAX_SAFE_INTEGER
|
||||||
|
let minIndex = 0
|
||||||
|
tempPoints.forEach((tempPoint, index) => {
|
||||||
|
const distance = Math.sqrt(Math.pow(tempPoint.point.x - arrivalPoint.x, 2) + Math.pow(tempPoint.point.y - arrivalPoint.y, 2))
|
||||||
|
if (distance < minDistance) {
|
||||||
|
minDistance = distance
|
||||||
|
minIndex = tempPoint.index
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
currentPoint = tempPoints[minIndex].point
|
||||||
|
currentLine = tempPoints[minIndex].line
|
||||||
|
routes.push(currentPoint)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
routes.push(endLine.startPoint)
|
||||||
|
const roof = new QPolygon(routes, {
|
||||||
|
fontSize: polygon.fontSize,
|
||||||
|
stroke: 'black',
|
||||||
|
fill: 'transparent',
|
||||||
|
strokeWidth: 3,
|
||||||
|
name: 'roof',
|
||||||
|
})
|
||||||
|
|
||||||
|
polygon.canvas.add(roof)
|
||||||
|
polygon.canvas.renderAll()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const isSamePoint = (a, b) => {
|
||||||
|
return a.x === b.x && a.y === b.y
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the angle between two lines.
|
||||||
|
* @param {Object} line1 - The first line defined by two points {x1, y1} and {x2, y2}.
|
||||||
|
* @param {Object} line2 - The second line defined by two points {x1, y1} and {x2, y2}.
|
||||||
|
* @returns {number} - The angle between the two lines in degrees.
|
||||||
|
*/
|
||||||
|
function calculateAngleBetweenLines(line1, line2) {
|
||||||
|
const { x1: x1_1, y1: y1_1, x2: x2_1, y2: y2_1 } = line1
|
||||||
|
const { x1: x1_2, y1: y1_2, x2: x2_2, y2: y2_2 } = line2
|
||||||
|
|
||||||
|
// Calculate direction vectors
|
||||||
|
const vector1 = { x: x2_1 - x1_1, y: y2_1 - y1_1 }
|
||||||
|
const vector2 = { x: x2_2 - x1_2, y: y2_2 - y1_2 }
|
||||||
|
|
||||||
|
// Calculate dot product and magnitudes
|
||||||
|
const dotProduct = vector1.x * vector2.x + vector1.y * vector2.y
|
||||||
|
const magnitude1 = Math.sqrt(vector1.x * vector1.x + vector1.y * vector1.y)
|
||||||
|
const magnitude2 = Math.sqrt(vector2.x * vector2.x + vector2.y * vector2.y)
|
||||||
|
|
||||||
|
// Calculate the cosine of the angle
|
||||||
|
const cosTheta = dotProduct / (magnitude1 * magnitude2)
|
||||||
|
|
||||||
|
// Calculate the angle in radians and then convert to degrees
|
||||||
|
const angleInRadians = Math.acos(cosTheta)
|
||||||
|
const angleInDegrees = (angleInRadians * 180) / Math.PI
|
||||||
|
|
||||||
|
return angleInDegrees
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user