Merge branch 'feature/test' into test-yj
This commit is contained in:
commit
6bf0a934c2
@ -126,16 +126,20 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
||||
points.forEach((start, i) => {
|
||||
const thisText = this.canvas.getObjects().find((obj) => obj.name === 'lengthText' && obj.parentId === this.id && obj.idx === i)
|
||||
|
||||
if (thisText) {
|
||||
thisText.set({ left: (start.x + points[(i + 1) % points.length].x) / 2, top: (start.y + points[(i + 1) % points.length].y) / 2 })
|
||||
return
|
||||
}
|
||||
|
||||
const end = points[(i + 1) % points.length]
|
||||
const dx = end.x - start.x
|
||||
const dy = end.y - start.y
|
||||
const length = Math.sqrt(dx * dx + dy * dy)
|
||||
|
||||
if (thisText) {
|
||||
thisText.set({
|
||||
left: (start.x + points[(i + 1) % points.length].x) / 2,
|
||||
top: (start.y + points[(i + 1) % points.length].y) / 2,
|
||||
text: length.toFixed(0),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
const midPoint = new fabric.Point((start.x + end.x) / 2, (start.y + end.y) / 2)
|
||||
|
||||
// Create new text object if it doesn't exist
|
||||
@ -168,38 +172,46 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
||||
this.canvas = canvas
|
||||
},
|
||||
fillCell(cell = { width: 50, height: 100, padding: 10 }) {
|
||||
const points = this.getCurrentPoints()
|
||||
let bounds
|
||||
const points = this.points
|
||||
const minX = Math.min(...points.map((p) => p.x))
|
||||
const maxX = Math.max(...points.map((p) => p.x))
|
||||
const minY = Math.min(...points.map((p) => p.y))
|
||||
const maxY = Math.max(...points.map((p) => p.y))
|
||||
|
||||
try {
|
||||
bounds = fabric.util.makeBoundingBoxFromPoints(points)
|
||||
} catch (error) {
|
||||
alert('다각형의 꼭지점이 4개 이상이어야 합니다.')
|
||||
return
|
||||
}
|
||||
const boundingBoxWidth = maxX - minX
|
||||
const boundingBoxHeight = maxY - minY
|
||||
|
||||
for (let x = bounds.left; x < bounds.left + bounds.width; x += cell.width + cell.padding) {
|
||||
for (let y = bounds.top; y < bounds.top + bounds.height; y += cell.height + cell.padding) {
|
||||
const rect = new fabric.Rect({
|
||||
left: x,
|
||||
top: y,
|
||||
width: cell.width,
|
||||
height: cell.height,
|
||||
fill: 'transparent',
|
||||
stroke: 'black',
|
||||
selectable: false,
|
||||
})
|
||||
const rectWidth = cell.width
|
||||
const rectHeight = cell.height
|
||||
|
||||
const cols = Math.floor((boundingBoxWidth + cell.padding) / (rectWidth + cell.padding))
|
||||
const rows = Math.floor((boundingBoxHeight + cell.padding) / (rectHeight + cell.padding))
|
||||
|
||||
for (let i = 0; i < cols; i++) {
|
||||
for (let j = 0; j < rows; j++) {
|
||||
const rectLeft = minX + i * (rectWidth + cell.padding)
|
||||
const rectTop = minY + j * (rectHeight + cell.padding)
|
||||
|
||||
const rectPoints = [
|
||||
new fabric.Point(rect.left, rect.top),
|
||||
new fabric.Point(rect.left + rect.width, rect.top),
|
||||
new fabric.Point(rect.left, rect.top + rect.height),
|
||||
new fabric.Point(rect.left + rect.width, rect.top + rect.height),
|
||||
{ x: rectLeft, y: rectTop },
|
||||
{ x: rectLeft + rectWidth, y: rectTop },
|
||||
{ x: rectLeft, y: rectTop + rectHeight },
|
||||
{ x: rectLeft + rectWidth, y: rectTop + rectHeight },
|
||||
]
|
||||
|
||||
const isInside = rectPoints.every((rectPoint) => this.inPolygon(rectPoint) && this.distanceFromEdge(rectPoint) >= cell.padding)
|
||||
const allPointsInside = rectPoints.every((point) => this.inPolygon(point))
|
||||
|
||||
if (allPointsInside) {
|
||||
const rect = new fabric.Rect({
|
||||
left: rectLeft,
|
||||
top: rectTop,
|
||||
width: rectWidth,
|
||||
height: rectHeight,
|
||||
stroke: 'black', // or any other color
|
||||
fill: 'transparent',
|
||||
selectable: false,
|
||||
})
|
||||
|
||||
if (isInside) {
|
||||
this.canvas.add(rect)
|
||||
}
|
||||
}
|
||||
|
||||
@ -292,56 +292,6 @@ export const getDirectionByPoint = (a, b) => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 두 선분의 교차점을 찾는 함수입니다. 이 함수는 두 선분이 실제로 교차하는 지점 내에서 교차하는지 확인합니다.
|
||||
* @param {Object} line1 첫 번째 선분, {x1, y1, x2, y2} 형태의 객체
|
||||
* @param {Object} line2 두 번째 선분, {x1, y1, x2, y2} 형태의 객체
|
||||
* @returns {{x: number, y: number}|null} 교차점의 좌표를 반환하거나, 교차점이 없으면 null을 반환합니다.
|
||||
*/
|
||||
export function calculateIntersection(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
|
||||
|
||||
const denominator = (x1_1 - x2_1) * (y1_2 - y2_2) - (y1_1 - y2_1) * (x1_2 - x2_2)
|
||||
if (denominator === 0) return null // 선분이 평행하거나 일치하는 경우
|
||||
|
||||
const t = ((x1_1 - x1_2) * (y1_2 - y2_2) - (y1_1 - y1_2) * (x1_2 - x2_2)) / denominator
|
||||
const u = -((x1_1 - x2_1) * (y1_1 - y1_2) - (y1_1 - y2_1) * (x1_1 - x1_2)) / denominator
|
||||
|
||||
// t와 u가 모두 0과 1 사이에 있을 때, 선분 내에서 교차
|
||||
if (t >= 0 && t <= 1 && u >= 0 && u <= 1) {
|
||||
const intersectionX = x1_1 + t * (x2_1 - x1_1)
|
||||
const intersectionY = y1_1 + t * (y2_1 - y1_1)
|
||||
|
||||
// Determine the min and max for line1 and line2 for both x and y
|
||||
const line1MinX = Math.min(line1.x1, line1.x2)
|
||||
const line1MaxX = Math.max(line1.x1, line1.x2)
|
||||
const line2MinX = Math.min(line2.x1, line2.x2)
|
||||
const line2MaxX = Math.max(line2.x1, line2.x2)
|
||||
|
||||
const line1MinY = Math.min(line1.y1, line1.y2)
|
||||
const line1MaxY = Math.max(line1.y1, line1.y2)
|
||||
const line2MinY = Math.min(line2.y1, line2.y2)
|
||||
const line2MaxY = Math.max(line2.y1, line2.y2)
|
||||
|
||||
// 교차점이 선분의 범위 내에 있는지 확인
|
||||
if (
|
||||
intersectionX >= line1MinX &&
|
||||
intersectionX <= line1MaxX &&
|
||||
intersectionX >= line2MinX &&
|
||||
intersectionX <= line2MaxX &&
|
||||
intersectionY >= line1MinY &&
|
||||
intersectionY <= line1MaxY &&
|
||||
intersectionY >= line2MinY &&
|
||||
intersectionY <= line2MaxY
|
||||
) {
|
||||
return { x: Math.round(intersectionX), y: Math.round(intersectionY) }
|
||||
}
|
||||
}
|
||||
|
||||
return null // 교차점이 선분의 범위 내에 없음
|
||||
}
|
||||
|
||||
export const findIntersection1 = (line1, line2) => {
|
||||
const { x1, y1, x2, y2 } = line1 // 첫 번째 선의 두 점
|
||||
|
||||
@ -372,7 +322,7 @@ export const findIntersection1 = (line1, line2) => {
|
||||
return { x, y }
|
||||
}
|
||||
|
||||
export const calculateIntersection2 = (line1, line2) => {
|
||||
export const calculateIntersection = (line1, line2) => {
|
||||
const result = intersect([line1.x1, line1.y1], [line1.x2, line1.y2], [line2.x1, line2.y1], [line2.x2, line2.y2])
|
||||
|
||||
if (!result) {
|
||||
@ -425,68 +375,51 @@ export function findOrthogonalPoint(line1, line2) {
|
||||
*/
|
||||
export const sortedPoints = (points) => {
|
||||
const copyPoints = [...points]
|
||||
//points를 x,y좌표를 기준으로 정렬합니다.
|
||||
copyPoints.sort((a, b) => {
|
||||
if (a.x === b.x) {
|
||||
return a.y - b.y
|
||||
}
|
||||
return a.x - b.x
|
||||
copyPoints.forEach((point) => {
|
||||
point.x1 = point.x
|
||||
point.y1 = point.y
|
||||
const nextPoint = copyPoints[(copyPoints.indexOf(point) + 1) % copyPoints.length]
|
||||
point.x2 = nextPoint.x
|
||||
point.y2 = nextPoint.y
|
||||
})
|
||||
|
||||
// 이때 copyPoints를 순회하며 최초엔 x값을 비교하여 같은 점을 찾는다. 이때 이 점이 2번째 점이 된다.
|
||||
// 그 다음점은 2번째 점과 y값이 같은 점이 된다.
|
||||
// 또 그다음 점은 3번째 점과 x값이 같은 점이 된다.
|
||||
// 이를 반복하여 copyPoints를 재배열한다.
|
||||
const resultPoints = [copyPoints[0]]
|
||||
let index = 1
|
||||
let currentPoint = { ...copyPoints[0] }
|
||||
copyPoints.splice(0, 1)
|
||||
while (index < points.length) {
|
||||
if (index === points.length - 1) {
|
||||
resultPoints.push(copyPoints[0])
|
||||
index++
|
||||
// copyPoint에서 x1, y1 값을 기준으로 시작 인덱스
|
||||
const startIndex = getStartIndex(copyPoints)
|
||||
const startDirection = getDirectionByPoint(
|
||||
{ x: copyPoints[startIndex].x1, y: copyPoints[startIndex].y1 },
|
||||
{ x: copyPoints[startIndex].x2, y: copyPoints[startIndex].y2 },
|
||||
)
|
||||
|
||||
const resultPoints = [copyPoints[startIndex]]
|
||||
|
||||
let currentPoint = copyPoints[startIndex]
|
||||
|
||||
switch (startDirection) {
|
||||
case 'right': {
|
||||
copyPoints.forEach((point, index) => {
|
||||
if (index === startIndex) return
|
||||
|
||||
const nextPoint = copyPoints.find((p) => p.x2 === currentPoint.x && p.y2 === currentPoint.y)
|
||||
resultPoints.push(nextPoint)
|
||||
currentPoint = nextPoint
|
||||
})
|
||||
break
|
||||
} else if (index % 2 === 0) {
|
||||
// 짝수번째는 y값이 같은 점을 찾는다.
|
||||
for (let i = 0; i < copyPoints.length; i++) {
|
||||
// y값이 같은 point가 많은 경우 그 중 x값이 가장 큰걸 찾는다.
|
||||
let temp = copyPoints.filter((point) => point.y === currentPoint.y)
|
||||
if (temp.length === 0) {
|
||||
// temp가 비어있을 경우 copyPoints에서 가장 가까운 점을 찾는다.
|
||||
temp = Array.of(findClosestPointByY(currentPoint, copyPoints))
|
||||
}
|
||||
// temp중 x값이 가장 가까운 값
|
||||
}
|
||||
case 'bottom': {
|
||||
copyPoints.forEach((point, index) => {
|
||||
if (index === startIndex) return
|
||||
|
||||
const min = temp.reduce((prev, current) => (Math.abs(current.x - currentPoint.x) <= Math.abs(prev.x - currentPoint.x) ? current : prev))
|
||||
|
||||
resultPoints.push(min)
|
||||
currentPoint = min
|
||||
copyPoints.splice(copyPoints.indexOf(min), 1)
|
||||
index++
|
||||
break
|
||||
}
|
||||
} else {
|
||||
// 홀수번째는 x값이 같은 점을 찾는다.
|
||||
for (let i = 0; i < copyPoints.length; i++) {
|
||||
// x값이 같은 point가 많은 경우 그 중 y값이 가장 큰걸 찾는다.
|
||||
let temp = copyPoints.filter((point) => point.x === currentPoint.x)
|
||||
if (temp.length === 0) {
|
||||
// temp가 비어있을 경우 copyPoints에서 가장 가까운 점을 찾는다.
|
||||
|
||||
temp = Array.of(findClosestPointByX(currentPoint, copyPoints))
|
||||
}
|
||||
// temp중 y값이 가장 가까운 값
|
||||
const min = temp.reduce((prev, current) => (Math.abs(current.y - currentPoint.y) <= Math.abs(prev.y - currentPoint.y) ? current : prev))
|
||||
|
||||
resultPoints.push(min)
|
||||
currentPoint = min
|
||||
copyPoints.splice(copyPoints.indexOf(min), 1)
|
||||
index++
|
||||
break
|
||||
}
|
||||
const nextPoint = copyPoints.find((p) => p.x1 === currentPoint.x2 && p.y1 === currentPoint.y2)
|
||||
resultPoints.push(nextPoint)
|
||||
currentPoint = nextPoint
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
return resultPoints
|
||||
|
||||
return resultPoints.map((point) => {
|
||||
return { x: point.x, y: point.y }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user