작업중

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 { QLine } from '@/components/fabric/QLine'
import { getTests, getCanvasState, insertCanvasState } from '@/lib/canvas'
import { calculateIntersection2 } from '@/util/canvas-util'
export default function Roof2() {
const { canvas, handleRedo, handleUndo, setCanvasBackgroundWithDots, saveImage, addCanvas } = useCanvas('canvas')
@ -198,7 +199,7 @@ export default function Roof2() {
]
if (canvas) {
const polygon = new QPolygon(eightPoint, {
const polygon = new QPolygon(type2, {
fill: 'transparent',
stroke: 'black',
strokeWidth: 1,
@ -232,7 +233,18 @@ export default function Roof2() {
const makeQLine = () => {
if (canvas) {
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',
strokeWidth: 5,
@ -243,6 +255,22 @@ export default function Roof2() {
)
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', () => {
console.log(this)
Object.keys(this.controls).forEach((controlKey) => {
if (controlKey !== 'ml' && controlKey !== 'mr') {
this.setControlVisible(controlKey, false)

View File

@ -312,7 +312,31 @@ export function calculateIntersection(line1, line2) {
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)
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 // 교차점이 선분의 범위 내에 없음
@ -339,7 +363,6 @@ export const findIntersection1 = (line1, line2) => {
if (determinant === 0) {
// 두 선이 평행하거나 일직선일 경우
console.log('두 직선은 평행하거나 일직선입니다.')
return null
}
@ -351,7 +374,37 @@ export const findIntersection1 = (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])
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) {
@ -401,10 +454,10 @@ export const sortedPoints = (points) => {
// y값이 같은 point가 많은 경우 그 중 x값이 가장 큰걸 찾는다.
const temp = copyPoints.filter((point) => point.y === currentPoint.y)
// temp중 x값이 가장 큰 값
const max = temp.reduce((prev, current) => (prev.x >= current.x ? prev : current))
resultPoints.push(max)
currentPoint = max
copyPoints.splice(copyPoints.indexOf(max), 1)
const min = temp.reduce((prev, current) => (prev.x <= current.x ? prev : current))
resultPoints.push(min)
currentPoint = min
copyPoints.splice(copyPoints.indexOf(min), 1)
index++
break
}
@ -414,11 +467,11 @@ export const sortedPoints = (points) => {
// x값이 같은 point가 많은 경우 그 중 y값이 가장 큰걸 찾는다.
const temp = copyPoints.filter((point) => point.x === currentPoint.x)
// 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)
currentPoint = max
copyPoints.splice(copyPoints.indexOf(max), 1)
resultPoints.push(min)
currentPoint = min
copyPoints.splice(copyPoints.indexOf(min), 1)
index++
break
}

View File

@ -49,20 +49,23 @@ export const drawHelpLineInHexagon2 = (polygon, chon) => {
const horizontalLines = oneSideLines.filter((line) => line.direction === 'right')
const verticalLines = oneSideLines.filter((line) => line.direction === 'bottom')
// horizontalLines 를 y1 좌표 기준으로 정렬한다.
horizontalLines.sort((a, b) => a.y1 - b.y1)
// verticalLines 를 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) => {
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 startCenterY = (line.y1 + nextLine.y1) / 2
@ -76,8 +79,8 @@ export const drawHelpLineInHexagon2 = (polygon, chon) => {
direction: 'horizontal',
})
polygon.canvas.add(centerLine)
polygon.canvas.renderAll()
/*polygon.canvas.add(centerLine)
polygon.canvas.renderAll()*/
centerLines.push(centerLine)
})
@ -99,14 +102,11 @@ export const drawHelpLineInHexagon2 = (polygon, chon) => {
direction: 'vertical',
})
polygon.canvas.add(centerLine)
polygon.canvas.renderAll()
/*polygon.canvas.add(centerLine)
polygon.canvas.renderAll()*/
centerLines.push(centerLine)
})
const maxLength = horizontalMaxLength < verticalMaxLength ? horizontalMaxLength : verticalMaxLength
polygon.points.forEach((point, index) => {
const wallPoint = polygon.wall.points[index]
// 두 점의 좌표
@ -120,50 +120,67 @@ export const drawHelpLineInHexagon2 = (polygon, chon) => {
// x1, y1을 기준으로 x2, y2와의 거리를 유지한 새로운 직선 생성
const angle = Math.atan2(y2 - y1, x2 - x1)
newX2 = Math.floor(x1 + (maxLength / 2 + 50) * Math.cos(angle))
newY2 = Math.floor(y1 + (maxLength / 2 + 50) * Math.sin(angle))
let previousIndex = index === 0 ? polygon.lines.length - 1 : index - 1
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], {
fontSize: polygon.fontSize,
stroke: 'green',
idx: index,
})
line.set({ degree: fabric.util.radiansToDegrees(angle) })
polygon.canvas.add(line)
helpLines.push(line)
polygon.canvas.renderAll()
debugger
})
helpLines.forEach((line, index) => {
if (line.isAlreadyInterSection) {
return
for (let i = index + 1; i < helpLines.length; i++) {
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 = []
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) => {
const interSectionPoint = findIntersection1(line, centerLine)
console.log('interSectionPoint', interSectionPoint)
const interSectionPoint = calculateIntersection2(line, centerLine)
if (!polygon.inPolygon(interSectionPoint) || !interSectionPoint) {
if (!interSectionPoint) {
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) => {
const circle = new fabric.Circle({
radius: 3,
fill: 'red',
left: point.x,
top: point.y,
})
ridgeStartPoints.forEach((point, index) => {
for (let i = index + 1; i < ridgeStartPoints.length; i++) {
const currentPoint = ridgeStartPoints[index]
const nextPoint = ridgeStartPoints[i]
polygon.canvas.add(circle)
polygon.canvas.renderAll()
if (currentPoint.x === nextPoint.x || currentPoint.y === nextPoint.y) {
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) => {
@ -203,7 +260,7 @@ export const drawHelpLineInHexagon2 = (polygon, chon) => {
let distance = Infinity
let startPoint
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) {
startPoint = point
distance = distanceBetweenPoints(point, interSectionPoint)
@ -230,10 +287,11 @@ export const drawHelpLineInHexagon2 = (polygon, chon) => {
polygon.canvas.add(helpLine)
polygon.canvas.remove(line)
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 nextRidgeEndPoint = ridgeEndPoints[(i + 1) % ridgeEndPoints.length]
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.renderAll()
}
debugger
}*/
}
export const drawHelpLineInHexagon = (polygon, chon) => {