작업중

This commit is contained in:
hyojun.choi 2024-07-23 15:47:08 +09:00
parent 89007b79ac
commit cb38a3815f
4 changed files with 214 additions and 73 deletions

View File

@ -10,6 +10,7 @@ import { useRecoilState, useRecoilValue } from 'recoil'
import { canvasAtom, canvasListState, canvasSizeState, fontSizeState, sortedPolygonArray } from '@/store/canvasAtom' import { canvasAtom, canvasListState, canvasSizeState, fontSizeState, sortedPolygonArray } from '@/store/canvasAtom'
import { QLine } from '@/components/fabric/QLine' import { QLine } from '@/components/fabric/QLine'
import { getTests, getCanvasState, insertCanvasState } from '@/lib/canvas' import { getTests, getCanvasState, insertCanvasState } from '@/lib/canvas'
import { calculateIntersection2 } from '@/util/canvas-util'
export default function Roof2() { export default function Roof2() {
const { canvas, handleRedo, handleUndo, setCanvasBackgroundWithDots, saveImage, addCanvas } = useCanvas('canvas') const { canvas, handleRedo, handleUndo, setCanvasBackgroundWithDots, saveImage, addCanvas } = useCanvas('canvas')
@ -198,7 +199,7 @@ export default function Roof2() {
] ]
if (canvas) { if (canvas) {
const polygon = new QPolygon(eightPoint, { const polygon = new QPolygon(type2, {
fill: 'transparent', fill: 'transparent',
stroke: 'black', stroke: 'black',
strokeWidth: 1, strokeWidth: 1,
@ -232,7 +233,18 @@ export default function Roof2() {
const makeQLine = () => { const makeQLine = () => {
if (canvas) { if (canvas) {
const line = new QLine( const line = new QLine(
[200, 200, 500, 500], [50, 250, 900, 250],
{
stroke: 'black',
strokeWidth: 5,
fontSize: fontSize,
selectable: true,
},
50,
)
const line2 = new QLine(
[450, 450, 821, 78],
{ {
stroke: 'black', stroke: 'black',
strokeWidth: 5, strokeWidth: 5,
@ -243,6 +255,22 @@ export default function Roof2() {
) )
canvas?.add(line) canvas?.add(line)
canvas?.add(line2)
const interSectionPoint = calculateIntersection2(line, line2)
if (interSectionPoint) {
console.log(interSectionPoint)
const circle = new fabric.Circle({
radius: 5,
fill: 'red',
left: interSectionPoint.x - 5,
top: interSectionPoint.y - 5,
})
canvas?.add(circle)
}
} }
} }

View File

@ -73,6 +73,7 @@ export class QLine extends fabric.Group {
}) })
this.on('selected', () => { this.on('selected', () => {
console.log(this)
Object.keys(this.controls).forEach((controlKey) => { Object.keys(this.controls).forEach((controlKey) => {
if (controlKey !== 'ml' && controlKey !== 'mr') { if (controlKey !== 'ml' && controlKey !== 'mr') {
this.setControlVisible(controlKey, false) this.setControlVisible(controlKey, false)

View File

@ -312,7 +312,31 @@ export function calculateIntersection(line1, line2) {
if (t >= 0 && t <= 1 && u >= 0 && u <= 1) { if (t >= 0 && t <= 1 && u >= 0 && u <= 1) {
const intersectionX = x1_1 + t * (x2_1 - x1_1) const intersectionX = x1_1 + t * (x2_1 - x1_1)
const intersectionY = y1_1 + t * (y2_1 - y1_1) const intersectionY = y1_1 + t * (y2_1 - y1_1)
return { x: Math.round(intersectionX), y: Math.round(intersectionY) }
// 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 // 교차점이 선분의 범위 내에 없음 return null // 교차점이 선분의 범위 내에 없음
@ -339,7 +363,6 @@ export const findIntersection1 = (line1, line2) => {
if (determinant === 0) { if (determinant === 0) {
// 두 선이 평행하거나 일직선일 경우 // 두 선이 평행하거나 일직선일 경우
console.log('두 직선은 평행하거나 일직선입니다.')
return null return null
} }
@ -351,7 +374,37 @@ export const findIntersection1 = (line1, line2) => {
export const calculateIntersection2 = (line1, line2) => { export const calculateIntersection2 = (line1, line2) => {
const result = intersect([line1.x1, line1.y1], [line1.x2, line1.y2], [line2.x1, line2.y1], [line2.x2, line2.y2]) const result = intersect([line1.x1, line1.y1], [line1.x2, line1.y2], [line2.x1, line2.y1], [line2.x2, line2.y2])
return { x: Math.round(result[0]), y: Math.round(result[1]) }
if (!result) {
return null
}
// 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)
// Check if the intersection X and Y are within the range of both lines
if (
result[0] >= line1MinX &&
result[0] <= line1MaxX &&
result[0] >= line2MinX &&
result[0] <= line2MaxX &&
result[1] >= line1MinY &&
result[1] <= line1MaxY &&
result[1] >= line2MinY &&
result[1] <= line2MaxY
) {
return { x: Math.round(result[0]), y: Math.round(result[1]) }
} else {
return null // Intersection is out of range
}
} }
export function findOrthogonalPoint(line1, line2) { export function findOrthogonalPoint(line1, line2) {
@ -401,10 +454,10 @@ export const sortedPoints = (points) => {
// y값이 같은 point가 많은 경우 그 중 x값이 가장 큰걸 찾는다. // y값이 같은 point가 많은 경우 그 중 x값이 가장 큰걸 찾는다.
const temp = copyPoints.filter((point) => point.y === currentPoint.y) const temp = copyPoints.filter((point) => point.y === currentPoint.y)
// temp중 x값이 가장 큰 값 // temp중 x값이 가장 큰 값
const max = temp.reduce((prev, current) => (prev.x >= current.x ? prev : current)) const min = temp.reduce((prev, current) => (prev.x <= current.x ? prev : current))
resultPoints.push(max) resultPoints.push(min)
currentPoint = max currentPoint = min
copyPoints.splice(copyPoints.indexOf(max), 1) copyPoints.splice(copyPoints.indexOf(min), 1)
index++ index++
break break
} }
@ -414,11 +467,11 @@ export const sortedPoints = (points) => {
// x값이 같은 point가 많은 경우 그 중 y값이 가장 큰걸 찾는다. // x값이 같은 point가 많은 경우 그 중 y값이 가장 큰걸 찾는다.
const temp = copyPoints.filter((point) => point.x === currentPoint.x) const temp = copyPoints.filter((point) => point.x === currentPoint.x)
// temp중 y값이 가장 큰 값 // temp중 y값이 가장 큰 값
const max = temp.reduce((prev, current) => (prev.y >= current.y ? prev : current)) const min = temp.reduce((prev, current) => (prev.y >= current.y ? prev : current))
resultPoints.push(max) resultPoints.push(min)
currentPoint = max currentPoint = min
copyPoints.splice(copyPoints.indexOf(max), 1) copyPoints.splice(copyPoints.indexOf(min), 1)
index++ index++
break break
} }

View File

@ -49,20 +49,23 @@ export const drawHelpLineInHexagon2 = (polygon, chon) => {
const horizontalLines = oneSideLines.filter((line) => line.direction === 'right') const horizontalLines = oneSideLines.filter((line) => line.direction === 'right')
const verticalLines = oneSideLines.filter((line) => line.direction === 'bottom') const verticalLines = oneSideLines.filter((line) => line.direction === 'bottom')
// horizontalLines 를 y1 좌표 기준으로 정렬한다. // horizontalLines 를 y1 좌표 기준으로 정렬한다.
horizontalLines.sort((a, b) => a.y1 - b.y1) horizontalLines.sort((a, b) => a.y1 - b.y1)
// verticalLines 를 x1 좌표 기준으로 정렬한다. // verticalLines 를 x1 좌표 기준으로 정렬한다.
verticalLines.sort((a, b) => a.x1 - b.x1) verticalLines.sort((a, b) => a.x1 - b.x1)
const horizontalMaxLength = horizontalLines.reduce((max, obj) => Math.max(max, obj.length), 0) const maxHorizontalLineLength = horizontalLines.reduce((prev, current) => (prev.length > current.length ? prev.length : current.length))
const maxVerticalLineLength = verticalLines.reduce((prev, current) => (prev.length > current.length ? prev.length : current.length))
const verticalMaxLength = verticalLines.reduce((max, obj) => Math.max(max, obj.length), 0)
// 모든 가로선의 중심선을 긋는다. // 모든 가로선의 중심선을 긋는다.
debugger
horizontalLines.forEach((line, index) => { horizontalLines.forEach((line, index) => {
const nextLine = horizontalLines[(index + 1) % horizontalLines.length] const nextLine = horizontalLines[(index + 1) % horizontalLines.length]
line.line.set({ strokeWidth: 5 })
nextLine.line.set({ strokeWidth: 5 })
polygon.canvas.renderAll()
const startCenterX = Math.min(line.x1, nextLine.x1) const startCenterX = Math.min(line.x1, nextLine.x1)
const startCenterY = (line.y1 + nextLine.y1) / 2 const startCenterY = (line.y1 + nextLine.y1) / 2
@ -76,8 +79,8 @@ export const drawHelpLineInHexagon2 = (polygon, chon) => {
direction: 'horizontal', direction: 'horizontal',
}) })
polygon.canvas.add(centerLine) /*polygon.canvas.add(centerLine)
polygon.canvas.renderAll() polygon.canvas.renderAll()*/
centerLines.push(centerLine) centerLines.push(centerLine)
}) })
@ -99,14 +102,11 @@ export const drawHelpLineInHexagon2 = (polygon, chon) => {
direction: 'vertical', direction: 'vertical',
}) })
polygon.canvas.add(centerLine) /*polygon.canvas.add(centerLine)
polygon.canvas.renderAll() polygon.canvas.renderAll()*/
centerLines.push(centerLine) centerLines.push(centerLine)
}) })
const maxLength = horizontalMaxLength < verticalMaxLength ? horizontalMaxLength : verticalMaxLength
polygon.points.forEach((point, index) => { polygon.points.forEach((point, index) => {
const wallPoint = polygon.wall.points[index] const wallPoint = polygon.wall.points[index]
// 두 점의 좌표 // 두 점의 좌표
@ -120,50 +120,67 @@ export const drawHelpLineInHexagon2 = (polygon, chon) => {
// x1, y1을 기준으로 x2, y2와의 거리를 유지한 새로운 직선 생성 // x1, y1을 기준으로 x2, y2와의 거리를 유지한 새로운 직선 생성
const angle = Math.atan2(y2 - y1, x2 - x1) const angle = Math.atan2(y2 - y1, x2 - x1)
newX2 = Math.floor(x1 + (maxLength / 2 + 50) * Math.cos(angle)) let previousIndex = index === 0 ? polygon.lines.length - 1 : index - 1
newY2 = Math.floor(y1 + (maxLength / 2 + 50) * Math.sin(angle)) const maxLength = Math.max(polygon.lines[index].length, polygon.lines[previousIndex].length)
newX2 = Math.floor(x1 + (maxLength / 2 + polygon.points.length * 20) * Math.cos(angle))
newY2 = Math.floor(y1 + (maxLength / 2 + polygon.points.length * 20) * Math.sin(angle))
const line = new QLine([x1, y1, newX2, newY2], { const line = new QLine([x1, y1, newX2, newY2], {
fontSize: polygon.fontSize, fontSize: polygon.fontSize,
stroke: 'green', stroke: 'green',
idx: index, idx: index,
}) })
line.set({ degree: fabric.util.radiansToDegrees(angle) })
polygon.canvas.add(line) polygon.canvas.add(line)
helpLines.push(line) helpLines.push(line)
polygon.canvas.renderAll() polygon.canvas.renderAll()
debugger
}) })
helpLines.forEach((line, index) => { helpLines.forEach((line, index) => {
if (line.isAlreadyInterSection) { for (let i = index + 1; i < helpLines.length; i++) {
return const nextLine = helpLines[i]
if (line.isAlreadyInterSection || nextLine.isAlreadyInterSection) {
continue
}
let intersectionPoint = calculateIntersection(line, nextLine)
if (!intersectionPoint) {
continue
}
const circle = new fabric.Circle({
radius: 3,
fill: 'red',
left: intersectionPoint.x - 3,
top: intersectionPoint.y - 3,
})
polygon.canvas.add(circle)
line.set({ isAlreadyInterSection: true })
nextLine.set({ isAlreadyInterSection: true })
const helpLine1 = new QLine([nextLine.x1, nextLine.y1, intersectionPoint.x, intersectionPoint.y], {
fontSize: polygon.fontSize,
stroke: 'skyblue',
})
const helpLine2 = new QLine([line.x1, line.y1, intersectionPoint.x, intersectionPoint.y], {
fontSize: polygon.fontSize,
stroke: 'skyblue',
})
ridgeStartPoints.push(intersectionPoint)
polygon.canvas.add(helpLine1)
polygon.canvas.add(helpLine2)
polygon.canvas.remove(nextLine)
polygon.canvas.remove(line)
polygon.canvas.renderAll()
} }
const nextLine = helpLines[(index + 1 + helpLines.length) % helpLines.length]
polygon.canvas.renderAll()
let intersectionPoint = calculateIntersection(line, nextLine)
if (!intersectionPoint) {
return
}
line.set({ isAlreadyInterSection: true })
nextLine.set({ isAlreadyInterSection: true })
const helpLine1 = new QLine([nextLine.x1, nextLine.y1, intersectionPoint.x, intersectionPoint.y], {
fontSize: polygon.fontSize,
stroke: 'skyblue',
})
const helpLine2 = new QLine([line.x1, line.y1, intersectionPoint.x, intersectionPoint.y], {
fontSize: polygon.fontSize,
stroke: 'skyblue',
})
ridgeStartPoints.push(intersectionPoint)
polygon.canvas.add(helpLine1)
polygon.canvas.add(helpLine2)
polygon.canvas.remove(nextLine)
polygon.canvas.remove(line)
polygon.canvas.renderAll()
}) })
// 안만나는 선들 // 안만나는 선들
@ -172,30 +189,70 @@ export const drawHelpLineInHexagon2 = (polygon, chon) => {
const interSectionPoints = [] const interSectionPoints = []
notInterSectionLines.forEach((line, index) => { notInterSectionLines.forEach((line, index) => {
line.line.set({ strokeWidth: (index + 1) * 5 }) let subCenterLines
if (maxHorizontalLineLength > maxVerticalLineLength) {
if (Math.abs(line.degree) < 90) {
subCenterLines = centerLines.filter((centerLine) => centerLine.direction === 'horizontal')
} else {
subCenterLines = centerLines.filter((centerLine) => centerLine.direction === 'vertical')
}
} else {
if (Math.abs(line.degree) < 90) {
subCenterLines = centerLines.filter((centerLine) => centerLine.direction === 'vertical')
} else {
subCenterLines = centerLines.filter((centerLine) => centerLine.direction === 'horizontal')
}
}
centerLines.forEach((centerLine) => { centerLines.forEach((centerLine) => {
const interSectionPoint = findIntersection1(line, centerLine) const interSectionPoint = calculateIntersection2(line, centerLine)
console.log('interSectionPoint', interSectionPoint)
if (!polygon.inPolygon(interSectionPoint) || !interSectionPoint) { if (!interSectionPoint) {
return return
} }
line.interSectionPoints.push(interSectionPoint)
interSectionPoints.push(interSectionPoint) ridgeStartPoints.forEach((point) => {
if (Math.abs(interSectionPoint.x - point.x) <= 2 || Math.abs(interSectionPoint.y - point.y) <= 2) {
line.interSectionPoints.push(interSectionPoint)
interSectionPoints.push(interSectionPoint)
const newLine = new QLine([line.x1, line.y1, interSectionPoint.x, interSectionPoint.y], {
stroke: 'black',
fontSize: polygon.fontSize,
})
const circle = new fabric.Circle({
radius: 3,
fill: 'blue',
left: interSectionPoint.x - 3,
top: interSectionPoint.y - 3,
})
polygon.canvas.add(circle)
polygon.canvas.add(newLine)
polygon.canvas.remove(line)
line.set({ isAlreadyInterSection: true })
}
})
}) })
}) })
interSectionPoints.forEach((point) => { ridgeStartPoints.forEach((point, index) => {
const circle = new fabric.Circle({ for (let i = index + 1; i < ridgeStartPoints.length; i++) {
radius: 3, const currentPoint = ridgeStartPoints[index]
fill: 'red', const nextPoint = ridgeStartPoints[i]
left: point.x,
top: point.y,
})
polygon.canvas.add(circle) if (currentPoint.x === nextPoint.x || currentPoint.y === nextPoint.y) {
polygon.canvas.renderAll() const ridge = new QLine([currentPoint.x, currentPoint.y, nextPoint.x, nextPoint.y], {
stroke: 'black',
fontSize: polygon.fontSize,
})
polygon.canvas.add(ridge)
polygon.canvas.renderAll()
break
}
}
}) })
ridgeStartPoints.forEach((point, index) => { ridgeStartPoints.forEach((point, index) => {
@ -203,7 +260,7 @@ export const drawHelpLineInHexagon2 = (polygon, chon) => {
let distance = Infinity let distance = Infinity
let startPoint let startPoint
interSectionPoints.forEach((interSectionPoint) => { interSectionPoints.forEach((interSectionPoint) => {
if (Math.abs(point.x - interSectionPoint.x) < 3 || Math.abs(point.y - interSectionPoint.y) < 3) { if (Math.abs(point.x - interSectionPoint.x) < 1 || Math.abs(point.y - interSectionPoint.y) < 1) {
if (distanceBetweenPoints(point, interSectionPoint) < distance) { if (distanceBetweenPoints(point, interSectionPoint) < distance) {
startPoint = point startPoint = point
distance = distanceBetweenPoints(point, interSectionPoint) distance = distanceBetweenPoints(point, interSectionPoint)
@ -230,10 +287,11 @@ export const drawHelpLineInHexagon2 = (polygon, chon) => {
polygon.canvas.add(helpLine) polygon.canvas.add(helpLine)
polygon.canvas.remove(line) polygon.canvas.remove(line)
polygon.canvas.renderAll() polygon.canvas.renderAll()
debugger
} }
}) })
for (let i = 0; i < ridgeEndPoints.length; i = i + 2) { /*for (let i = 0; i < ridgeEndPoints.length; i = i + 2) {
const currentRidgeEndPoint = ridgeEndPoints[i] const currentRidgeEndPoint = ridgeEndPoints[i]
const nextRidgeEndPoint = ridgeEndPoints[(i + 1) % ridgeEndPoints.length] const nextRidgeEndPoint = ridgeEndPoints[(i + 1) % ridgeEndPoints.length]
const ridgeConnectLine = new QLine([currentRidgeEndPoint.x, currentRidgeEndPoint.y, nextRidgeEndPoint.x, nextRidgeEndPoint.y], { const ridgeConnectLine = new QLine([currentRidgeEndPoint.x, currentRidgeEndPoint.y, nextRidgeEndPoint.x, nextRidgeEndPoint.y], {
@ -243,7 +301,8 @@ export const drawHelpLineInHexagon2 = (polygon, chon) => {
polygon.canvas.add(ridgeConnectLine) polygon.canvas.add(ridgeConnectLine)
polygon.canvas.renderAll() polygon.canvas.renderAll()
} debugger
}*/
} }
export const drawHelpLineInHexagon = (polygon, chon) => { export const drawHelpLineInHexagon = (polygon, chon) => {