Merge branch 'dev' of https://git.hanasys.jp/qcast3/qcast-front into dev_ysCha

This commit is contained in:
ysCha 2025-12-22 17:33:44 +09:00
commit 2e3ae74a82

View File

@ -4848,6 +4848,9 @@ export const drawRoofByAttribute = (roofId, canvas, textMode) => {
const prevLineVector = { x: Math.sign(prevLine.x1 - prevLine.x2), y: Math.sign(prevLine.y1 - prevLine.y2) }
const nextLineVector = { x: Math.sign(nextLine.x1 - nextLine.x2), y: Math.sign(nextLine.y1 - nextLine.y2) }
const midX = (baseLine.x1 + baseLine.x2) / 2
const midY = (baseLine.y1 + baseLine.y2) / 2
const checkPoint = { x: midX + nextLineVector.x, y: midY + nextLineVector.y }
//반절마루 생성불가이므로 지붕선 분기를 해야하는지 확인 후 처리.
if (
prevLineVector.x === nextLineVector.x &&
@ -4855,198 +4858,408 @@ export const drawRoofByAttribute = (roofId, canvas, textMode) => {
baseLine.attributes.type === LINE_TYPE.WALLLINE.EAVES &&
(prevLine.attributes.type === LINE_TYPE.WALLLINE.GABLE || nextLine.attributes.type === LINE_TYPE.WALLLINE.GABLE)
) {
downRoofGable.push({ currLine: baseLine, currIndex: index })
downRoofGable.push({ currLine: baseLine, currIndex: index, type: 'A' })
}
if (
(prevLineVector.x !== nextLineVector.x || prevLineVector.y !== nextLineVector.y) &&
checkWallPolygon.inPolygon(checkPoint) &&
prevLine.attributes.type === LINE_TYPE.WALLLINE.GABLE &&
nextLine.attributes.type === LINE_TYPE.WALLLINE.GABLE
) {
downRoofGable.push({ currLine: baseLine, currIndex: index, type: 'B' })
}
})
const downRoofLines = [] // 하단지붕 파생 라인 처리후 innerLines에 추가.
downRoofGable.forEach(({ currLine, currIndex }) => {
// 라인의 방향
const currVector = { x: Math.sign(clamp01(currLine.x1 - currLine.x2)), y: Math.sign(clamp01(currLine.y1 - currLine.y2)) }
//A타입 하단 지붕 prevLine과 nextLine이 같은 방향으로 가는 경우
downRoofGable
.filter((l) => l.type === 'A')
.forEach(({ currLine, currIndex }) => {
// 라인의 방향
const currVector = { x: Math.sign(clamp01(currLine.x1 - currLine.x2)), y: Math.sign(clamp01(currLine.y1 - currLine.y2)) }
//어느쪽이 기준인지 확인.
//대각선 제외
if (currVector.x !== 0 && currVector.y !== 0) return
//어느쪽이 기준인지 확인.
//대각선 제외
if (currVector.x !== 0 && currVector.y !== 0) return
const prevLine = baseLines[(currIndex - 1 + baseLines.length) % baseLines.length]
const nextLine = baseLines[(currIndex + 1) % baseLines.length]
const prevLine = baseLines[(currIndex - 1 + baseLines.length) % baseLines.length]
const nextLine = baseLines[(currIndex + 1) % baseLines.length]
const prevVector = { x: Math.sign(clamp01(prevLine.x1 - prevLine.x2)), y: Math.sign(clamp01(prevLine.y1 - prevLine.y2)) }
const nextVector = { x: Math.sign(clamp01(nextLine.x1 - nextLine.x2)), y: Math.sign(clamp01(nextLine.y1 - nextLine.y2)) }
const prevVector = { x: Math.sign(clamp01(prevLine.x1 - prevLine.x2)), y: Math.sign(clamp01(prevLine.y1 - prevLine.y2)) }
const nextVector = { x: Math.sign(clamp01(nextLine.x1 - nextLine.x2)), y: Math.sign(clamp01(nextLine.y1 - nextLine.y2)) }
let gableLine
//가로선
if (currVector.y === 0) {
if (currVector.x === 1) {
if (prevVector.y === 1 && nextVector.y === 1) {
gableLine = nextLine
let gableLine
//가로선
if (currVector.y === 0) {
if (currVector.x === 1) {
if (prevVector.y === 1 && nextVector.y === 1) {
gableLine = nextLine
}
if (prevVector.y === -1 && nextVector.y === -1) {
gableLine = prevLine
}
}
if (prevVector.y === -1 && nextVector.y === -1) {
gableLine = prevLine
if (currVector.x === -1) {
if (prevVector.y === 1 && nextVector.y === 1) {
gableLine = prevLine
}
if (prevVector.y === -1 && nextVector.y === -1) {
gableLine = nextLine
}
}
}
if (currVector.x === -1) {
if (prevVector.y === 1 && nextVector.y === 1) {
gableLine = prevLine
//세로선
if (currVector.x === 0) {
if (currVector.y === 1) {
if (prevVector.x === 1 && nextVector.x === 1) {
gableLine = prevLine
}
if (prevVector.x === -1 && nextVector.x === -1) {
gableLine = nextLine
}
}
if (prevVector.y === -1 && nextVector.y === -1) {
gableLine = nextLine
if (currVector.y === -1) {
if (prevVector.x === 1 && nextVector.x === 1) {
gableLine = nextLine
}
if (prevVector.x === -1 && nextVector.x === -1) {
gableLine = prevLine
}
}
}
}
//세로선
if (currVector.x === 0) {
if (currVector.y === 1) {
if (prevVector.x === 1 && nextVector.x === 1) {
gableLine = prevLine
}
if (prevVector.x === -1 && nextVector.x === -1) {
gableLine = nextLine
}
//기준점
let stdPoint = []
//반대쪽 라인을 찾기위한 vector
let oppFindVector
if (gableLine === prevLine) {
stdPoint.push(currLine.x1, currLine.y1)
stdPoint.push(currLine.x2 + -currVector.x * nextLine.attributes.offset, currLine.y2 + -currVector.y * nextLine.attributes.offset)
oppFindVector = { x: Math.sign(clamp01(nextLine.x2 - nextLine.x1)), y: Math.sign(clamp01(nextLine.y2 - nextLine.y1)) }
} else {
stdPoint.push(currLine.x2, currLine.y2)
stdPoint.push(currLine.x1 + currVector.x * prevLine.attributes.offset, currLine.y1 + currVector.y * prevLine.attributes.offset)
oppFindVector = { x: Math.sign(clamp01(prevLine.x1 - prevLine.x2)), y: Math.sign(clamp01(prevLine.y1 - prevLine.y2)) }
}
if (currVector.y === -1) {
if (prevVector.x === 1 && nextVector.x === 1) {
gableLine = nextLine
}
if (prevVector.x === -1 && nextVector.x === -1) {
gableLine = prevLine
}
}
}
//기준점
let stdPoint = []
//반대쪽 라인을 찾기위한 vector
let oppFindVector
if (gableLine === prevLine) {
stdPoint.push(currLine.x1, currLine.y1)
stdPoint.push(currLine.x2 + -currVector.x * nextLine.attributes.offset, currLine.y2 + -currVector.y * nextLine.attributes.offset)
oppFindVector = { x: Math.sign(clamp01(nextLine.x2 - nextLine.x1)), y: Math.sign(clamp01(nextLine.y2 - nextLine.y1)) }
} else {
stdPoint.push(currLine.x2, currLine.y2)
stdPoint.push(currLine.x1 + currVector.x * prevLine.attributes.offset, currLine.y1 + currVector.y * prevLine.attributes.offset)
oppFindVector = { x: Math.sign(clamp01(prevLine.x1 - prevLine.x2)), y: Math.sign(clamp01(prevLine.y1 - prevLine.y2)) }
}
//반대쪽 라인들 (마루선을 위함)
const oppLines = baseLines.filter((line) => {
const lineVector = { x: Math.sign(clamp01(line.x1 - line.x2)), y: Math.sign(clamp01(line.y1 - line.y2)) }
const oppVector =
lineVector.x === 0 ? { x: Math.sign(clamp01(line.x1 - stdPoint[0])), y: 0 } : { x: 0, y: Math.sign(clamp01(line.y1 - stdPoint[1])) }
const rightDirection =
(currVector.x === lineVector.x && currVector.y !== lineVector.y) || (currVector.x !== lineVector.x && currVector.y === lineVector.y)
const rightOpp = oppFindVector.x === oppVector.x && oppFindVector.y === oppVector.y
return rightDirection && rightOpp
})
const innerRidge = innerLines
.filter((line) => line.name === LINE_TYPE.SUBLINE.RIDGE)
.filter((line) => {
//반대쪽 라인들 (마루선을 위함)
const oppLines = baseLines.filter((line) => {
const lineVector = { x: Math.sign(clamp01(line.x1 - line.x2)), y: Math.sign(clamp01(line.y1 - line.y2)) }
//마루선을 찾는다.
if ((currVector.x === 0 && lineVector.x === 0) || (currVector.y === 0 && lineVector.y === 0)) {
//세로선
if (lineVector.x === 0) {
const minY = Math.min(line.y1, line.y2)
const maxY = Math.max(line.y1, line.y2)
// 기준 라인 안에 들어있는 경우에만 처리.
if (
Math.min(stdPoint[1], stdPoint[3]) <= minY &&
maxY <= Math.max(stdPoint[1], stdPoint[3]) &&
Math.min(stdPoint[0], ...oppLines.map((line) => line.x1)) <= line.x1 &&
line.x1 <= Math.max(stdPoint[0], ...oppLines.map((line) => line.x1))
) {
return true
const oppVector =
lineVector.x === 0 ? { x: Math.sign(clamp01(line.x1 - stdPoint[0])), y: 0 } : { x: 0, y: Math.sign(clamp01(line.y1 - stdPoint[1])) }
const rightDirection =
(currVector.x === lineVector.x && currVector.y !== lineVector.y) || (currVector.x !== lineVector.x && currVector.y === lineVector.y)
const rightOpp = oppFindVector.x === oppVector.x && oppFindVector.y === oppVector.y
return rightDirection && rightOpp
})
const innerRidge = innerLines
.filter((line) => line.name === LINE_TYPE.SUBLINE.RIDGE)
.filter((line) => {
const lineVector = { x: Math.sign(clamp01(line.x1 - line.x2)), y: Math.sign(clamp01(line.y1 - line.y2)) }
//마루선을 찾는다.
if ((currVector.x === 0 && lineVector.x === 0) || (currVector.y === 0 && lineVector.y === 0)) {
//세로선
if (lineVector.x === 0) {
const minY = Math.min(line.y1, line.y2)
const maxY = Math.max(line.y1, line.y2)
// 기준 라인 안에 들어있는 경우에만 처리.
if (
Math.min(stdPoint[1], stdPoint[3]) <= minY &&
maxY <= Math.max(stdPoint[1], stdPoint[3]) &&
Math.min(stdPoint[0], ...oppLines.map((line) => line.x1)) <= line.x1 &&
line.x1 <= Math.max(stdPoint[0], ...oppLines.map((line) => line.x1))
) {
return true
}
}
//가로선
if (lineVector.y === 0) {
const minX = Math.min(line.x1, line.x2)
const maxX = Math.max(line.x1, line.x2)
// 기준 라인 안에 들어있는 경우에만 처리
if (
Math.min(stdPoint[0], stdPoint[2]) <= minX &&
maxX <= Math.max(stdPoint[0], stdPoint[2]) &&
Math.min(stdPoint[1], ...oppLines.map((line) => line.y1)) <= line.y1 &&
line.y1 <= Math.max(stdPoint[1], ...oppLines.map((line) => line.y1))
) {
return true
}
}
}
//가로선
if (lineVector.y === 0) {
const minX = Math.min(line.x1, line.x2)
const maxX = Math.max(line.x1, line.x2)
// 기준 라인 안에 들어있는 경우에만 처리
if (
Math.min(stdPoint[0], stdPoint[2]) <= minX &&
maxX <= Math.max(stdPoint[0], stdPoint[2]) &&
Math.min(stdPoint[1], ...oppLines.map((line) => line.y1)) <= line.y1 &&
line.y1 <= Math.max(stdPoint[1], ...oppLines.map((line) => line.y1))
) {
return true
})
//1. 현재 라인을 기준으로 지붕선 추가.
//1-1 stdPoint을 현재라인의 지붕 출폭 만큼 조정
const currOffset = currLine.attributes.offset
const noGableLine = gableLine === prevLine ? nextLine : prevLine
let roofLinePoint = stdPoint
if (currVector.x === 0) {
//세로일때
//x축 조정
roofLinePoint[0] = roofLinePoint[0] + currVector.y * currOffset
roofLinePoint[2] = roofLinePoint[2] + currVector.y * currOffset
} else if (currVector.y === 0) {
//가로일때
//y축 조정
roofLinePoint[1] = roofLinePoint[1] - currVector.x * currOffset
roofLinePoint[3] = roofLinePoint[3] - currVector.x * currOffset
}
//지붕선추가.
downRoofLines.push(drawRoofLine(roofLinePoint, canvas, roof, textMode))
//1-2 지붕선에서 oppLine으로 향하는 중 가장 가까운 마루선까지의 연결선 생성
const findRidgeEdge = {
vertex1: { x: roofLinePoint[0], y: roofLinePoint[1] },
vertex2: { x: roofLinePoint[0] + oppFindVector.x, y: roofLinePoint[1] + oppFindVector.y },
}
let minDistance = Infinity
let minPoint
let isLine
innerRidge.forEach((line) => {
const lineEdge = { vertex1: { x: line.x1, y: line.y1 }, vertex2: { x: line.x2, y: line.y2 } }
const intersect = edgesIntersection(lineEdge, findRidgeEdge)
if (intersect) {
let distance = Infinity
if (currVector.x === 0) {
const lineDistance1 = Math.abs(line.y1 - roofLinePoint[1])
const lineDistance2 = Math.abs(line.y2 - roofLinePoint[1])
distance = Math.min(lineDistance1, lineDistance2)
} else if (currVector.y === 0) {
const lineDistance1 = Math.abs(line.x1 - roofLinePoint[0])
const lineDistance2 = Math.abs(line.x2 - roofLinePoint[0])
distance = Math.min(lineDistance1, lineDistance2)
}
if (distance < minDistance) {
minDistance = distance
minPoint = intersect
isLine = line
}
}
})
if (minPoint) {
const hipPoint = [roofLinePoint[0], roofLinePoint[1], minPoint.x, minPoint.y]
downRoofLines.push(
drawHipLine(hipPoint, canvas, roof, textMode, null, getDegreeByChon(currLine.attributes.pitch), getDegreeByChon(currLine.attributes.pitch)),
)
if (isLine) {
const newRidgePoint = [minPoint.x, minPoint.y]
const distance1 = Math.sqrt(Math.pow(minPoint.x - isLine.x1, 2) + Math.pow(minPoint.y - isLine.y1, 2))
const distance2 = Math.sqrt(Math.pow(minPoint.x - isLine.x2, 2) + Math.pow(minPoint.y - isLine.y2, 2))
if (distance2 < distance1) {
newRidgePoint.push(isLine.x1, isLine.y1)
} else {
newRidgePoint.push(isLine.x2, isLine.y2)
}
downRoofLines.push(drawRoofLine(newRidgePoint, canvas, roof, textMode))
}
}
})
// B타입 하단지붕 prevLine과 nextLine의 방향이 반대인데 현재 라인이 지붕 안쪽으로 들어가는 모양.
downRoofGable
.filter((l) => l.type === 'B')
.forEach(({ currLine, currIndex }) => {
const checkLine = new fabric.Line([currLine.x1, currLine.y1, currLine.x2, currLine.y2], {
stroke: 'red',
strokeWidth: 4,
parentId: roofId,
name: 'check',
})
canvas.add(checkLine).renderAll()
// 라인의 방향
const currVector = { x: Math.sign(clamp01(currLine.x1 - currLine.x2)), y: Math.sign(clamp01(currLine.y1 - currLine.y2)) }
//어느쪽이 기준인지 확인.
//대각선 제외
if (currVector.x !== 0 && currVector.y !== 0) return
const prevLine = baseLines[(currIndex - 1 + baseLines.length) % baseLines.length]
const nextLine = baseLines[(currIndex + 1) % baseLines.length]
const prevVector = { x: Math.sign(clamp01(prevLine.x1 - prevLine.x2)), y: Math.sign(clamp01(prevLine.y1 - prevLine.y2)) }
const nextVector = { x: Math.sign(clamp01(nextLine.x1 - nextLine.x2)), y: Math.sign(clamp01(nextLine.y1 - nextLine.y2)) }
const minX = Math.min(currLine.x1, currLine.x2)
const maxX = Math.max(currLine.x1, currLine.x2)
const minY = Math.min(currLine.y1, currLine.y2)
const maxY = Math.max(currLine.y1, currLine.y2)
const midX = (currLine.x1 + currLine.x2) / 2
const midY = (currLine.y1 + currLine.y2) / 2
let ridgeFindVector = { x: nextVector.x, y: nextVector.y }
if (!checkWallPolygon.inPolygon({ x: midX, y: midY })) {
ridgeFindVector = { x: prevVector.x, y: prevVector.y }
}
// 마루를 따라 생성되어야 하는 지붕선 추가.
const oppLines = innerLines
.filter((l) => l.name === LINE_TYPE.SUBLINE.RIDGE)
.filter((line) => {
const lineVector = { x: Math.sign(clamp01(line.x1 - line.x2)), y: Math.sign(clamp01(line.y1 - line.y2)) }
let oppVector
if (currVector.x === 0) {
if (currVector.y === 1) {
oppVector = { x: Math.sign(clamp01(currLine.x1 - line.x1)), y: 0 }
} else if (currVector.y === -1) {
oppVector = { x: Math.sign(clamp01(line.x1 - currLine.x1)), y: 0 }
}
} else if (currVector.y === 0) {
if (currVector.x === 1) {
oppVector = { x: 0, y: Math.sign(clamp01(line.y1 - currLine.y1)) }
} else if (currVector.x === -1) {
oppVector = { x: 0, y: Math.sign(clamp01(currLine.y1 - line.y1)) }
}
}
const lineMinX = Math.min(line.x1, line.x2)
const lineMaxX = Math.max(line.x1, line.x2)
const lineMinY = Math.min(line.y1, line.y2)
const lineMaxY = Math.max(line.y1, line.y2)
const isInside = lineVector.y === 0 ? minX <= lineMinX && lineMaxX <= maxX : minY <= lineMinY && lineMaxY <= maxY
const rightOpp = ridgeFindVector.x === oppVector.x && ridgeFindVector.y === oppVector.y
return rightOpp && isInside
})
// 현재 라인의 지붕선 추가.
const currOffset = currLine.attributes.offset
const roofPoint = [
currLine.x1 + -nextVector.x * currOffset,
currLine.y1 + -nextVector.y * currOffset,
currLine.x2 + -nextVector.x * currOffset,
currLine.y2 + -nextVector.y * currOffset,
]
downRoofLines.push(drawRoofLine(roofPoint, canvas, roof, textMode))
// 현재 라인 좌표의 시작과 끝 포인트에서 직교하는 포인트와 라인을 찾는다
let orthogonalStartPoint,
orthogonalStartDistance = Infinity,
orthogonalStartLine
let orthogonalEndPoint,
orthogonalEndDistance = Infinity,
orthogonalEndLine
oppLines.forEach((line) => {
const checkLine = new fabric.Line([line.x1, line.y1, line.x2, line.y2], { stroke: 'red', strokeWidth: 4, parentId: roofId, name: 'check' })
canvas.add(checkLine).renderAll()
if (currVector.x === 0) {
//세로선
// 시작포인트와 가까운 포인트의 길이
const lineStartDist =
Math.abs(currLine.y1 - line.y1) < Math.abs(currLine.y1 - line.y2) ? Math.abs(currLine.y1 - line.y1) : Math.abs(currLine.y1 - line.y2)
const lineStartPoint =
Math.abs(currLine.y1 - line.y1) < Math.abs(currLine.y1 - line.y2) ? { x: line.x1, y: currLine.y1 } : { x: line.x2, y: currLine.y1 }
if (lineStartDist < orthogonalStartDistance) {
orthogonalStartDistance = lineStartDist
orthogonalStartPoint = lineStartPoint
orthogonalStartLine = line
}
// 종료포인트와 가까운 포인트의 길이
const lineEndDist =
Math.abs(currLine.y2 - line.y1) < Math.abs(currLine.y2 - line.y2) ? Math.abs(currLine.y2 - line.y2) : Math.abs(currLine.y2 - line.y1)
const lineEndPoint =
Math.abs(currLine.y2 - line.y1) < Math.abs(currLine.y2 - line.y2) ? { x: line.x2, y: currLine.y2 } : { x: line.x1, y: currLine.y2 }
if (lineEndDist < orthogonalEndDistance) {
orthogonalEndDistance = lineEndDist
orthogonalEndPoint = lineEndPoint
orthogonalEndLine = line
}
} else if (currVector.y === 0) {
//가로선
// 시작포인트와 가까운 포인트의 길이
const lineStartDist =
Math.abs(currLine.x1 - line.x1) < Math.abs(currLine.x1 - line.x2) ? Math.abs(currLine.x1 - line.x1) : Math.abs(currLine.x1 - line.x2)
const lineStartPoint =
Math.abs(currLine.x1 - line.x1) < Math.abs(currLine.x1 - line.x2) ? { x: currLine.x1, y: line.y1 } : { x: currLine.x1, y: line.y2 }
if (lineStartDist < orthogonalStartDistance) {
orthogonalStartDistance = lineStartDist
orthogonalStartPoint = lineStartPoint
orthogonalStartLine = line
}
//종료포인트와 가까운 포인트의 길이
const lineEndDist =
Math.abs(currLine.x2 - line.x1) < Math.abs(currLine.x2 - line.x2) ? Math.abs(currLine.x2 - line.x1) : Math.abs(currLine.x2 - line.x2)
const lineEndPoint =
Math.abs(currLine.x2 - line.x1) < Math.abs(currLine.x2 - line.x2) ? { x: currLine.x2, y: line.y1 } : { x: currLine.x2, y: line.y2 }
if (lineEndDist < orthogonalEndDistance) {
orthogonalEndDistance = lineEndDist
orthogonalEndPoint = lineEndPoint
orthogonalEndLine = line
}
}
})
//1. 현재 라인을 기준으로 지붕선 추가.
//1-1 stdPoint을 현재라인의 지붕 출폭 만큼 조정
const currOffset = currLine.attributes.offset
const noGableLine = gableLine === prevLine ? nextLine : prevLine
//직교 라인이 있는 경우
if (orthogonalStartLine !== undefined && orthogonalEndLine !== undefined) {
if (orthogonalStartLine === orthogonalEndLine) {
//직교 라인이 1개일때 처리
downRoofLines.push(
drawRoofLine([orthogonalStartPoint.x, orthogonalStartPoint.y, orthogonalEndPoint.x, orthogonalEndPoint.y], canvas, roof, textMode),
)
} else {
//직교 라인이 2개일때 처리
// 시작 라인 처리
const startDist1 = Math.sqrt(
Math.pow(orthogonalStartPoint.x - orthogonalStartLine.x1, 2) + Math.pow(orthogonalStartPoint.y - orthogonalStartLine.y1, 2),
)
const startDist2 = Math.sqrt(
Math.pow(orthogonalStartPoint.x - orthogonalStartLine.x2, 2) + Math.pow(orthogonalStartPoint.y - orthogonalStartLine.y2, 2),
)
const otherStartPoint =
startDist1 > startDist2
? { x: orthogonalStartLine.x1, y: orthogonalStartLine.y1 }
: { x: orthogonalStartLine.x2, y: orthogonalStartLine.y2 }
downRoofLines.push(
drawRoofLine([orthogonalStartPoint.x, orthogonalStartPoint.y, otherStartPoint.x, otherStartPoint.y], canvas, roof, textMode),
)
let roofLinePoint = stdPoint
if (currVector.x === 0) {
//세로일때
//x축 조정
roofLinePoint[0] = roofLinePoint[0] + currVector.y * currOffset
roofLinePoint[2] = roofLinePoint[2] + currVector.y * currOffset
} else if (currVector.y === 0) {
//가로일때
//y축 조정
roofLinePoint[1] = roofLinePoint[1] - currVector.x * currOffset
roofLinePoint[3] = roofLinePoint[3] - currVector.x * currOffset
}
//지붕선추가.
downRoofLines.push(drawRoofLine(roofLinePoint, canvas, roof, textMode))
//1-2 지붕선에서 oppLine으로 향하는 중 가장 가까운 마루선까지의 연결선 생성
const findRidgeEdge = {
vertex1: { x: roofLinePoint[0], y: roofLinePoint[1] },
vertex2: { x: roofLinePoint[0] + oppFindVector.x, y: roofLinePoint[1] + oppFindVector.y },
}
let minDistance = Infinity
let minPoint
let isLine
innerRidge.forEach((line) => {
const lineEdge = { vertex1: { x: line.x1, y: line.y1 }, vertex2: { x: line.x2, y: line.y2 } }
const intersect = edgesIntersection(lineEdge, findRidgeEdge)
if (intersect) {
let distance = Infinity
if (currVector.x === 0) {
const lineDistance1 = Math.abs(line.y1 - roofLinePoint[1])
const lineDistance2 = Math.abs(line.y2 - roofLinePoint[1])
distance = Math.min(lineDistance1, lineDistance2)
} else if (currVector.y === 0) {
const lineDistance1 = Math.abs(line.x1 - roofLinePoint[0])
const lineDistance2 = Math.abs(line.x2 - roofLinePoint[0])
distance = Math.min(lineDistance1, lineDistance2)
}
if (distance < minDistance) {
minDistance = distance
minPoint = intersect
isLine = line
const endDist1 = Math.sqrt(
Math.pow(orthogonalEndPoint.x - orthogonalEndLine.x1, 2) + Math.pow(orthogonalEndPoint.y - orthogonalEndLine.y1, 2),
)
const endDist2 = Math.sqrt(
Math.pow(orthogonalEndPoint.x - orthogonalEndLine.x2, 2) + Math.pow(orthogonalEndPoint.y - orthogonalEndLine.y2, 2),
)
const otherEndPoint =
endDist1 > endDist2 ? { x: orthogonalEndLine.x1, y: orthogonalEndLine.y1 } : { x: orthogonalEndLine.x2, y: orthogonalEndLine.y2 }
downRoofLines.push(drawRoofLine([orthogonalEndPoint.x, orthogonalEndPoint.y, otherEndPoint.x, otherEndPoint.y], canvas, roof, textMode))
}
//지붕선(roofPoint)에서 직교포인트까지 연결하는 라인을 추가한다.
const orthogonalPoint1 = [roofPoint[0], roofPoint[1], orthogonalStartPoint.x, orthogonalStartPoint.y]
const orthogonalPoint2 = [roofPoint[2], roofPoint[3], orthogonalEndPoint.x, orthogonalEndPoint.y]
downRoofLines.push(
drawHipLine(
orthogonalPoint1,
canvas,
roof,
textMode,
null,
getDegreeByChon(currLine.attributes.pitch),
getDegreeByChon(currLine.attributes.pitch),
),
)
downRoofLines.push(
drawHipLine(
orthogonalPoint2,
canvas,
roof,
textMode,
null,
getDegreeByChon(currLine.attributes.pitch),
getDegreeByChon(currLine.attributes.pitch),
),
)
}
})
if (minPoint) {
const hipPoint = [roofLinePoint[0], roofLinePoint[1], minPoint.x, minPoint.y]
downRoofLines.push(
drawHipLine(hipPoint, canvas, roof, textMode, null, getDegreeByChon(currLine.attributes.pitch), getDegreeByChon(currLine.attributes.pitch)),
)
if (isLine) {
const newRidgePoint = [minPoint.x, minPoint.y]
const distance1 = Math.sqrt(Math.pow(minPoint.x - isLine.x1, 2) + Math.pow(minPoint.y - isLine.y1, 2))
const distance2 = Math.sqrt(Math.pow(minPoint.x - isLine.x2, 2) + Math.pow(minPoint.y - isLine.y2, 2))
if (distance2 < distance1) {
newRidgePoint.push(isLine.x1, isLine.y1)
} else {
newRidgePoint.push(isLine.x2, isLine.y2)
}
downRoofLines.push(drawRoofLine(newRidgePoint, canvas, roof, textMode))
}
}
})
//추가된 하단 지붕 라인 innerLines에 추가.
innerLines.push(...downRoofLines)
@ -5107,7 +5320,13 @@ export const drawRoofByAttribute = (roofId, canvas, textMode) => {
}
startPoint = point
}
innerLines.push(drawHipLine([startPoint.x, startPoint.y, currentLine.x2, currentLine.y2], canvas, roof, textMode, null, nextDegree, nextDegree))
if (splitPoint.length === 1) {
innerLines.push(drawRoofLine([startPoint.x, startPoint.y, currentLine.x2, currentLine.y2], canvas, roof, textMode))
} else {
innerLines.push(
drawHipLine([startPoint.x, startPoint.y, currentLine.x2, currentLine.y2], canvas, roof, textMode, null, nextDegree, nextDegree),
)
}
} else {
innerLines.push(drawRoofLine([currentLine.x1, currentLine.y1, currentLine.x2, currentLine.y2], canvas, roof, textMode))
}