마루 지붕 그리기 재정의

This commit is contained in:
Jaeyoung Lee 2024-11-14 17:29:21 +09:00
parent 919a97f967
commit 1e9dca5b63
2 changed files with 174 additions and 325 deletions

View File

@ -449,7 +449,18 @@ export default function Roof2(props) {
{ x: 1478.6, y: 114.9 }, { x: 1478.6, y: 114.9 },
] ]
const polygon = new QPolygon(eightPoint, { const test3 = [
{ x: 100, y: 100 },
{ x: 100, y: 600 },
{ x: 600, y: 600 },
{ x: 600, y: 100 },
{ x: 500, y: 100 },
{ x: 500, y: 200 },
{ x: 200, y: 200 },
{ x: 200, y: 100 },
]
const polygon = new QPolygon(eightPoint4, {
fill: 'transparent', fill: 'transparent',
stroke: 'green', stroke: 'green',
strokeWidth: 1, strokeWidth: 1,

View File

@ -1274,9 +1274,9 @@ export const drawRidgeRoof = (roofId, canvas) => {
return return
} }
drawRidge(roof, canvas) drawRidge(roof, canvas)
// drawHips(roof, canvas) drawHips(roof, canvas)
/*connectLinePoint(roof, canvas) connectLinePoint(roof, canvas)
modifyRidge(roof, canvas)*/ modifyRidge(roof, canvas)
} }
/** /**
@ -1315,10 +1315,12 @@ const drawRidge = (roof, canvas) => {
currentRoof = item.roof currentRoof = item.roof
const prevRoof = index === 0 ? roofLines[wallLines.length - 1] : roofLines[index - 1] const prevRoof = index === 0 ? roofLines[wallLines.length - 1] : roofLines[index - 1]
const nextRoof = index === roofLines.length - 1 ? roofLines[0] : index === roofLines.length ? roofLines[1] : roofLines[index + 1] const nextRoof = index === roofLines.length - 1 ? roofLines[0] : index === roofLines.length ? roofLines[1] : roofLines[index + 1]
const beforePrevRoof = index <= 1 ? roofLines[roofLines.length - 2 + index] : roofLines[index - 2] // const beforePrevRoof = index <= 1 ? roofLines[roofLines.length - 2 + index] : roofLines[index - 2]
const afterNextRoof = index >= roofLines.length - 2 ? roofLines[(index + 2) % roofLines.length] : roofLines[index + 2] // const afterNextRoof = index >= roofLines.length - 2 ? roofLines[(index + 2) % roofLines.length] : roofLines[index + 2]
let startXPoint, startYPoint, endXPoint, endYPoint let startXPoint, startYPoint, endXPoint, endYPoint
// console.log('currentRoof : ', currentRoof.direction, currentRoof.attributes.planeSize)
let wallLine = wallLines.filter((w) => w.id === currentRoof.attributes.wallLine) let wallLine = wallLines.filter((w) => w.id === currentRoof.attributes.wallLine)
if (wallLine.length > 0) { if (wallLine.length > 0) {
wallLine = wallLine[0] wallLine = wallLine[0]
@ -1326,49 +1328,107 @@ const drawRidge = (roof, canvas) => {
const anotherRoof = roofLines.filter((roof) => roof !== currentRoof && roof !== prevRoof && roof !== nextRoof) const anotherRoof = roofLines.filter((roof) => roof !== currentRoof && roof !== prevRoof && roof !== nextRoof)
/*let xEqualInnerLines = anotherRoof.filter((roof) => roof.x1 === roof.x2 && isInnerLine(prevRoof, currentRoof, nextRoof, roof)), //x가 같은 내부선
yEqualInnerLines = anotherRoof.filter((roof) => roof.y1 === roof.y2 && isInnerLine(prevRoof, currentRoof, nextRoof, roof)) //y가 같은 내부선
console.log('xEqualInnerLines', xEqualInnerLines, 'yEqualInnerLines', yEqualInnerLines)
*/
let currentX1 = currentRoof.x1, let currentX1 = currentRoof.x1,
currentY1 = currentRoof.y1, currentY1 = currentRoof.y1,
currentX2 = currentRoof.x2, currentX2 = currentRoof.x2,
currentY2 = currentRoof.y2 currentY2 = currentRoof.y2
let ridgeMaxLength = Math.max(prevRoof.attributes.planeSize, nextRoof.attributes.planeSize) / 10
let ridgeMinLength = Math.min(prevRoof.attributes.planeSize, nextRoof.attributes.planeSize) / 10
const currentAngle = Math.atan2(currentY2 - currentY1, currentX2 - currentX1) * (180 / Math.PI)
anotherRoof anotherRoof
.filter((roof) => isInnerLine(prevRoof, currentRoof, nextRoof, roof)) .filter((roof) => isInnerLine(prevRoof, currentRoof, nextRoof, roof))
.forEach((roof) => { .forEach((innerRoof) => {
const angle = calculateAngle(currentRoof.startPoint, currentRoof.endPoint) - calculateAngle(roof.startPoint, roof.endPoint) const vector1 = { x: currentRoof.x2 - currentRoof.x1, y: currentRoof.y2 - currentRoof.y1 }
console.log('확인 : ', angle) const vector2 = { x: innerRoof.x2 - innerRoof.x1, y: innerRoof.y2 - innerRoof.y1 }
if (angle === 90) {
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)
const angle = (Math.acos(dotProduct / (magnitude1 * magnitude2)) * 180) / Math.PI
// console.log('innerRoof', innerRoof)
// console.log('현재라인', currentRoof, '현재라인의 각도 : ', currentAngle, 'inner 라인과의 각도:', angle)
//현재 지붕선과 직각인 선
if (Math.abs(angle) === 90) {
const innerBefore = roofLines.find((line) => innerRoof.x1 === line.x2 && innerRoof.y1 === line.y2)
const ibAngle = Math.atan2(innerBefore.y2 - innerBefore.y1, innerBefore.x2 - innerBefore.x1) * (180 / Math.PI)
// console.log('현재라인과 직각인 선의 이전라인', innerBefore, '각도', ibAngle)
if (Math.abs(currentAngle - ibAngle) === 180) {
// console.log('currentRoof 의 x2,y2 좌표에서 연결된 라인')
if (currentAngle === 0 || currentAngle === 180) {
currentX2 = innerRoof.x1
ridgeMinLength =
Math.round(
Math.sqrt(
Math.pow(Math.round(Math.abs(nextRoof.x1 - nextRoof.x2) * 10), 2) +
Math.pow(Math.round(Math.abs(nextRoof.y1 - innerRoof.y2) * 10), 2),
),
) / 10
}
if (currentAngle === 90 || currentAngle === 270) {
currentY2 = innerRoof.y1
ridgeMinLength =
Math.round(
Math.sqrt(
Math.pow(Math.round(Math.abs(nextRoof.x1 - innerRoof.x2) * 10), 2) +
Math.pow(Math.round(Math.abs(nextRoof.y1 - nextRoof.y2) * 10), 2),
),
) / 10
}
}
if (Math.abs(currentAngle - ibAngle) === 0) {
// console.log('currentRoof 의 x1,y1 좌표에서 연결된 라인', currentAngle)
if (currentAngle === 0 || currentAngle === 180) {
currentX1 = innerRoof.x2
ridgeMinLength =
Math.round(
Math.sqrt(
Math.pow(Math.round(Math.abs(prevRoof.x1 - prevRoof.x2) * 10), 2) +
Math.pow(Math.round(Math.abs(prevRoof.y1 - innerRoof.y1) * 10), 2),
),
) / 10
}
if (currentAngle === 90 || currentAngle === 270) {
currentY1 = innerRoof.y2
ridgeMinLength =
Math.round(
Math.sqrt(
Math.pow(Math.round(Math.abs(prevRoof.x1 - innerRoof.x1) * 10), 2) +
Math.pow(Math.round(Math.abs(prevRoof.y1 - prevRoof.y2) * 10), 2),
),
) / 10
}
}
}
//현재 지붕선과 반대인 선
if (Math.abs(angle) === 180) {
// console.log('현재라인과 반대인 선')
if (currentAngle === 0 || currentAngle === 180) {
}
if (currentAngle === 90 || currentAngle === 270) {
}
} }
}) })
console.log('current angle : ', calculateAngle(currentRoof.startPoint, currentRoof.endPoint))
const midX = (currentRoof.x1 + currentRoof.x2) / 2 // 지붕의 X 중심 const midX = (currentX1 + currentX2) / 2 // 지붕의 X 중심
const midY = (currentRoof.y1 + currentRoof.y2) / 2 // 지붕의 Y 중심 const midY = (currentY1 + currentY2) / 2 // 지붕의 Y 중심
/*
const midWallY = (wallLine.y1 + wallLine.y2) / 2 // 벽의 Y 중심
const midWallX = (wallLine.x1 + wallLine.x2) / 2 // 벽의 X 중심
*/
const alpha = (currentRoof.x1 + currentRoof.x2) / 2 - (wallLine.x1 + wallLine.x2) / 2 // 벽과 지붕의 X 거리 const alpha = (currentRoof.x1 + currentRoof.x2) / 2 - (wallLine.x1 + wallLine.x2) / 2 // 벽과 지붕의 X 거리
const beta = (currentRoof.y1 + currentRoof.y2) / 2 - (wallLine.y1 + wallLine.y2) / 2 // 벽과 지붕의 Y 거리 const beta = (currentRoof.y1 + currentRoof.y2) / 2 - (wallLine.y1 + wallLine.y2) / 2 // 벽과 지붕의 Y 거리
const hypotenuse = Math.sqrt(Math.pow(alpha, 2) + Math.pow(beta, 2)) // 벽과 지붕의 거리 const hypotenuse = Math.sqrt(Math.pow(alpha, 2) + Math.pow(beta, 2)) // 벽과 지붕의 거리
let ridgeBaseLength = Math.round(currentRoof.attributes.planeSize / 2) / 10, // 지붕의 기반 길이 const currentPlaneSize = Math.sqrt(
ridgeMaxLength = Math.min(prevRoof.attributes.planeSize, nextRoof.attributes.planeSize) / 10, // 지붕의 최대 길이. 이전, 다음 벽 중 짧은 길이 Math.pow(Math.round(Math.abs(currentX1 - currentX2) * 10), 2) + Math.pow(Math.round(Math.abs(currentY1 - currentY2) * 10), 2),
ridgeAcrossLength = Math.abs(Math.max(prevRoof.attributes.planeSize, nextRoof.attributes.planeSize) - currentRoof.attributes.planeSize) / 10 // 맞은편 벽까지의 길이 - 지붕의 기반 길이 )
let ridgeBaseLength = Math.round(currentPlaneSize / 2) / 10 // 지붕의 기반 길이
startXPoint = Math.round(midX + (-1 * (alpha / hypotenuse) * (currentRoof.attributes.planeSize / 2)) / 10) startXPoint = Math.round(midX + (-1 * (alpha / hypotenuse) * (currentPlaneSize / 2)) / 10)
startYPoint = Math.round(midY + (-1 * (beta / hypotenuse) * (currentRoof.attributes.planeSize / 2)) / 10) startYPoint = Math.round(midY + (-1 * (beta / hypotenuse) * (currentPlaneSize / 2)) / 10)
console.log('ridgeMaxLength', ridgeMaxLength, Math.sign(alpha), Math.sign(alpha) * -1 * ridgeMaxLength)
const checkEndXPoint = Math.round(startXPoint + Math.sign(alpha) * -1 * (ridgeMaxLength + ridgeBaseLength)) const checkEndXPoint = Math.round(startXPoint + Math.sign(alpha) * -1 * (ridgeMaxLength + ridgeBaseLength))
const checkEndYPoint = Math.round(startYPoint + Math.sign(beta) * -1 * (ridgeMaxLength + ridgeBaseLength)) const checkEndYPoint = Math.round(startYPoint + Math.sign(beta) * -1 * (ridgeMaxLength + ridgeBaseLength))
console.log('startXPoint', startXPoint, 'startYPoint', startYPoint, 'endXPoint', checkEndXPoint, 'endYPoint', checkEndYPoint)
const checkLine = new QLine([startXPoint, startYPoint, checkEndXPoint, checkEndYPoint], { const checkLine = new QLine([startXPoint, startYPoint, checkEndXPoint, checkEndYPoint], {
fontSize: roof.fontSize, fontSize: roof.fontSize,
stroke: 'red', stroke: 'red',
@ -1400,14 +1460,28 @@ const drawRidge = (roof, canvas) => {
if (intersectLines.length > 0) { if (intersectLines.length > 0) {
const intersectLine = intersectLines[0] const intersectLine = intersectLines[0]
const diffX = intersectLine.x - startXPoint const diffX = Math.round(intersectLine.x - startXPoint)
const diffY = intersectLine.y - startYPoint const diffY = Math.round(intersectLine.y - startYPoint)
endXPoint = Math.sign(diffX) * Math.round(Math.abs(diffX) - ridgeBaseLength) + startXPoint endXPoint = Math.sign(diffX) * Math.round(Math.abs(diffX) - ridgeBaseLength) + startXPoint
endYPoint = Math.sign(diffY) * Math.round(Math.abs(diffY) - ridgeBaseLength) + startYPoint endYPoint = Math.sign(diffY) * Math.round(Math.abs(diffY) - ridgeBaseLength) + startYPoint
const hypo = Math.sqrt(Math.pow(Math.abs(startXPoint - endXPoint), 2) + Math.pow(Math.abs(startYPoint - endYPoint), 2))
const intersectLength = Math.sqrt(Math.pow(Math.abs(midX - intersectLine.x), 2) + Math.pow(Math.abs(midY - intersectLine.y), 2))
console.log('intersect 좌표까지의 거리 : ', intersectLength)
console.log('hypotenuse', hypo, 'ridgeMinLength', ridgeMinLength)
if (intersectLength < prevRoof.attributes.planeSize / 10 && intersectLength < nextRoof.attributes.planeSize / 10) {
endXPoint = startXPoint
endYPoint = startYPoint
} else {
if (ridgeMinLength < hypo) {
endXPoint = Math.round(startXPoint + Math.sign(diffX) * ridgeMinLength)
endYPoint = Math.round(startYPoint + Math.sign(diffY) * ridgeMinLength)
}
}
} else { } else {
endXPoint = Math.round(startXPoint + Math.sign(alpha) * -1 * ridgeMaxLength) endXPoint = Math.round(startXPoint + Math.sign(alpha) * -1 * ridgeMinLength)
endYPoint = Math.round(startYPoint + Math.sign(beta) * -1 * ridgeMaxLength) endYPoint = Math.round(startYPoint + Math.sign(beta) * -1 * ridgeMinLength)
} }
console.log('startXPoint', startXPoint, 'startYPoint', startYPoint, 'endXPoint', endXPoint, 'endYPoint', endYPoint) console.log('startXPoint', startXPoint, 'startYPoint', startYPoint, 'endXPoint', endXPoint, 'endYPoint', endYPoint)
@ -1436,258 +1510,11 @@ const drawRidge = (roof, canvas) => {
y1: dist1 < dist2 ? startYPoint : endYPoint, y1: dist1 < dist2 ? startYPoint : endYPoint,
} }
} }
/*
console.log('ridgeBaseLength', ridgeBaseLength, 'ridgeMaxLength', ridgeMaxLength, 'ridgeAcrossLength', ridgeAcrossLength)
let acrossRoof = anotherRoof
.filter((roof) => {
const angle1 = calculateAngle(currentRoof.startPoint, currentRoof.endPoint)
const angle2 = calculateAngle(roof.startPoint, roof.endPoint)
if (Math.abs(angle1 - angle2) === 180) {
return roof
}
})
.reduce((prev, current) => {
let hasBetweenRoof = false
if (current.x1 === current.x2) {
hasBetweenRoof = roofLines
.filter((roof) => roof !== current)
.some((line) => {
let currentY2 = currentRoof.y2
if (yEqualInnerLines.length > 0) {
yEqualInnerLines.forEach((line) => {
currentY2 = Math.abs(currentRoof.y1 - currentY2) < Math.abs(currentRoof.y1 - line.y1) ? currentY2 : line.y1
})
}
const isY1Between = (line.y1 > currentRoof.y1 && line.y1 < currentY2) || (line.y1 > currentY2 && line.y1 < currentRoof.y1)
const isY2Between = (line.y2 > currentRoof.y1 && line.y2 < currentY2) || (line.y2 > currentY2 && line.y2 < currentRoof.y1)
const isX1Between = (line.x1 > currentRoof.x1 && line.x1 < current.x1) || (line.x1 > currentRoof.x1 && line.x1 < current.x1)
const isX2Between = (line.x2 > currentRoof.x1 && line.x2 < current.x1) || (line.x2 > currentRoof.x1 && line.x2 < current.x1)
return isY1Between && isY2Between && isX1Between && isX2Between
})
}
if (current.y1 === current.y2) {
hasBetweenRoof = roofLines
.filter((roof) => roof !== current)
.some((line) => {
let currentX2 = currentRoof.x2
if (xEqualInnerLines.length > 0) {
xEqualInnerLines.forEach((line) => {
currentX2 = Math.abs(currentRoof.x1 - currentX2) < Math.abs(currentRoof.x1 - line.x1) ? currentX2 : line.x1
})
}
const isX1Between = (line.x1 > currentRoof.x1 && line.x1 < currentX2) || (line.x1 > currentX2 && line.x1 < currentRoof.x1)
const isX2Between = (line.x2 > currentRoof.x1 && line.x2 < currentX2) || (line.x2 > currentX2 && line.x2 < currentRoof.x1)
const isY1Between = (line.y1 > currentRoof.y1 && line.y1 < current.y1) || (line.y1 > currentRoof.y1 && line.y1 < current.y1)
const isY2Between = (line.y2 > currentRoof.y1 && line.y2 < current.y1) || (line.y2 > currentRoof.y1 && line.y2 < current.y1)
return isX1Between && isX2Between && isY1Between && isY2Between
})
}
if (prev !== undefined) {
if (currentRoof.x1 === currentRoof.x2) {
return Math.abs(currentRoof.y1 - prev.y1) > Math.abs(currentRoof.y1 - current.y1) ? prev : current
}
if (currentRoof.y1 === currentRoof.y2) {
return Math.abs(currentRoof.x1 - prev.x1) > Math.abs(currentRoof.x1 - current.x1) ? prev : current
}
} else {
if (!hasBetweenRoof) {
if (currentRoof.x1 === currentRoof.x2) {
return Math.sign(currentRoof.y1 - currentRoof.y2) !== Math.sign(current.y1 - current.y2) ? current : undefined
}
if (currentRoof.y1 === currentRoof.y2) {
return Math.sign(currentRoof.x1 - currentRoof.x2) !== Math.sign(current.x1 - current.x2) ? current : undefined
}
return undefined
} else {
return undefined
}
}
}, undefined)
if (acrossRoof !== undefined) {
if (currentRoof.x1 === currentRoof.x2) {
if (ridgeAcrossLength < Math.abs(currentRoof.x1 - acrossRoof.x1)) {
ridgeAcrossLength = Math.round(Math.round(Math.abs(currentRoof.x1 - acrossRoof.x1) * 10) - currentRoof.attributes.planeSize)
}
}
if (currentRoof.y1 === currentRoof.y2) {
if (ridgeAcrossLength < Math.abs(currentRoof.y1 - acrossRoof.y1)) {
ridgeAcrossLength = Math.round(Math.round(Math.abs(currentRoof.y1 - acrossRoof.y1) * 10) - currentRoof.attributes.planeSize)
}
}
}
ridgeBaseLength = ridgeBaseLength / 10
ridgeMaxLength = ridgeMaxLength / 10
ridgeAcrossLength = ridgeAcrossLength / 10
console.log('ridgeBaseLength', ridgeBaseLength, 'ridgeMaxLength', ridgeMaxLength, 'ridgeAcrossLength', ridgeAcrossLength)
if (ridgeBaseLength > 0 && ridgeMaxLength > 0 && ridgeAcrossLength > 0) {
let ridgeLength = Math.min(ridgeMaxLength, ridgeAcrossLength)
if (currentRoof.x1 === currentRoof.x2) {
startXPoint = currentRoof.x1 + (nextRoof.direction === 'right' ? 1 : -1) * ridgeBaseLength
startYPoint = currentRoof.y1 + (currentRoof.direction === 'top' ? -1 : 1) * ridgeBaseLength
endXPoint = startXPoint + (nextRoof.direction === 'right' ? 1 : -1) * ridgeLength
endYPoint = startYPoint
let adjustY
if (currentRoof.direction === 'top') {
if (afterNextRoof.direction === 'bottom' && beforePrevRoof.direction === 'bottom') {
adjustY =
Math.abs(currentRoof.x1 - afterNextRoof.x1) < Math.abs(currentRoof.x1 - beforePrevRoof.x1) ? afterNextRoof.y2 : beforePrevRoof.y1
} else if (afterNextRoof.direction === 'bottom' && afterNextRoof.y2 > currentRoof.y2 && afterNextRoof.y2 < currentRoof.y1) {
adjustY = afterNextRoof.y2
} else if (beforePrevRoof.direction === 'bottom' && beforePrevRoof.y1 > currentRoof.y2 && beforePrevRoof.y1 < currentRoof.y1) {
adjustY = beforePrevRoof.y1
}
if (adjustY) {
startYPoint = currentRoof.y1 - Math.abs(currentRoof.y1 - adjustY) / 2
endYPoint = startYPoint
}
}
if (currentRoof.direction === 'bottom') {
if (afterNextRoof.direction === 'top' && beforePrevRoof.direction === 'top') {
adjustY =
Math.abs(currentRoof.x1 - afterNextRoof.x1) < Math.abs(currentRoof.x1 - beforePrevRoof.x1) ? afterNextRoof.y2 : beforePrevRoof.y1
} else if (afterNextRoof.direction === 'top' && afterNextRoof.y2 < currentRoof.y2 && afterNextRoof.y2 > currentRoof.y1) {
adjustY = afterNextRoof.y2
} else if (beforePrevRoof.direction === 'top' && beforePrevRoof.y1 < currentRoof.y2 && beforePrevRoof.y1 > currentRoof.y1) {
adjustY = beforePrevRoof.y1
}
if (adjustY) {
startYPoint = currentRoof.y1 + Math.abs(currentRoof.y1 - adjustY) / 2
endYPoint = startYPoint
}
}
if (yEqualInnerLines.length > 0) {
yEqualInnerLines.reduce((prev, current) => {
if (prev !== undefined) {
return Math.abs(currentRoof.y1 - prev.y1) < Math.abs(currentRoof.y1 - current.y1) ? prev : current
} else {
return current
}
}, undefined)
startYPoint =
Math.abs(currentRoof.y1 - startYPoint) * 2 <= Math.abs(currentRoof.y1 - yEqualInnerLines[0].y1)
? startYPoint
: Math.abs(currentRoof.y1 - yEqualInnerLines[0].y1)
endYPoint = startYPoint
ridgeAcrossLength = Math.max(prevRoof.length, nextRoof.length) - Math.abs(currentRoof.y1 - startYPoint) * 2
if (
//yEqualInnerLines 이 다음 벽보다 안쪽에 있을때
Math.abs(currentRoof.y1 - yEqualInnerLines[0].y1) <= Math.abs(currentRoof.y1 - nextRoof.y1) &&
Math.abs(currentRoof.x1 - yEqualInnerLines[0].x2) >= Math.abs(currentRoof.x1 - nextRoof.x2)
) {
ridgeMaxLength = Math.round(Math.abs(currentRoof.x1 - yEqualInnerLines[0].x2) * 10) / 10
}
ridgeLength = Math.min(ridgeMaxLength, ridgeAcrossLength)
startXPoint = currentRoof.x1 + (nextRoof.direction === 'right' ? 1 : -1) * Math.abs(currentRoof.y1 - startYPoint)
endXPoint = startXPoint + (nextRoof.direction === 'right' ? 1 : -1) * ridgeLength
}
}
if (currentRoof.y1 === currentRoof.y2) {
startXPoint = currentRoof.x1 + (currentRoof.direction === 'left' ? -1 : 1) * ridgeBaseLength
startYPoint = currentRoof.y1 + (nextRoof.direction === 'bottom' ? 1 : -1) * ridgeBaseLength
endXPoint = startXPoint
endYPoint = startYPoint + (nextRoof.direction === 'bottom' ? 1 : -1) * ridgeLength
let adjustX
if (currentRoof.direction === 'right') {
if (afterNextRoof.direction === 'left' && beforePrevRoof.direction === 'left') {
adjustX =
Math.abs(currentRoof.y1 - afterNextRoof.y1) < Math.abs(currentRoof.y1 - beforePrevRoof.y1) ? afterNextRoof.x2 : beforePrevRoof.x1
} else if (afterNextRoof.direction === 'left' && afterNextRoof.x2 < currentRoof.x2 && afterNextRoof.x2 > currentRoof.x1) {
adjustX = afterNextRoof.x2
} else if (beforePrevRoof.direction === 'left' && beforePrevRoof.x1 < currentRoof.x2 && beforePrevRoof.x1 > currentRoof.x1) {
adjustX = beforePrevRoof.x1
}
if (adjustX) {
startXPoint = currentRoof.x1 + Math.abs(currentRoof.x1 - adjustX) / 2
endXPoint = startXPoint
}
}
if (currentRoof.direction === 'left') {
if (afterNextRoof.direction === 'right' && beforePrevRoof.direction === 'right') {
adjustX =
Math.abs(currentRoof.y1 - afterNextRoof.y1) < Math.abs(currentRoof.y1 - beforePrevRoof.y1) ? afterNextRoof.x2 : beforePrevRoof.x1
} else if (afterNextRoof.direction === 'right' && afterNextRoof.x2 > currentRoof.x2 && afterNextRoof.x2 < currentRoof.x1) {
adjustX = afterNextRoof.x2
} else if (beforePrevRoof.direction === 'right' && beforePrevRoof.x1 > currentRoof.x2 && beforePrevRoof.x1 < currentRoof.x1) {
adjustX = beforePrevRoof.x1
}
if (adjustX) {
startXPoint = currentRoof.x1 - Math.abs(currentRoof.x1 - adjustX) / 2
endXPoint = startXPoint
}
}
if (xEqualInnerLines.length > 0) {
xEqualInnerLines.reduce((prev, current) => {
if (prev !== undefined) {
return Math.abs(currentRoof.x1 - prev.x1) < Math.abs(currentRoof.x1 - current.x1) ? prev : current
} else {
return current
}
}, undefined)
startXPoint =
Math.abs(currentRoof.x1 - startXPoint) * 2 <= Math.abs(currentRoof.x1 - xEqualInnerLines[0].x1)
? startXPoint
: Math.abs(currentRoof.x1 - xEqualInnerLines[0].x1)
endXPoint = startXPoint
ridgeAcrossLength = Math.max(prevRoof.length, nextRoof.length) - Math.abs(currentRoof.x1 - startXPoint) * 2
if (
//xEqualInnerLines 이 다음 벽보다 안쪽에 있을때
Math.abs(currentRoof.x1 - xEqualInnerLines[0].x1) <= Math.abs(currentRoof.x1 - nextRoof.x1) &&
Math.abs(currentRoof.y1 - xEqualInnerLines[0].y2) >= Math.abs(currentRoof.y1 - nextRoof.y2)
) {
ridgeMaxLength = Math.round(Math.abs(currentRoof.y1 - xEqualInnerLines[0].y2) * 10) / 10
}
ridgeLength = Math.min(ridgeMaxLength, ridgeAcrossLength)
startYPoint = currentRoof.y1 + (nextRoof.direction === 'bottom' ? 1 : -1) * Math.abs(currentRoof.x1 - startXPoint)
endYPoint = startYPoint + (nextRoof.direction === 'bottom' ? 1 : -1) * ridgeLength
}
}
}
// 마루 그리기
if (startXPoint !== undefined && startYPoint !== undefined && endXPoint !== undefined && endYPoint !== undefined) {
startXPoint = Math.round(startXPoint * 10) / 10
startYPoint = Math.round(startYPoint * 10) / 10
endXPoint = Math.round(endXPoint * 10) / 10
endYPoint = Math.round(endYPoint * 10) / 10
const ridge = new QLine(
[Math.min(startXPoint, endXPoint), Math.min(startYPoint, endYPoint), Math.max(startXPoint, endXPoint), Math.max(startYPoint, endYPoint)],
{
fontSize: roof.fontSize,
stroke: 'blue',
strokeWidth: 1,
name: LINE_TYPE.SUBLINE.RIDGE,
attributes: { roofId: roof.id },
},
)
ridge.attributes.planeSize = Math.round(Math.sqrt(Math.pow(ridge.x1 - ridge.x2, 2) + Math.pow(ridge.y1 - ridge.y2, 2)) * 10)
ridge.attributes.actualSize = Math.round(Math.sqrt(Math.pow(ridge.x1 - ridge.x2, 2) + Math.pow(ridge.y1 - ridge.y2, 2)) * 10)
canvas.add(ridge)
roof.ridges.push(ridge)
roof.innerLines.push(ridge)
const distance = (x1, y1, x2, y2) => Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2))
const dist1 = distance(startXPoint, startYPoint, currentRoof.x1, currentRoof.y1)
const dist2 = distance(endXPoint, endYPoint, currentRoof.x1, currentRoof.y1)
currentRoof.attributes.ridgeCoordinate = {
x1: dist1 < dist2 ? startXPoint : endXPoint,
y1: dist1 < dist2 ? startYPoint : endYPoint,
}
}*/
} }
}) })
//겹쳐지는 마루는 하나로 합침 //겹쳐지는 마루는 하나로 합침
/*roof.ridges.forEach((ridge, index) => { roof.ridges.forEach((ridge, index) => {
roof.ridges roof.ridges
.filter((ridge2) => !(ridge.x1 === ridge2.x1 && ridge.y1 === ridge2.y1 && ridge.x2 === ridge2.x2 && ridge.y2 === ridge2.y2)) .filter((ridge2) => !(ridge.x1 === ridge2.x1 && ridge.y1 === ridge2.y1 && ridge.x2 === ridge2.x2 && ridge.y2 === ridge2.y2))
.forEach((ridge2) => { .forEach((ridge2) => {
@ -1717,7 +1544,7 @@ const drawRidge = (roof, canvas) => {
roof.innerLines.push(newRidge) roof.innerLines.push(newRidge)
} }
}) })
})*/ })
canvas?.renderAll() canvas?.renderAll()
} }
@ -1782,39 +1609,52 @@ const drawHips = (roof, canvas) => {
const nextDegree = nextRoof.attributes.pitch > 0 ? getDegreeByChon(nextRoof.attributes.pitch) : nextRoof.attributes.degree const nextDegree = nextRoof.attributes.pitch > 0 ? getDegreeByChon(nextRoof.attributes.pitch) : nextRoof.attributes.degree
const ridgeCoordinate = currentRoof.attributes.ridgeCoordinate const ridgeCoordinate = currentRoof.attributes.ridgeCoordinate
const hip1 = new QLine([currentRoof.x1, currentRoof.y1, ridgeCoordinate.x1, ridgeCoordinate.y1], {
fontSize: roof.fontSize,
stroke: 'red',
strokeWidth: 1,
name: LINE_TYPE.SUBLINE.HIP,
attributes: { roofId: roof.id, currentRoof: currentRoof.id, actualSize: 0 },
})
canvas.add(hip1)
const hip1Base = ((Math.abs(hip1.x1 - hip1.x2) + Math.abs(hip1.y1 - hip1.y2)) / 2) * 10
const hip1Height = Math.round(hip1Base / Math.tan(((90 - currentDegree) * Math.PI) / 180))
hip1.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip1.x1 - hip1.x2, 2) + Math.pow(hip1.y1 - hip1.y2, 2))) * 10
if (prevDegree === currentDegree) {
hip1.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip1.attributes.planeSize, 2) + Math.pow(hip1Height, 2)))
}
roof.hips.push(hip1)
roof.innerLines.push(hip1)
const hip2 = new QLine([currentRoof.x2, currentRoof.y2, ridgeCoordinate.x1, ridgeCoordinate.y1], { const vectorX1 = ridgeCoordinate.x1 - currentRoof.x1
fontSize: roof.fontSize, const vectorY1 = ridgeCoordinate.y1 - currentRoof.y1
stroke: 'red', const angle1 = Math.atan2(vectorY1, vectorX1) * (180 / Math.PI)
strokeWidth: 1, console.log('angle1', Math.abs(Math.round(angle1)) % 45)
name: LINE_TYPE.SUBLINE.HIP, if (Math.abs(Math.round(angle1)) % 45 === 0) {
attributes: { roofId: roof.id, currentRoof: currentRoof.id, actualSize: 0 }, const hip1 = new QLine([currentRoof.x1, currentRoof.y1, ridgeCoordinate.x1, ridgeCoordinate.y1], {
}) fontSize: roof.fontSize,
canvas.add(hip2) stroke: 'red',
const hip2Base = ((Math.abs(hip2.x1 - hip2.x2) + Math.abs(hip2.y1 - hip2.y2)) / 2) * 10 strokeWidth: 1,
const hip2Height = Math.round(hip2Base / Math.tan(((90 - currentDegree) * Math.PI) / 180)) name: LINE_TYPE.SUBLINE.HIP,
hip2.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip2.x1 - hip2.x2, 2) + Math.pow(hip2.y1 - hip2.y2, 2))) * 10 attributes: { roofId: roof.id, currentRoof: currentRoof.id, actualSize: 0 },
if (nextDegree === currentDegree) { })
hip2.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip2.attributes.planeSize, 2) + Math.pow(hip2Height, 2))) canvas.add(hip1)
const hip1Base = ((Math.abs(hip1.x1 - hip1.x2) + Math.abs(hip1.y1 - hip1.y2)) / 2) * 10
const hip1Height = Math.round(hip1Base / Math.tan(((90 - currentDegree) * Math.PI) / 180))
hip1.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip1.x1 - hip1.x2, 2) + Math.pow(hip1.y1 - hip1.y2, 2))) * 10
if (prevDegree === currentDegree) {
hip1.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip1.attributes.planeSize, 2) + Math.pow(hip1Height, 2)))
}
roof.hips.push(hip1)
roof.innerLines.push(hip1)
}
const vectorX2 = ridgeCoordinate.x1 - currentRoof.x2
const vectorY2 = ridgeCoordinate.y1 - currentRoof.y2
const angle2 = Math.atan2(vectorY2, vectorX2) * (180 / Math.PI)
console.log('angle2', Math.abs(Math.round(angle2)) % 45)
if (Math.abs(Math.round(angle2)) % 45 === 0) {
const hip2 = new QLine([currentRoof.x2, currentRoof.y2, ridgeCoordinate.x1, ridgeCoordinate.y1], {
fontSize: roof.fontSize,
stroke: 'red',
strokeWidth: 1,
name: LINE_TYPE.SUBLINE.HIP,
attributes: { roofId: roof.id, currentRoof: currentRoof.id, actualSize: 0 },
})
canvas.add(hip2)
const hip2Base = ((Math.abs(hip2.x1 - hip2.x2) + Math.abs(hip2.y1 - hip2.y2)) / 2) * 10
const hip2Height = Math.round(hip2Base / Math.tan(((90 - currentDegree) * Math.PI) / 180))
hip2.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip2.x1 - hip2.x2, 2) + Math.pow(hip2.y1 - hip2.y2, 2))) * 10
if (nextDegree === currentDegree) {
hip2.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip2.attributes.planeSize, 2) + Math.pow(hip2Height, 2)))
}
roof.hips.push(hip2)
roof.innerLines.push(hip2)
} }
roof.hips.push(hip2)
roof.innerLines.push(hip2)
}) })
const hipLines = canvas?.getObjects().filter((object) => object.name === LINE_TYPE.SUBLINE.HIP && object.attributes.roofId === roof.id) const hipLines = canvas?.getObjects().filter((object) => object.name === LINE_TYPE.SUBLINE.HIP && object.attributes.roofId === roof.id)
@ -1872,7 +1712,7 @@ const drawHips = (roof, canvas) => {
if (ridgePoints !== undefined) { if (ridgePoints !== undefined) {
const hip = new QLine([currentRoof.x1, currentRoof.y1, ridgePoints.x, ridgePoints.y], { const hip = new QLine([currentRoof.x1, currentRoof.y1, ridgePoints.x, ridgePoints.y], {
fontSize: roof.fontSize, fontSize: roof.fontSize,
stroke: 'red', stroke: 'yellow',
strokeWidth: 1, strokeWidth: 1,
name: LINE_TYPE.SUBLINE.HIP, name: LINE_TYPE.SUBLINE.HIP,
attributes: { roofId: roof.id, currentRoof: currentRoof.id, actualSize: 0 }, attributes: { roofId: roof.id, currentRoof: currentRoof.id, actualSize: 0 },
@ -2286,8 +2126,6 @@ const changeEavesRoof = (currentRoof, canvas) => {
const alpha = midX - midWallX // 벽과 지붕의 X 거리 const alpha = midX - midWallX // 벽과 지붕의 X 거리
const beta = midY - midWallY // 벽과 지붕의 Y 거리 const beta = midY - midWallY // 벽과 지붕의 Y 거리
const hypotenuse = Math.sqrt(Math.pow(alpha, 2) + Math.pow(beta, 2)) // 벽과 지붕의 거리 const hypotenuse = Math.sqrt(Math.pow(alpha, 2) + Math.pow(beta, 2)) // 벽과 지붕의 거리
// const addHipX2 = Math.sign(midX - midWallX) * (alpha / hypotenuse) * (currentRoof.length / 2) // 추녀마루의 X 너비
// const addHipY2 = Math.sign(midY - midWallY) * (beta / hypotenuse) * (currentRoof.length / 2) // 추녀마루의 Y 너비
const hipX2 = Math.round(midX + -1 * (alpha / hypotenuse) * (currentRoof.length / 2)) const hipX2 = Math.round(midX + -1 * (alpha / hypotenuse) * (currentRoof.length / 2))
const hipY2 = Math.round(midY + -1 * (beta / hypotenuse) * (currentRoof.length / 2)) const hipY2 = Math.round(midY + -1 * (beta / hypotenuse) * (currentRoof.length / 2))
@ -2585,7 +2423,7 @@ const changeGableRoof = (currentRoof, canvas) => {
const hip1Height = Math.round(hip1Base / Math.tan(((90 - prevDegree) * Math.PI) / 180)) const hip1Height = Math.round(hip1Base / Math.tan(((90 - prevDegree) * Math.PI) / 180))
hip1.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip1.x1 - hip1.x2, 2) + Math.pow(hip1.y1 - hip1.y2, 2))) * 10 hip1.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip1.x1 - hip1.x2, 2) + Math.pow(hip1.y1 - hip1.y2, 2))) * 10
hip1.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip1.attributes.planeSize, 2) + Math.pow(hip1Height, 2))) hip1.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip1.attributes.planeSize, 2) + Math.pow(hip1Height, 2)))
roof.innerLines.push(hip1) // roof.innerLines.push(hip1)
let hip2 = new QLine([currentRoof.x2, currentRoof.y2, midX, midY], { let hip2 = new QLine([currentRoof.x2, currentRoof.y2, midX, midY], {
fontSize: roof.fontSize, fontSize: roof.fontSize,
@ -2604,7 +2442,7 @@ const changeGableRoof = (currentRoof, canvas) => {
const hip2Height = Math.round(hip2Base / Math.tan(((90 - nextDegree) * Math.PI) / 180)) const hip2Height = Math.round(hip2Base / Math.tan(((90 - nextDegree) * Math.PI) / 180))
hip2.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip2.x1 - hip2.x2, 2) + Math.pow(hip2.y1 - hip2.y2, 2))) * 10 hip2.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip2.x1 - hip2.x2, 2) + Math.pow(hip2.y1 - hip2.y2, 2))) * 10
hip2.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip2.attributes.planeSize, 2) + Math.pow(hip2Height, 2))) hip2.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip2.attributes.planeSize, 2) + Math.pow(hip2Height, 2)))
roof.innerLines.push(hip2) // roof.innerLines.push(hip2)
canvas?.renderAll() canvas?.renderAll()
} }
} }
@ -3013,7 +2851,7 @@ const changeJerkInHeadRoof = (currentRoof, canvas) => {
gable1.attributes.planeSize = Math.round(Math.sqrt(Math.pow(gable1.x1 - gable1.x2, 2) + Math.pow(gable1.y1 - gable1.y2, 2))) * 10 gable1.attributes.planeSize = Math.round(Math.sqrt(Math.pow(gable1.x1 - gable1.x2, 2) + Math.pow(gable1.y1 - gable1.y2, 2))) * 10
gable1.attributes.actualSize = Math.round(Math.sqrt(Math.pow(gable1.attributes.planeSize, 2) + Math.pow(gable1Height, 2))) gable1.attributes.actualSize = Math.round(Math.sqrt(Math.pow(gable1.attributes.planeSize, 2) + Math.pow(gable1Height, 2)))
canvas?.add(gable1) canvas?.add(gable1)
// roof.innerLines.push(gable1) roof.innerLines.push(gable1)
hipX1 = (Math.sign(currentRoof.x2 - midX) * currentRoof.attributes.width) / 2 hipX1 = (Math.sign(currentRoof.x2 - midX) * currentRoof.attributes.width) / 2
hipY1 = (Math.sign(currentRoof.y2 - midY) * currentRoof.attributes.width) / 2 hipY1 = (Math.sign(currentRoof.y2 - midY) * currentRoof.attributes.width) / 2
@ -3034,7 +2872,7 @@ const changeJerkInHeadRoof = (currentRoof, canvas) => {
gable2.attributes.planeSize = Math.round(Math.sqrt(Math.pow(gable2.x1 - gable2.x2, 2) + Math.pow(gable2.y1 - gable2.y2, 2))) * 10 gable2.attributes.planeSize = Math.round(Math.sqrt(Math.pow(gable2.x1 - gable2.x2, 2) + Math.pow(gable2.y1 - gable2.y2, 2))) * 10
gable2.attributes.actualSize = Math.round(Math.sqrt(Math.pow(gable2.attributes.planeSize, 2) + Math.pow(gable2Height, 2))) gable2.attributes.actualSize = Math.round(Math.sqrt(Math.pow(gable2.attributes.planeSize, 2) + Math.pow(gable2Height, 2)))
canvas?.add(gable2) canvas?.add(gable2)
// roof.innerLines.push(gable2) roof.innerLines.push(gable2)
const gable3 = new QLine([gable1.x1, gable1.y1, gable2.x1, gable2.y1], { const gable3 = new QLine([gable1.x1, gable1.y1, gable2.x1, gable2.y1], {
fontSize: roof.fontSize, fontSize: roof.fontSize,
@ -3068,7 +2906,7 @@ const changeJerkInHeadRoof = (currentRoof, canvas) => {
hip1.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip1.x1 - hip1.x2, 2) + Math.pow(hip1.y1 - hip1.y2, 2))) * 10 hip1.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip1.x1 - hip1.x2, 2) + Math.pow(hip1.y1 - hip1.y2, 2))) * 10
hip1.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip1.attributes.planeSize, 2) + Math.pow(hip1Height, 2))) hip1.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip1.attributes.planeSize, 2) + Math.pow(hip1Height, 2)))
canvas?.add(hip1) canvas?.add(hip1)
roof.innerLines.push(hip1) // roof.innerLines.push(hip1)
const hip2 = new QLine([currentRoof.x2, currentRoof.y2, gable2.x1, gable2.y1], { const hip2 = new QLine([currentRoof.x2, currentRoof.y2, gable2.x1, gable2.y1], {
fontSize: roof.fontSize, fontSize: roof.fontSize,
@ -3086,7 +2924,7 @@ const changeJerkInHeadRoof = (currentRoof, canvas) => {
hip2.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip2.x1 - hip2.x2, 2) + Math.pow(hip2.y1 - hip2.y2, 2))) * 10 hip2.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip2.x1 - hip2.x2, 2) + Math.pow(hip2.y1 - hip2.y2, 2))) * 10
hip2.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip2.attributes.planeSize, 2) + Math.pow(hip2Height, 2))) hip2.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip2.attributes.planeSize, 2) + Math.pow(hip2Height, 2)))
canvas?.add(hip2) canvas?.add(hip2)
roof.innerLines.push(hip2) // roof.innerLines.push(hip2)
} }
} }
} }