박공지붕 동선이동 대응 정리 (혼합 처리 중)
This commit is contained in:
parent
69763dd413
commit
2f261cb0c0
@ -1,6 +1,6 @@
|
|||||||
import { fabric } from 'fabric'
|
import { fabric } from 'fabric'
|
||||||
import { QLine } from '@/components/fabric/QLine'
|
import { QLine } from '@/components/fabric/QLine'
|
||||||
import { getDegreeByChon } from '@/util/canvas-util'
|
import { getDegreeByChon, isPointOnLine } from '@/util/canvas-util'
|
||||||
|
|
||||||
import { QPolygon } from '@/components/fabric/QPolygon'
|
import { QPolygon } from '@/components/fabric/QPolygon'
|
||||||
import * as turf from '@turf/turf'
|
import * as turf from '@turf/turf'
|
||||||
@ -878,6 +878,8 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => {
|
|||||||
|
|
||||||
if (checkWallPolygon.inPolygon(checkPoints)) {
|
if (checkWallPolygon.inPolygon(checkPoints)) {
|
||||||
drawGablePolygonFirst.push({ currentBaseLine, prevBaseLine, nextBaseLine })
|
drawGablePolygonFirst.push({ currentBaseLine, prevBaseLine, nextBaseLine })
|
||||||
|
} else {
|
||||||
|
drawGablePolygonSecond.push({ currentBaseLine, prevBaseLine, nextBaseLine })
|
||||||
}
|
}
|
||||||
// if (!checkWallPolygon.inPolygon(checkPoints)) {
|
// if (!checkWallPolygon.inPolygon(checkPoints)) {
|
||||||
drawGableRidgeSecond.push({ currentBaseLine, prevBaseLine, nextBaseLine })
|
drawGableRidgeSecond.push({ currentBaseLine, prevBaseLine, nextBaseLine })
|
||||||
@ -1655,410 +1657,27 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => {
|
|||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
})
|
})
|
||||||
|
|
||||||
/** 케라바 지붕으로 생성된 마루의 지붕선을 그린다.*/
|
const uniqueRidgeLines = []
|
||||||
baseGableRidgeLines.forEach((ridge) => {
|
/** 중복제거 */
|
||||||
return
|
baseGableRidgeLines.forEach((currentLine, index) => {
|
||||||
const { x1, x2, y1, y2 } = ridge
|
if (index === 0) {
|
||||||
const checkLine = new fabric.Line([x1, y1, x2, y2], {
|
uniqueRidgeLines.push(currentLine)
|
||||||
stroke: 'red',
|
|
||||||
strokeWidth: 4,
|
|
||||||
parentId: roofId,
|
|
||||||
name: 'checkLine',
|
|
||||||
})
|
|
||||||
canvas.add(checkLine)
|
|
||||||
canvas.renderAll()
|
|
||||||
|
|
||||||
const ridgeVectorX = Math.sign(Big(x1).minus(x2).toNumber())
|
|
||||||
const ridgeVectorY = Math.sign(Big(y1).minus(y2).toNumber())
|
|
||||||
const firstPoint = { x: x1, y: y1 }
|
|
||||||
const secondPoint = { x: x2, y: y2 }
|
|
||||||
let firstRoofLine, secondRoofLine
|
|
||||||
roof.lines
|
|
||||||
.filter((line) => {
|
|
||||||
if (ridgeVectorX === 0) {
|
|
||||||
return line.x1 !== line.x2
|
|
||||||
} else {
|
} else {
|
||||||
return line.y1 !== line.y2
|
const duplicateLines = uniqueRidgeLines.filter(
|
||||||
}
|
|
||||||
})
|
|
||||||
.forEach((line) => {
|
|
||||||
if (ridgeVectorX === 0) {
|
|
||||||
if (line.y1 === firstPoint.y) {
|
|
||||||
firstRoofLine = line
|
|
||||||
}
|
|
||||||
if (line.y1 === secondPoint.y) {
|
|
||||||
secondRoofLine = line
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (line.x1 === firstPoint.x) {
|
|
||||||
firstRoofLine = line
|
|
||||||
}
|
|
||||||
if (line.x1 === secondPoint.x) {
|
|
||||||
secondRoofLine = line
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
/** 마루 1개에 (위,아래), (좌,우) 로 두가지의 지붕면이 생길 수 있다.*/
|
|
||||||
let firstCheckPoints = []
|
|
||||||
let secondCheckPoints = []
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param startPoint
|
|
||||||
* @param nextPoint
|
|
||||||
* @param endPoint
|
|
||||||
*/
|
|
||||||
const findPointToPolygon = (startPoint, nextPoint, endPoint) => {
|
|
||||||
let findPoint = nextPoint
|
|
||||||
const points = [startPoint, nextPoint]
|
|
||||||
let index = 1
|
|
||||||
while (!(points[points.length - 1].x === endPoint.x && points[points.length - 1].y === endPoint.y)) {
|
|
||||||
const prevVector = { x: Math.sign(points[index - 1].x - points[index].x), y: Math.sign(points[index - 1].y - points[index].y) }
|
|
||||||
const currentPoint = points[index]
|
|
||||||
|
|
||||||
const hipLine = baseHipLines.find(
|
|
||||||
(line) =>
|
(line) =>
|
||||||
(line.line.x1 === currentPoint.x && line.line.y1 === currentPoint.y) ||
|
(currentLine.x1 === line.x1 && currentLine.y1 === line.y1 && currentLine.x2 === line.x2 && currentLine.y2 === line.y2) ||
|
||||||
(line.line.x2 === currentPoint.x && line.line.y2 === currentPoint.y),
|
(currentLine.x1 === line.x2 && currentLine.y1 === line.y2 && currentLine.x2 === line.x1 && currentLine.y2 === line.y1),
|
||||||
)
|
)
|
||||||
if (hipLine) {
|
if (duplicateLines.length === 0) {
|
||||||
if (hipLine.line.x1 === currentPoint.x && hipLine.line.y1 === currentPoint.y) {
|
uniqueRidgeLines.push(currentLine)
|
||||||
points.push({ x: hipLine.line.x2, y: hipLine.line.y2 })
|
|
||||||
} else {
|
|
||||||
points.push({ x: hipLine.line.x1, y: hipLine.line.y1 })
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const nextRoofLine = roof.lines.find((line) => {
|
|
||||||
if (prevVector.x !== 0) {
|
|
||||||
return (
|
|
||||||
line.y1 !== line.y2 &&
|
|
||||||
((line.x1 <= currentPoint.x && currentPoint.x <= line.x2) || (line.x2 <= currentPoint.x && currentPoint.x <= line.x1))
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
line.x1 !== line.x2 &&
|
|
||||||
((line.y1 <= currentPoint.y && currentPoint.y <= line.y2) || (line.y2 <= currentPoint.y && currentPoint.y <= line.y1))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
const checkLine = new fabric.Line([nextRoofLine.x1, nextRoofLine.y1, nextRoofLine.x2, nextRoofLine.y2], {
|
|
||||||
stroke: 'yellow',
|
|
||||||
strokeWidth: 4,
|
|
||||||
parentId: roofId,
|
|
||||||
name: 'checkLine',
|
|
||||||
})
|
|
||||||
canvas.add(checkLine)
|
|
||||||
canvas.renderAll()
|
|
||||||
|
|
||||||
const lineEdge = { vertex1: { x: nextRoofLine.x1, y: nextRoofLine.y1 }, vertex2: { x: nextRoofLine.x2, y: nextRoofLine.y2 } }
|
|
||||||
let ridgeIntersection
|
|
||||||
baseGableRidgeLines.forEach((ridgeLine) => {
|
|
||||||
const ridgeEdge = { vertex1: { x: ridgeLine.x1, y: ridgeLine.y1 }, vertex2: { x: ridgeLine.x2, y: ridgeLine.y2 } }
|
|
||||||
const intersection = edgesIntersection(lineEdge, ridgeEdge)
|
|
||||||
console.log('intersection', intersection)
|
|
||||||
if (intersection && !intersection.isIntersectionOutside) {
|
|
||||||
ridgeIntersection = { x: intersection.x, y: intersection.y }
|
|
||||||
}
|
|
||||||
})
|
|
||||||
if (ridgeIntersection) {
|
|
||||||
points.push(ridgeIntersection)
|
|
||||||
} else {
|
|
||||||
if (nextRoofLine.x1 === currentPoint.x && nextRoofLine.y1 === currentPoint.y) {
|
|
||||||
points.push({ x: nextRoofLine.x2, y: nextRoofLine.y2 })
|
|
||||||
} else {
|
|
||||||
points.push({ x: nextRoofLine.x1, y: nextRoofLine.y1 })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log('points', points, points[points.length - 1], endPoint)
|
|
||||||
index = index + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas
|
|
||||||
.getObjects()
|
|
||||||
.filter((obj) => obj.name === 'checkLine' || obj.name === 'checkPoint')
|
|
||||||
.forEach((obj) => canvas.remove(obj))
|
|
||||||
canvas.renderAll()
|
|
||||||
return points
|
|
||||||
}
|
|
||||||
|
|
||||||
let startVector
|
|
||||||
console.log('!firstRoofLine && !secondRoofLine', !firstRoofLine && !secondRoofLine)
|
|
||||||
let firstPoints, secondPoints
|
|
||||||
if (!firstRoofLine && !secondRoofLine) {
|
|
||||||
} else {
|
|
||||||
if (firstRoofLine) {
|
|
||||||
firstPoints = findPointToPolygon(firstPoint, { x: firstRoofLine.x1, y: firstRoofLine.y1 }, secondPoint)
|
|
||||||
secondPoints = findPointToPolygon(firstPoint, { x: firstRoofLine.x2, y: firstRoofLine.y2 }, secondPoint)
|
|
||||||
} else {
|
|
||||||
firstPoints = findPointToPolygon(secondPoint, { x: secondRoofLine.x1, y: secondRoofLine.y1 }, firstPoint)
|
|
||||||
secondPoints = findPointToPolygon(secondPoint, { x: secondRoofLine.x2, y: secondRoofLine.y2 }, firstPoint)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const firstPolygonPoints = getSortedPoint(firstPoints)
|
|
||||||
const secondPolygonPoints = getSortedPoint(secondPoints)
|
|
||||||
|
|
||||||
firstPolygonPoints.forEach((point, index) => {
|
|
||||||
let endPoint
|
|
||||||
if (index === firstPolygonPoints.length - 1) {
|
|
||||||
endPoint = firstPolygonPoints[0]
|
|
||||||
} else {
|
|
||||||
endPoint = firstPolygonPoints[index + 1]
|
|
||||||
}
|
|
||||||
const hipLine = drawHipLine([point.x, point.y, endPoint.x, endPoint.y], canvas, roof, textMode, null, currentDegree, currentDegree)
|
|
||||||
baseHipLines.push({ x1: point.x, y1: point.y, x2: endPoint.x, y2: endPoint.y, line: hipLine })
|
|
||||||
|
|
||||||
const checkLine = new fabric.Line([point.x, point.y, endPoint.x, endPoint.y], {
|
|
||||||
stroke: 'red',
|
|
||||||
strokeWidth: 4,
|
|
||||||
parentId: roofId,
|
|
||||||
name: 'checkLine',
|
|
||||||
})
|
|
||||||
canvas.add(checkLine)
|
|
||||||
canvas.renderAll()
|
|
||||||
})
|
|
||||||
secondPolygonPoints.forEach((point, index) => {
|
|
||||||
let endPoint
|
|
||||||
if (index === secondPolygonPoints.length - 1) {
|
|
||||||
endPoint = secondPolygonPoints[0]
|
|
||||||
} else {
|
|
||||||
endPoint = secondPolygonPoints[index + 1]
|
|
||||||
}
|
|
||||||
const hipLine = drawHipLine([point.x, point.y, endPoint.x, endPoint.y], canvas, roof, textMode, null, currentDegree, currentDegree)
|
|
||||||
baseHipLines.push({ x1: point.x, y1: point.y, x2: endPoint.x, y2: endPoint.y, line: hipLine })
|
|
||||||
|
|
||||||
const checkLine = new fabric.Line([point.x, point.y, endPoint.x, endPoint.y], {
|
|
||||||
stroke: 'red',
|
|
||||||
strokeWidth: 4,
|
|
||||||
parentId: roofId,
|
|
||||||
name: 'checkLine',
|
|
||||||
})
|
|
||||||
canvas.add(checkLine)
|
|
||||||
canvas.renderAll()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
drawGableFirstLines.forEach((current) => {
|
|
||||||
return
|
|
||||||
const { currentBaseLine, prevBaseLine, nextBaseLine } = current
|
|
||||||
const currentLine = currentBaseLine.line
|
|
||||||
const prevLine = prevBaseLine.line
|
|
||||||
const nextLine = nextBaseLine.line
|
|
||||||
let { x1, x2, y1, y2, size } = currentBaseLine
|
|
||||||
let beforePrevBaseLine, afterNextBaseLine
|
|
||||||
|
|
||||||
/** 이전 라인의 경사 */
|
|
||||||
const prevDegree = prevLine.attributes.pitch > 0 ? getDegreeByChon(prevLine.attributes.pitch) : prevLine.attributes.degree
|
|
||||||
/** 다음 라인의 경사 */
|
|
||||||
const nextDegree = nextLine.attributes.pitch > 0 ? getDegreeByChon(nextLine.attributes.pitch) : nextLine.attributes.degree
|
|
||||||
/** 현재 라인의 경사 */
|
|
||||||
const currentDegree = currentLine.attributes.pitch > 0 ? getDegreeByChon(currentLine.attributes.pitch) : currentLine.attributes.degree
|
|
||||||
|
|
||||||
/** 이전 라인의 전라인, 다음 라인의 다음라인을 찾는다 */
|
|
||||||
drawBaseLines.forEach((line, index) => {
|
|
||||||
if (line === prevBaseLine) {
|
|
||||||
beforePrevBaseLine = drawBaseLines[(index - 1 + drawBaseLines.length) % drawBaseLines.length]
|
|
||||||
}
|
|
||||||
if (line === nextBaseLine) {
|
|
||||||
afterNextBaseLine = drawBaseLines[(index + 1) % drawBaseLines.length]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const beforePrevLine = beforePrevBaseLine?.line
|
|
||||||
const afterNextLine = afterNextBaseLine?.line
|
|
||||||
|
|
||||||
/** 각 라인의 흐름 방향을 확인한다. */
|
|
||||||
const currentAngle = calculateAngle(currentLine.startPoint, currentLine.endPoint)
|
|
||||||
const prevAngle = calculateAngle(prevLine.startPoint, prevLine.endPoint)
|
|
||||||
const nextAngle = calculateAngle(nextLine.startPoint, nextLine.endPoint)
|
|
||||||
const beforePrevAngle = calculateAngle(beforePrevLine.startPoint, beforePrevLine.endPoint)
|
|
||||||
const afterNextAngle = calculateAngle(afterNextLine.startPoint, afterNextLine.endPoint)
|
|
||||||
|
|
||||||
/** 이전라인의 vector*/
|
|
||||||
const prevVectorX = Math.sign(Big(prevLine.x2).minus(Big(prevLine.x1)))
|
|
||||||
const prevVectorY = Math.sign(Big(prevLine.y2).minus(Big(prevLine.y1)))
|
|
||||||
|
|
||||||
/** 현재라인의 기준점*/
|
|
||||||
const currentMidX = Big(x1).plus(Big(x2)).div(2).plus(Big(prevVectorX).times(currentLine.attributes.offset))
|
|
||||||
const currentMidY = Big(y1).plus(Big(y2)).div(2).plus(Big(prevVectorY).times(currentLine.attributes.offset))
|
|
||||||
|
|
||||||
if (beforePrevBaseLine === afterNextBaseLine) {
|
|
||||||
console.log('박공지붕 사각')
|
|
||||||
|
|
||||||
const afterNextMidX = Big(afterNextLine.x1).plus(Big(afterNextLine.x2)).div(2)
|
|
||||||
const afterNextMidY = Big(afterNextLine.y1).plus(Big(afterNextLine.y2)).div(2)
|
|
||||||
const vectorMidX = Math.sign(currentMidX.minus(afterNextMidX))
|
|
||||||
const vectorMidY = Math.sign(currentMidY.minus(afterNextMidY))
|
|
||||||
|
|
||||||
let oppositeMidX, oppositeMidY
|
|
||||||
if (eavesType.includes(afterNextLine.attributes?.type)) {
|
|
||||||
const checkSize = currentMidX
|
|
||||||
.minus(afterNextMidX)
|
|
||||||
.pow(2)
|
|
||||||
.plus(currentMidY.minus(afterNextMidY).pow(2))
|
|
||||||
.sqrt()
|
|
||||||
.minus(Big(afterNextLine.attributes.planeSize).div(20))
|
|
||||||
.round(1)
|
|
||||||
oppositeMidX = currentMidX.plus(checkSize.times(vectorMidX).neg())
|
|
||||||
oppositeMidY = currentMidY.plus(checkSize.times(vectorMidY).neg())
|
|
||||||
|
|
||||||
const xVector1 = Math.sign(Big(oppositeMidX).minus(Big(afterNextLine.x1)).neg().toNumber())
|
|
||||||
const yVector1 = Math.sign(Big(oppositeMidY).minus(Big(afterNextLine.y1)).neg().toNumber())
|
|
||||||
const xVector2 = Math.sign(Big(oppositeMidX).minus(Big(afterNextLine.x2)).neg().toNumber())
|
|
||||||
const yVector2 = Math.sign(Big(oppositeMidY).minus(Big(afterNextLine.y2)).neg().toNumber())
|
|
||||||
|
|
||||||
let addOppositeX1 = 0,
|
|
||||||
addOppositeY1 = 0,
|
|
||||||
addOppositeX2 = 0,
|
|
||||||
addOppositeY2 = 0
|
|
||||||
|
|
||||||
if (!checkWallPolygon.inPolygon({ x: oppositeMidX.toNumber(), y: oppositeMidY.toNumber() })) {
|
|
||||||
const checkScale = currentMidX.minus(oppositeMidX).pow(2).plus(currentMidY.minus(oppositeMidY).pow(2)).sqrt()
|
|
||||||
addOppositeX1 = checkScale.times(xVector1).toNumber()
|
|
||||||
addOppositeY1 = checkScale.times(yVector1).toNumber()
|
|
||||||
addOppositeX2 = checkScale.times(xVector2).toNumber()
|
|
||||||
addOppositeY2 = checkScale.times(yVector2).toNumber()
|
|
||||||
}
|
|
||||||
|
|
||||||
let scale1 = Big(afterNextLine.attributes.offset).pow(2).plus(Big(nextLine.attributes.offset).pow(2)).sqrt()
|
|
||||||
scale1 = scale1.eq(0) ? Big(1) : scale1
|
|
||||||
let scale2 = Big(afterNextLine.attributes.offset).pow(2).plus(Big(prevLine.attributes.offset).pow(2)).sqrt()
|
|
||||||
scale2 = scale2.eq(0) ? Big(1) : scale2
|
|
||||||
|
|
||||||
const checkHip1 = {
|
|
||||||
x1: Big(afterNextLine.x1).plus(scale1.times(xVector1)).toNumber(),
|
|
||||||
y1: Big(afterNextLine.y1).plus(scale1.times(yVector1)).toNumber(),
|
|
||||||
x2: oppositeMidX.plus(addOppositeX1).toNumber(),
|
|
||||||
y2: oppositeMidY.plus(addOppositeY1).toNumber(),
|
|
||||||
}
|
|
||||||
|
|
||||||
const checkHip2 = {
|
|
||||||
x1: Big(afterNextLine.x2).plus(scale2.times(xVector2)).toNumber(),
|
|
||||||
y1: Big(afterNextLine.y2).plus(scale2.times(yVector2)).toNumber(),
|
|
||||||
x2: oppositeMidX.plus(addOppositeX2).toNumber(),
|
|
||||||
y2: oppositeMidY.plus(addOppositeY2).toNumber(),
|
|
||||||
}
|
|
||||||
|
|
||||||
const intersection1 = findRoofIntersection(roof, checkHip1, { x: oppositeMidX.plus(addOppositeX1), y: oppositeMidY.plus(addOppositeY1) })
|
|
||||||
const intersection2 = findRoofIntersection(roof, checkHip2, { x: oppositeMidX.plus(addOppositeX2), y: oppositeMidY.plus(addOppositeY2) })
|
|
||||||
|
|
||||||
const afterNextDegree = afterNextLine.attributes.pitch > 0 ? getDegreeByChon(afterNextLine.attributes.pitch) : afterNextLine.attributes.degree
|
|
||||||
|
|
||||||
if (intersection1) {
|
|
||||||
const hipLine = drawHipLine(
|
|
||||||
[intersection1.intersection.x, intersection1.intersection.y, oppositeMidX.plus(addOppositeX1), oppositeMidY.plus(addOppositeY1)],
|
|
||||||
canvas,
|
|
||||||
roof,
|
|
||||||
textMode,
|
|
||||||
null,
|
|
||||||
nextDegree,
|
|
||||||
afterNextDegree,
|
|
||||||
)
|
|
||||||
baseHipLines.push({
|
|
||||||
x1: afterNextLine.x1,
|
|
||||||
y1: afterNextLine.y1,
|
|
||||||
x2: oppositeMidX.plus(addOppositeX1).toNumber(),
|
|
||||||
y2: oppositeMidY.plus(addOppositeY1).toNumber(),
|
|
||||||
line: hipLine,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if (intersection2) {
|
|
||||||
const hipLine = drawHipLine(
|
|
||||||
[intersection2.intersection.x, intersection2.intersection.y, oppositeMidX.plus(addOppositeX2), oppositeMidY.plus(addOppositeY2)],
|
|
||||||
canvas,
|
|
||||||
roof,
|
|
||||||
textMode,
|
|
||||||
null,
|
|
||||||
prevDegree,
|
|
||||||
afterNextDegree,
|
|
||||||
)
|
|
||||||
baseHipLines.push({
|
|
||||||
x1: afterNextLine.x2,
|
|
||||||
y1: afterNextLine.y2,
|
|
||||||
x2: oppositeMidX.plus(addOppositeX2).toNumber(),
|
|
||||||
y2: oppositeMidY.plus(addOppositeY2).toNumber(),
|
|
||||||
line: hipLine,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
oppositeMidX = Big(afterNextLine.x1).plus(Big(afterNextLine.x2)).div(2).plus(Big(prevVectorX).neg().times(afterNextLine.attributes.offset))
|
|
||||||
oppositeMidY = Big(afterNextLine.y1).plus(Big(afterNextLine.y2)).div(2).plus(Big(prevVectorY).neg().times(afterNextLine.attributes.offset))
|
|
||||||
}
|
|
||||||
|
|
||||||
const vectorOppositeX = Math.sign(currentMidX.minus(oppositeMidX))
|
|
||||||
const vectorOppositeY = Math.sign(currentMidY.minus(oppositeMidY))
|
|
||||||
|
|
||||||
if (vectorMidX === vectorOppositeX && vectorMidY === vectorOppositeY && baseRidgeCount < getMaxRidge(baseLines.length)) {
|
|
||||||
const ridge = drawRidgeLine(
|
|
||||||
[currentMidX.toNumber(), currentMidY.toNumber(), oppositeMidX.toNumber(), oppositeMidY.toNumber()],
|
|
||||||
canvas,
|
|
||||||
roof,
|
|
||||||
textMode,
|
|
||||||
)
|
|
||||||
baseRidgeLines.push(ridge)
|
|
||||||
baseRidgeCount++
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log('4각 아님')
|
|
||||||
const vectorMidX = Math.sign(Big(nextLine.x2).minus(nextLine.x1))
|
|
||||||
const vectorMidY = Math.sign(Big(nextLine.y2).minus(nextLine.y1))
|
|
||||||
let oppositeMidX = currentMidX,
|
|
||||||
oppositeMidY = currentMidY
|
|
||||||
let prevOppositeMidX, prevOppositeMidY, nextOppositeMidX, nextOppositeMidY
|
|
||||||
const beforePrevOffset =
|
|
||||||
currentAngle === beforePrevAngle
|
|
||||||
? Big(beforePrevLine.attributes.offset)
|
|
||||||
: Big(beforePrevLine.attributes.offset).plus(currentLine.attributes.offset)
|
|
||||||
const afterNextOffset =
|
|
||||||
currentAngle === afterNextAngle
|
|
||||||
? Big(afterNextLine.attributes.offset)
|
|
||||||
: Big(afterNextLine.attributes.offset).plus(currentLine.attributes.offset)
|
|
||||||
const prevSize = Big(prevLine.attributes.planeSize).div(10)
|
|
||||||
const nextSize = Big(nextLine.attributes.planeSize).div(10)
|
|
||||||
|
|
||||||
/** 다음 라인이 그 다음 라인과의 사이에 추녀마루가 존재 하는지 확인. 처마-처마 인 경우 추녀마루*/
|
|
||||||
if (eavesType.includes(afterNextLine.attributes?.type)) {
|
|
||||||
} else {
|
|
||||||
if (vectorMidX === 0) {
|
|
||||||
prevOppositeMidY = currentMidY.plus(prevSize.plus(beforePrevOffset).times(vectorMidY))
|
|
||||||
prevOppositeMidX = currentMidX
|
|
||||||
} else {
|
|
||||||
prevOppositeMidX = currentMidX.plus(prevSize.plus(beforePrevOffset).times(vectorMidX))
|
|
||||||
prevOppositeMidY = currentMidY
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 이전 라인이 그 이전 라인과의 사이에 추녀마루가 존재 하는지 확인. 처마-처마 인 경우 추녀마루*/
|
|
||||||
if (eavesType.includes(beforePrevLine.attributes?.type)) {
|
|
||||||
} else {
|
|
||||||
if (vectorMidX === 0) {
|
|
||||||
nextOppositeMidY = currentMidY.plus(nextSize.plus(afterNextOffset).times(vectorMidY))
|
|
||||||
nextOppositeMidX = currentMidX
|
|
||||||
} else {
|
|
||||||
nextOppositeMidX = currentMidX.plus(nextSize.plus(afterNextOffset).times(vectorMidX))
|
|
||||||
nextOppositeMidY = currentMidY
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const checkPrevSize = currentMidX.minus(prevOppositeMidX).pow(2).plus(currentMidY.minus(prevOppositeMidY).pow(2)).sqrt()
|
|
||||||
const checkNextSize = currentMidX.minus(nextOppositeMidX).pow(2).plus(currentMidY.minus(nextOppositeMidY).pow(2)).sqrt()
|
|
||||||
|
|
||||||
/** 두 포인트 중에 current와 가까운 포인트를 사용*/
|
|
||||||
if (checkPrevSize.gt(checkNextSize)) {
|
|
||||||
oppositeMidY = nextOppositeMidY
|
|
||||||
oppositeMidX = nextOppositeMidX
|
|
||||||
} else {
|
|
||||||
oppositeMidY = prevOppositeMidY
|
|
||||||
oppositeMidX = prevOppositeMidX
|
|
||||||
}
|
|
||||||
|
|
||||||
if (baseRidgeCount < getMaxRidge(baseLines.length)) {
|
|
||||||
const ridgeLine = drawRidgeLine([currentMidX, currentMidY, oppositeMidX, oppositeMidY], canvas, roof, textMode)
|
|
||||||
baseRidgeLines.push(ridgeLine)
|
|
||||||
baseRidgeCount++
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
baseGableRidgeLines = uniqueRidgeLines
|
||||||
|
|
||||||
|
console.log('baseGableRidgeLines : ', baseGableRidgeLines)
|
||||||
|
|
||||||
/** 박공지붕 polygon 생성 */
|
/** 박공지붕 polygon 생성 */
|
||||||
drawGablePolygonFirst.forEach((current) => {
|
drawGablePolygonFirst.forEach((current) => {
|
||||||
const { currentBaseLine, prevBaseLine, nextBaseLine } = current
|
const { currentBaseLine, prevBaseLine, nextBaseLine } = current
|
||||||
@ -2093,14 +1712,24 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => {
|
|||||||
roofY2 = roofY1
|
roofY2 = roofY1
|
||||||
}
|
}
|
||||||
|
|
||||||
const prevRoofLine = roof.lines.find(
|
let prevRoofLine, nextRoofLine
|
||||||
(line) => currentVectorX !== Math.sign(line.x2 - line.x1) && line.x2 === roofX1.toNumber() && line.y2 === roofY1.toNumber(),
|
const roofEdge = { vertex1: { x: roofX1.toNumber(), y: roofY1.toNumber() }, vertex2: { x: roofX2.toNumber(), y: roofY2.toNumber() } }
|
||||||
)
|
roof.lines
|
||||||
const nextRoofLine = roof.lines.find(
|
.filter((line) => (currentVectorX === 0 ? line.y1 === line.y2 : line.x1 === line.x2))
|
||||||
(line) => currentVectorX !== Math.sign(line.x2 - line.x1) && line.x1 === roofX2.toNumber() && line.y1 === roofY2.toNumber(),
|
.forEach((line) => {
|
||||||
)
|
const lineEdge = { vertex1: { x: line.x1, y: line.y1 }, vertex2: { x: line.x2, y: line.y2 } }
|
||||||
|
const intersection = edgesIntersection(roofEdge, lineEdge)
|
||||||
|
if (intersection) {
|
||||||
|
if (roofX1.eq(intersection.x) && roofY1.eq(intersection.y)) {
|
||||||
|
prevRoofLine = line
|
||||||
|
}
|
||||||
|
if (roofX2.eq(intersection.x) && roofY2.eq(intersection.y)) {
|
||||||
|
nextRoofLine = line
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const prevRoofEdge = { vertex1: { x: prevRoofLine.x1, y: prevRoofLine.y1 }, vertex2: { x: prevRoofLine.x2, y: prevRoofLine.y2 } }
|
const prevRoofEdge = { vertex1: { x: prevRoofLine.x2, y: prevRoofLine.y2 }, vertex2: { x: prevRoofLine.x1, y: prevRoofLine.y1 } }
|
||||||
const nextRoofEdge = { vertex1: { x: nextRoofLine.x1, y: nextRoofLine.y1 }, vertex2: { x: nextRoofLine.x2, y: nextRoofLine.y2 } }
|
const nextRoofEdge = { vertex1: { x: nextRoofLine.x1, y: nextRoofLine.y1 }, vertex2: { x: nextRoofLine.x2, y: nextRoofLine.y2 } }
|
||||||
|
|
||||||
baseGableRidgeLines.forEach((ridge) => {
|
baseGableRidgeLines.forEach((ridge) => {
|
||||||
@ -2110,21 +1739,18 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => {
|
|||||||
if (prevIs) {
|
if (prevIs) {
|
||||||
prevLineRidges.push({
|
prevLineRidges.push({
|
||||||
ridge,
|
ridge,
|
||||||
size: calcLinePlaneSize({ x1: ridgeEdge.vertex1.x, y1: ridgeEdge.vertex1.y, x2: prevIs.x, y2: prevIs.y }),
|
size: calcLinePlaneSize({ x1: roofX1, y1: roofY1, x2: prevIs.x, y2: prevIs.y }),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (nextIs) {
|
if (nextIs) {
|
||||||
nextLineRidges.push({
|
nextLineRidges.push({
|
||||||
ridge,
|
ridge,
|
||||||
size: calcLinePlaneSize({ x1: ridgeEdge.vertex1.x, y1: ridgeEdge.vertex1.y, x2: nextIs.x, y2: nextIs.y }),
|
size: calcLinePlaneSize({ x1: roofX2, y1: roofY2, x2: nextIs.x, y2: nextIs.y }),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const polygonPoints = [
|
const polygonPoints = []
|
||||||
{ x: roofX1.toNumber(), y: roofY1.toNumber() },
|
|
||||||
{ x: roofX2.toNumber(), y: roofY2.toNumber() },
|
|
||||||
]
|
|
||||||
|
|
||||||
let prevLineRidge, nextLineRidge
|
let prevLineRidge, nextLineRidge
|
||||||
if (prevLineRidges.length > 0) {
|
if (prevLineRidges.length > 0) {
|
||||||
@ -2154,9 +1780,44 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => {
|
|||||||
nextLineRidge = nextLineRidges[0].ridge
|
nextLineRidge = nextLineRidges[0].ridge
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 마루에서 현재라인으로 향하는 외벽선까지의 포인트를 확인 하여 처리*/
|
||||||
|
let checkEdge
|
||||||
|
if (currentVectorX === 0) {
|
||||||
|
checkEdge = { vertex1: { x: prevLineRidge.x1, y: roofY1.toNumber() }, vertex2: { x: roofX1.toNumber(), y: roofY1.toNumber() } }
|
||||||
|
} else {
|
||||||
|
checkEdge = { vertex1: { x: roofX1.toNumber(), y: prevLineRidge.y1 }, vertex2: { x: roofX1.toNumber(), y: roofY1.toNumber() } }
|
||||||
|
}
|
||||||
|
const checkVectorX = Math.sign(checkEdge.vertex1.x - checkEdge.vertex2.x)
|
||||||
|
const checkVectorY = Math.sign(checkEdge.vertex1.y - checkEdge.vertex2.y)
|
||||||
|
const intersectPoints = []
|
||||||
|
roof.lines
|
||||||
|
.filter((line) => (currentVectorX === 0 ? line.x1 === line.x2 : line.y1 === line.y2))
|
||||||
|
.forEach((line) => {
|
||||||
|
const lineEdge = { vertex1: { x: line.x1, y: line.y1 }, vertex2: { x: line.x2, y: line.y2 } }
|
||||||
|
const is = edgesIntersection(checkEdge, lineEdge)
|
||||||
|
if (is) {
|
||||||
|
const isVectorX = Math.sign(checkEdge.vertex1.x - is.x)
|
||||||
|
const isVectorY = Math.sign(checkEdge.vertex1.y - is.y)
|
||||||
|
const isLineOtherPoint = is.x === line.x1 && is.y === line.y1 ? { x: line.x2, y: line.y2 } : { x: line.x1, y: line.y1 }
|
||||||
|
const lineVectorX = Math.sign(isLineOtherPoint.x - is.x)
|
||||||
|
const lineVectorY = Math.sign(isLineOtherPoint.y - is.y)
|
||||||
|
if (checkVectorX === isVectorX && checkVectorY === isVectorY && lineVectorX === currentVectorX && lineVectorY === currentVectorY) {
|
||||||
|
intersectPoints.push(is)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let intersect = intersectPoints[0]
|
||||||
|
if (currentVectorX === 0) {
|
||||||
|
polygonPoints.push({ x: intersect.x, y: roofY1.toNumber() }, { x: intersect.x, y: roofY2.toNumber() })
|
||||||
|
} else {
|
||||||
|
polygonPoints.push({ x: roofX1.toNumber(), y: intersect.y }, { x: roofX2.toNumber(), y: intersect.y })
|
||||||
|
}
|
||||||
|
|
||||||
if (prevLineRidge === nextLineRidge) {
|
if (prevLineRidge === nextLineRidge) {
|
||||||
|
/** 4각*/
|
||||||
polygonPoints.push({ x: prevLineRidge.x1, y: prevLineRidge.y1 }, { x: prevLineRidge.x2, y: prevLineRidge.y2 })
|
polygonPoints.push({ x: prevLineRidge.x1, y: prevLineRidge.y1 }, { x: prevLineRidge.x2, y: prevLineRidge.y2 })
|
||||||
} else {
|
} else {
|
||||||
|
/** 6각이상*/
|
||||||
let isOverLap =
|
let isOverLap =
|
||||||
currentVectorX === 0
|
currentVectorX === 0
|
||||||
? (prevLineRidge.y1 <= nextLineRidge.y1 && prevLineRidge.y2 >= nextLineRidge.y1) ||
|
? (prevLineRidge.y1 <= nextLineRidge.y1 && prevLineRidge.y2 >= nextLineRidge.y1) ||
|
||||||
@ -2167,12 +1828,13 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => {
|
|||||||
(prevLineRidge.x1 >= nextLineRidge.x1 && prevLineRidge.x2 <= nextLineRidge.x1) ||
|
(prevLineRidge.x1 >= nextLineRidge.x1 && prevLineRidge.x2 <= nextLineRidge.x1) ||
|
||||||
(prevLineRidge.x1 <= nextLineRidge.x2 && prevLineRidge.x2 >= nextLineRidge.x2) ||
|
(prevLineRidge.x1 <= nextLineRidge.x2 && prevLineRidge.x2 >= nextLineRidge.x2) ||
|
||||||
(prevLineRidge.x1 >= nextLineRidge.x2 && prevLineRidge.x2 <= nextLineRidge.x2)
|
(prevLineRidge.x1 >= nextLineRidge.x2 && prevLineRidge.x2 <= nextLineRidge.x2)
|
||||||
console.log('isOverLap : ', isOverLap)
|
|
||||||
if (isOverLap) {
|
if (isOverLap) {
|
||||||
const prevDistance = currentVectorX === 0 ? Math.abs(prevLineRidge.x1 - roofX1.toNumber()) : Math.abs(prevLineRidge.y1 - roofY1.toNumber())
|
const prevDistance = currentVectorX === 0 ? Math.abs(prevLineRidge.x1 - roofX1.toNumber()) : Math.abs(prevLineRidge.y1 - roofY1.toNumber())
|
||||||
const nextDistance = currentVectorX === 0 ? Math.abs(nextLineRidge.x1 - roofX1.toNumber()) : Math.abs(nextLineRidge.y1 - roofY1.toNumber())
|
const nextDistance = currentVectorX === 0 ? Math.abs(nextLineRidge.x1 - roofX1.toNumber()) : Math.abs(nextLineRidge.y1 - roofY1.toNumber())
|
||||||
/** 현재 지붕 라인과 먼 라인의 포인트를 온전히 사용한다. */
|
/** 현재 지붕 라인과 먼 라인의 포인트를 온전히 사용한다. */
|
||||||
if (prevDistance < nextDistance) {
|
if (prevDistance === nextDistance) {
|
||||||
|
console.log('prevDistance === nextDistance')
|
||||||
|
} else if (prevDistance < nextDistance) {
|
||||||
polygonPoints.push({ x: nextLineRidge.x1, y: nextLineRidge.y1 }, { x: nextLineRidge.x2, y: nextLineRidge.y2 })
|
polygonPoints.push({ x: nextLineRidge.x1, y: nextLineRidge.y1 }, { x: nextLineRidge.x2, y: nextLineRidge.y2 })
|
||||||
/** 이전라인과 교차한 마루의 포인트*/
|
/** 이전라인과 교차한 마루의 포인트*/
|
||||||
const prevRidgePoint1 =
|
const prevRidgePoint1 =
|
||||||
@ -2227,11 +1889,178 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => {
|
|||||||
polygonPoints.push(nextRidgePoint2)
|
polygonPoints.push(nextRidgePoint2)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
/** 마루가 겹치지 않을때 */
|
||||||
|
const otherRidgeLines = []
|
||||||
|
|
||||||
|
baseGableRidgeLines
|
||||||
|
.filter((ridge) => ridge !== prevLineRidge && ridge !== nextLineRidge)
|
||||||
|
.filter((ridge) => (currentVectorX === 0 ? ridge.x1 === ridge.x2 : ridge.y1 === ridge.y2))
|
||||||
|
.filter((ridge) =>
|
||||||
|
currentVectorX === 0 ? nextVectorX === Math.sign(nextLine.x1 - ridge.x1) : nextVectorY === Math.sign(nextLine.y1 - ridge.y1),
|
||||||
|
)
|
||||||
|
.forEach((ridge) => {
|
||||||
|
const size = currentVectorX === 0 ? Math.abs(nextLine.x1 - ridge.x1) : Math.abs(nextLine.y1 - ridge.y1)
|
||||||
|
otherRidgeLines.push({ ridge, size })
|
||||||
|
})
|
||||||
|
if (otherRidgeLines.length > 0) {
|
||||||
|
const otherRidge = otherRidgeLines.sort((a, b) => a.size - b.size)[0].ridge
|
||||||
|
/**
|
||||||
|
* otherRidge이 prevRidgeLine, nextRidgeLine 과 currentLine의 사이에 있는지 확인해서 분할하여 작업
|
||||||
|
* 지붕의 덮힘이 다르기 때문
|
||||||
|
*/
|
||||||
|
const isInside =
|
||||||
|
currentVectorX === 0
|
||||||
|
? Math.abs(currentLine.x1 - otherRidge.x1) < Math.abs(currentLine.x1 - prevLineRidge.x1) &&
|
||||||
|
Math.abs(currentLine.x1 - otherRidge.x1) < Math.abs(currentLine.x1 - nextLineRidge.x1)
|
||||||
|
: Math.abs(currentLine.y1 - otherRidge.y1) < Math.abs(currentLine.y1 - prevLineRidge.y1) &&
|
||||||
|
Math.abs(currentLine.y1 - otherRidge.y1) < Math.abs(currentLine.y1 - nextLineRidge.y1)
|
||||||
|
|
||||||
|
if (isInside) {
|
||||||
|
polygonPoints.push(
|
||||||
|
{ x: prevLineRidge.x1, y: prevLineRidge.y1 },
|
||||||
|
{ x: prevLineRidge.x2, y: prevLineRidge.y2 },
|
||||||
|
{ x: nextLineRidge.x1, y: nextLineRidge.y1 },
|
||||||
|
{ x: nextLineRidge.x2, y: nextLineRidge.y2 },
|
||||||
|
)
|
||||||
|
|
||||||
|
let ridgeAllPoints = [
|
||||||
|
{ x: prevLineRidge.x1, y: prevLineRidge.y1 },
|
||||||
|
{ x: prevLineRidge.x2, y: prevLineRidge.y2 },
|
||||||
|
{ x: nextLineRidge.x1, y: nextLineRidge.y1 },
|
||||||
|
{ x: nextLineRidge.x2, y: nextLineRidge.y2 },
|
||||||
|
]
|
||||||
|
let ridgePoints = []
|
||||||
|
ridgeAllPoints.forEach((point) => {
|
||||||
|
let isOnLine = false
|
||||||
|
roof.lines.forEach((line) => {
|
||||||
|
if (isPointOnLine({ x1: line.x1, y1: line.y1, x2: line.x2, y2: line.y2 }, point)) {
|
||||||
|
isOnLine = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (!isOnLine) {
|
||||||
|
ridgePoints.push(point)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (ridgePoints.length === 2) {
|
||||||
|
if (Math.sign(otherRidge.x1 - otherRidge.x2) === 0) {
|
||||||
|
polygonPoints.push({ x: otherRidge.x1, y: ridgePoints[0].y }, { x: otherRidge.x1, y: ridgePoints[1].y })
|
||||||
|
} else {
|
||||||
|
polygonPoints.push({ x: ridgePoints[0].x, y: otherRidge.y1 }, { x: ridgePoints[1].x, y: otherRidge.y1 })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
polygonPoints.push({ x: otherRidge.x1, y: otherRidge.y1 }, { x: otherRidge.x2, y: otherRidge.y2 })
|
||||||
|
|
||||||
|
let ridgePoints = [
|
||||||
|
{ x: prevLineRidge.x1, y: prevLineRidge.y1 },
|
||||||
|
{ x: prevLineRidge.x2, y: prevLineRidge.y2 },
|
||||||
|
{ x: nextLineRidge.x1, y: nextLineRidge.y1 },
|
||||||
|
{ x: nextLineRidge.x2, y: nextLineRidge.y2 },
|
||||||
|
]
|
||||||
|
|
||||||
|
ridgePoints.forEach((point) => {
|
||||||
|
let isOnLine = false
|
||||||
|
roof.lines.forEach((line) => {
|
||||||
|
if (isPointOnLine({ x1: line.x1, y1: line.y1, x2: line.x2, y2: line.y2 }, point)) {
|
||||||
|
isOnLine = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (isOnLine) {
|
||||||
|
polygonPoints.push(point)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (Math.sign(otherRidge.x1 - otherRidge.x2) === 0) {
|
||||||
|
const prevY =
|
||||||
|
(prevLineRidge.y1 <= otherRidge.y1 && otherRidge.y1 <= prevLineRidge.y2) ||
|
||||||
|
(prevLineRidge.y1 >= otherRidge.y1 && otherRidge.y1 >= prevLineRidge.y2)
|
||||||
|
? otherRidge.y1
|
||||||
|
: otherRidge.y2
|
||||||
|
const nextY =
|
||||||
|
(nextLineRidge.y1 <= otherRidge.y1 && otherRidge.y1 <= nextLineRidge.y2) ||
|
||||||
|
(nextLineRidge.y1 >= otherRidge.y1 && otherRidge.y1 >= nextLineRidge.y2)
|
||||||
|
? otherRidge.y1
|
||||||
|
: otherRidge.y2
|
||||||
|
polygonPoints.push({ x: prevLineRidge.x1, y: prevY }, { x: nextLineRidge.x1, y: nextY })
|
||||||
|
} else {
|
||||||
|
const prevX =
|
||||||
|
(prevLineRidge.x1 <= otherRidge.x1 && otherRidge.x1 <= prevLineRidge.x2) ||
|
||||||
|
(prevLineRidge.x1 >= otherRidge.x1 && otherRidge.x1 >= prevLineRidge.x2)
|
||||||
|
? otherRidge.x1
|
||||||
|
: otherRidge.x2
|
||||||
|
const nextX =
|
||||||
|
(nextLineRidge.x1 <= otherRidge.x1 && otherRidge.x1 <= nextLineRidge.x2) ||
|
||||||
|
(nextLineRidge.x1 >= otherRidge.x1 && otherRidge.x1 >= nextLineRidge.x2)
|
||||||
|
? otherRidge.x1
|
||||||
|
: otherRidge.x2
|
||||||
|
polygonPoints.push({ x: prevX, y: prevLineRidge.y1 }, { x: nextX, y: nextLineRidge.y1 })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const sortedPolygonPoints = getSortedPoint(polygonPoints)
|
const sortedPolygonPoints = getSortedPoint(polygonPoints)
|
||||||
|
|
||||||
|
/** 외벽선 밖으로 나가있는 포인트*/
|
||||||
|
const outsidePoints = polygonPoints.filter((point) => {
|
||||||
|
let isOutside = true
|
||||||
|
roof.lines.forEach((line) => {
|
||||||
|
if (
|
||||||
|
(line.x1 <= point.x && line.x2 >= point.x && line.y1 <= point.y && line.y2 >= point.y) ||
|
||||||
|
(line.x1 >= point.x && line.x2 <= point.x && line.y1 >= point.y && line.y2 <= point.y)
|
||||||
|
) {
|
||||||
|
isOutside = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
baseGableRidgeLines.forEach((line) => {
|
||||||
|
if (
|
||||||
|
(line.x1 <= point.x && line.x2 >= point.x && line.y1 <= point.y && line.y2 >= point.y) ||
|
||||||
|
(line.x1 >= point.x && line.x2 <= point.x && line.y1 >= point.y && line.y2 <= point.y)
|
||||||
|
) {
|
||||||
|
isOutside = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return isOutside
|
||||||
|
})
|
||||||
|
|
||||||
|
if (outsidePoints.length > 0) {
|
||||||
|
sortedPolygonPoints.forEach((currentPoint, index) => {
|
||||||
|
if (outsidePoints.includes(currentPoint)) {
|
||||||
|
const prevPoint = sortedPolygonPoints[(index - 1 + sortedPolygonPoints.length) % sortedPolygonPoints.length]
|
||||||
|
const nextPoint = sortedPolygonPoints[(index + 1) % sortedPolygonPoints.length]
|
||||||
|
const vectorX = Math.sign(currentPoint.x - prevPoint.x)
|
||||||
|
const vectorY = Math.sign(currentPoint.y - prevPoint.y)
|
||||||
|
|
||||||
|
const checkEdge = { vertex1: { x: prevPoint.x, y: prevPoint.y }, vertex2: { x: currentPoint.x, y: currentPoint.y } }
|
||||||
|
const intersectPoints = []
|
||||||
|
roof.lines
|
||||||
|
.filter((line) => (vectorX === 0 ? line.x1 !== line.x2 : line.y1 !== line.y2))
|
||||||
|
.forEach((line) => {
|
||||||
|
const lineEdge = { vertex1: { x: line.x1, y: line.y1 }, vertex2: { x: line.x2, y: line.y2 } }
|
||||||
|
const is = edgesIntersection(checkEdge, lineEdge)
|
||||||
|
if (is && !is.isIntersectionOutside) {
|
||||||
|
const isVectorX = Math.sign(is.x - prevPoint.x)
|
||||||
|
const isVectorY = Math.sign(is.y - prevPoint.y)
|
||||||
|
if ((vectorX === 0 && vectorY === isVectorY) || (vectorY === 0 && vectorX === isVectorX)) {
|
||||||
|
intersectPoints.push(is)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (intersectPoints.length > 0) {
|
||||||
|
const intersection = intersectPoints[0]
|
||||||
|
if (vectorX === 0) {
|
||||||
|
currentPoint.y = intersection.y
|
||||||
|
nextPoint.y = intersection.y
|
||||||
|
} else {
|
||||||
|
currentPoint.x = intersection.x
|
||||||
|
nextPoint.x = intersection.x
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
sortedPolygonPoints.forEach((startPoint, index) => {
|
sortedPolygonPoints.forEach((startPoint, index) => {
|
||||||
let endPoint
|
let endPoint
|
||||||
if (index === sortedPolygonPoints.length - 1) {
|
if (index === sortedPolygonPoints.length - 1) {
|
||||||
@ -2239,6 +2068,7 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => {
|
|||||||
} else {
|
} else {
|
||||||
endPoint = sortedPolygonPoints[index + 1]
|
endPoint = sortedPolygonPoints[index + 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
const hipLine = drawHipLine([startPoint.x, startPoint.y, endPoint.x, endPoint.y], canvas, roof, textMode, null, currentDegree, currentDegree)
|
const hipLine = drawHipLine([startPoint.x, startPoint.y, endPoint.x, endPoint.y], canvas, roof, textMode, null, currentDegree, currentDegree)
|
||||||
if (currentVectorX === 0) {
|
if (currentVectorX === 0) {
|
||||||
if (Math.sign(startPoint.x - endPoint.x) === 0) {
|
if (Math.sign(startPoint.x - endPoint.x) === 0) {
|
||||||
@ -2251,12 +2081,6 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => {
|
|||||||
}
|
}
|
||||||
baseHipLines.push({ x1: hipLine.x1, y1: hipLine.y1, x2: hipLine.x2, y2: hipLine.y2, line: hipLine })
|
baseHipLines.push({ x1: hipLine.x1, y1: hipLine.y1, x2: hipLine.x2, y2: hipLine.y2, line: hipLine })
|
||||||
})
|
})
|
||||||
|
|
||||||
canvas
|
|
||||||
.getObjects()
|
|
||||||
.filter((obj) => obj.name === 'checkLine' || obj.name === 'checkRoofLine')
|
|
||||||
.forEach((obj) => canvas.remove(obj))
|
|
||||||
canvas.renderAll()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
drawGablePolygonSecond.forEach((current) => {
|
drawGablePolygonSecond.forEach((current) => {
|
||||||
@ -2279,6 +2103,53 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => {
|
|||||||
const prevOffset = prevLine.attributes.offset
|
const prevOffset = prevLine.attributes.offset
|
||||||
const nextOffset = nextLine.attributes.offset
|
const nextOffset = nextLine.attributes.offset
|
||||||
|
|
||||||
|
const prevAngle = calculateAngle(prevLine.startPoint, prevLine.endPoint)
|
||||||
|
const nextAngle = calculateAngle(nextLine.startPoint, nextLine.endPoint)
|
||||||
|
|
||||||
|
const polygonPoints = []
|
||||||
|
if (Big(prevAngle).minus(Big(nextAngle)).abs().eq(180)) {
|
||||||
|
const currentRidge = baseGableRidgeLines.find((line) =>
|
||||||
|
currentVectorX === 0
|
||||||
|
? (line.y1 === y1 && line.y2 === y2) || (line.y1 === y2 && line.y2 === y1)
|
||||||
|
: (line.x1 === x1 && line.x2 === x2) || (line.x1 === x2 && line.x2 === x1),
|
||||||
|
)
|
||||||
|
if (currentRidge) {
|
||||||
|
const ridgeVectorX = Math.sign(currentRidge.x1 - currentRidge.x2)
|
||||||
|
const ridgeVectorY = Math.sign(currentRidge.y1 - currentRidge.y2)
|
||||||
|
|
||||||
|
let checkEdge
|
||||||
|
if (currentVectorX === 0) {
|
||||||
|
checkEdge = { vertex1: { x: currentRidge.x1, y: currentRidge.y1 }, vertex2: { x: currentLine.x1, y: currentRidge.y1 } }
|
||||||
|
} else {
|
||||||
|
checkEdge = { vertex1: { x: currentRidge.x1, y: currentRidge.y1 }, vertex2: { x: currentRidge.x1, y: currentLine.y1 } }
|
||||||
|
}
|
||||||
|
const isRoofLines = []
|
||||||
|
roof.lines
|
||||||
|
.filter((line) => (currentVectorX === 0 ? line.x1 === line.x2 : line.y1 === line.y2))
|
||||||
|
.forEach((line) => {
|
||||||
|
const lineEdge = { vertex1: { x: line.x1, y: line.y1 }, vertex2: { x: line.x2, y: line.y2 } }
|
||||||
|
const is = edgesIntersection(checkEdge, lineEdge)
|
||||||
|
if (is) {
|
||||||
|
const checkVectorX = Math.sign(checkEdge.vertex1.x - checkEdge.vertex2.x)
|
||||||
|
const checkVectorY = Math.sign(checkEdge.vertex1.y - checkEdge.vertex2.y)
|
||||||
|
const isVectorX = Math.sign(checkEdge.vertex1.x - is.x)
|
||||||
|
const isVectorY = Math.sign(checkEdge.vertex1.y - is.y)
|
||||||
|
if ((ridgeVectorX === 0 && checkVectorX === isVectorX) || (ridgeVectorY === 0 && checkVectorY === isVectorY)) {
|
||||||
|
const size = ridgeVectorX === 0 ? Math.abs(checkEdge.vertex1.x - is.x) : Math.abs(checkEdge.vertex1.y - is.y)
|
||||||
|
isRoofLines.push({ line, size })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
isRoofLines.sort((a, b) => a.size - b.size)
|
||||||
|
const roofLine = isRoofLines[0].line
|
||||||
|
polygonPoints.push({ x: currentRidge.x1, y: currentRidge.y1 }, { x: currentRidge.x2, y: currentRidge.y2 })
|
||||||
|
if (ridgeVectorX === 0) {
|
||||||
|
polygonPoints.push({ x: roofLine.x1, y: currentRidge.y1 }, { x: roofLine.x1, y: currentRidge.y2 })
|
||||||
|
} else {
|
||||||
|
polygonPoints.push({ x: currentRidge.x1, y: roofLine.y1 }, { x: currentRidge.x2, y: roofLine.y1 })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
const prevEdge = { vertex1: { x: prevLine.x1, y: prevLine.y1 }, vertex2: { x: prevLine.x2, y: prevLine.y2 } }
|
const prevEdge = { vertex1: { x: prevLine.x1, y: prevLine.y1 }, vertex2: { x: prevLine.x2, y: prevLine.y2 } }
|
||||||
const prevRidge = baseGableRidgeLines.find((ridge) => {
|
const prevRidge = baseGableRidgeLines.find((ridge) => {
|
||||||
const ridgeEdge = { vertex1: { x: ridge.x1, y: ridge.y1 }, vertex2: { x: ridge.x2, y: ridge.y2 } }
|
const ridgeEdge = { vertex1: { x: ridge.x1, y: ridge.y1 }, vertex2: { x: ridge.x2, y: ridge.y2 } }
|
||||||
@ -2332,27 +2203,63 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (currentRidge) {
|
if (currentRidge) {
|
||||||
const vectorX = currentVectorX === 0 ? Math.sign(currentLine.x1 - currentRidge.x1) : 0
|
polygonPoints.push({ x: currentRidge.x1, y: currentRidge.y1 }, { x: currentRidge.x2, y: currentRidge.y2 })
|
||||||
const vectorY = currentVectorY === 0 ? Math.sign(currentLine.y1 - currentRidge.y1) : 0
|
|
||||||
|
|
||||||
const polygonPoints = [
|
/** 마루에서 현재라인으로 향하는 외벽선까지의 포인트를 확인 하여 처리*/
|
||||||
{ x: currentRidge.x1, y: currentRidge.y1 },
|
let checkEdge
|
||||||
{ x: currentRidge.x2, y: currentRidge.y2 },
|
|
||||||
]
|
|
||||||
if (currentVectorX === 0) {
|
if (currentVectorX === 0) {
|
||||||
polygonPoints.push(
|
checkEdge = {
|
||||||
{ x: Big(currentLine.x1).plus(Big(currentOffset).times(vectorX)).toNumber(), y: currentRidge.y1 },
|
vertex1: { x: currentRidge.x1, y: currentRidge.y1 },
|
||||||
{ x: Big(currentLine.x2).plus(Big(currentOffset).times(vectorX)).toNumber(), y: currentRidge.y2 },
|
vertex2: { x: currentLine.x1, y: currentRidge.y1 },
|
||||||
)
|
}
|
||||||
} else {
|
} else {
|
||||||
polygonPoints.push(
|
checkEdge = {
|
||||||
{ x: currentRidge.x1, y: Big(currentLine.y1).plus(Big(currentOffset).times(vectorY)).toNumber() },
|
vertex1: { x: currentRidge.x1, y: currentRidge.y1 },
|
||||||
{ x: currentRidge.x2, y: Big(currentLine.y2).plus(Big(currentOffset).times(vectorY)).toNumber() },
|
vertex2: { x: currentRidge.x1, y: currentLine.y1 },
|
||||||
)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkVectorX = Math.sign(checkEdge.vertex1.x - checkEdge.vertex2.x)
|
||||||
|
const checkVectorY = Math.sign(checkEdge.vertex1.y - checkEdge.vertex2.y)
|
||||||
|
const intersectPoints = []
|
||||||
|
roof.lines
|
||||||
|
.filter((line) => (currentVectorX === 0 ? line.x1 === line.x2 : line.y1 === line.y2))
|
||||||
|
.forEach((line) => {
|
||||||
|
const lineEdge = { vertex1: { x: line.x1, y: line.y1 }, vertex2: { x: line.x2, y: line.y2 } }
|
||||||
|
const is = edgesIntersection(checkEdge, lineEdge)
|
||||||
|
if (is) {
|
||||||
|
const isVectorX = Math.sign(checkEdge.vertex1.x - is.x)
|
||||||
|
const isVectorY = Math.sign(checkEdge.vertex1.y - is.y)
|
||||||
|
const isLineOtherPoint =
|
||||||
|
is.x === line.x1 && is.y === line.y1
|
||||||
|
? { x: line.x2, y: line.y2 }
|
||||||
|
: {
|
||||||
|
x: line.x1,
|
||||||
|
y: line.y1,
|
||||||
|
}
|
||||||
|
const isInPoint =
|
||||||
|
checkVectorX === 0
|
||||||
|
? (currentRidge.x1 <= isLineOtherPoint.x && isLineOtherPoint.x <= currentRidge.x2) ||
|
||||||
|
(currentRidge.x1 >= isLineOtherPoint.x && isLineOtherPoint.x >= currentRidge.x2)
|
||||||
|
: (currentRidge.y1 <= isLineOtherPoint.y && isLineOtherPoint.y <= currentRidge.y2) ||
|
||||||
|
(currentRidge.y1 >= isLineOtherPoint.y && isLineOtherPoint.y >= currentRidge.y2)
|
||||||
|
if (checkVectorX === isVectorX && checkVectorY === isVectorY && isInPoint) {
|
||||||
|
const size = Big(checkEdge.vertex1.x).minus(is.x).abs().pow(2).plus(Big(checkEdge.vertex1.y).minus(is.y).abs().pow(2)).sqrt()
|
||||||
|
intersectPoints.push({ is, size })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
intersectPoints.sort((a, b) => a.size - b.size)
|
||||||
|
let intersect = intersectPoints[0].is
|
||||||
|
if (currentVectorX === 0) {
|
||||||
|
polygonPoints.push({ x: intersect.x, y: currentRidge.y1 }, { x: intersect.x, y: currentRidge.y2 })
|
||||||
|
} else {
|
||||||
|
polygonPoints.push({ x: currentRidge.x1, y: intersect.y }, { x: currentRidge.x2, y: intersect.y })
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const sortedPolygonPoints = getSortedPoint(polygonPoints)
|
const sortedPolygonPoints = getSortedPoint(polygonPoints)
|
||||||
|
|
||||||
sortedPolygonPoints.forEach((startPoint, index) => {
|
sortedPolygonPoints.forEach((startPoint, index) => {
|
||||||
let endPoint
|
let endPoint
|
||||||
if (index === sortedPolygonPoints.length - 1) {
|
if (index === sortedPolygonPoints.length - 1) {
|
||||||
@ -2372,7 +2279,6 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => {
|
|||||||
}
|
}
|
||||||
baseHipLines.push({ x1: hipLine.x1, y1: hipLine.y1, x2: hipLine.x2, y2: hipLine.y2, line: hipLine })
|
baseHipLines.push({ x1: hipLine.x1, y1: hipLine.y1, x2: hipLine.x2, y2: hipLine.y2, line: hipLine })
|
||||||
})
|
})
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
/** ⨆ 모양 처마에 추녀마루를 그린다. */
|
/** ⨆ 모양 처마에 추녀마루를 그린다. */
|
||||||
@ -4716,7 +4622,8 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const innerLines = [...baseRidgeLines, ...baseGableRidgeLines, ...baseHipLines.map((line) => line.line)]
|
const innerLines = [...baseRidgeLines, ...baseGableRidgeLines, ...baseHipLines.map((line) => line.line)]
|
||||||
const uniqueInnerLines = []
|
roof.innerLines = innerLines
|
||||||
|
/*const uniqueInnerLines = []
|
||||||
|
|
||||||
innerLines.forEach((currentLine) => {
|
innerLines.forEach((currentLine) => {
|
||||||
const sameLines = uniqueInnerLines.filter(
|
const sameLines = uniqueInnerLines.filter(
|
||||||
@ -4733,7 +4640,7 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
roof.innerLines = uniqueInnerLines
|
roof.innerLines = uniqueInnerLines*/
|
||||||
|
|
||||||
/** 확인용 라인, 포인트 제거 */
|
/** 확인용 라인, 포인트 제거 */
|
||||||
canvas
|
canvas
|
||||||
@ -7729,18 +7636,20 @@ const getSortedPoint = (points) => {
|
|||||||
let prevPoint = startPoint
|
let prevPoint = startPoint
|
||||||
|
|
||||||
for (let i = 0; i < points.length - 1; i++) {
|
for (let i = 0; i < points.length - 1; i++) {
|
||||||
|
const samePoints = []
|
||||||
points
|
points
|
||||||
.filter((point) => !sortedPoints.includes(point))
|
.filter((point) => !sortedPoints.includes(point))
|
||||||
.forEach((point) => {
|
.forEach((point) => {
|
||||||
if (i % 2 === 1 && prevPoint.y === point.y) {
|
if (i % 2 === 1 && prevPoint.y === point.y) {
|
||||||
sortedPoints.push(point)
|
samePoints.push({ point, size: Math.abs(point.x - prevPoint.x) })
|
||||||
prevPoint = point
|
|
||||||
}
|
}
|
||||||
if (i % 2 === 0 && prevPoint.x === point.x) {
|
if (i % 2 === 0 && prevPoint.x === point.x) {
|
||||||
sortedPoints.push(point)
|
samePoints.push({ point, size: Math.abs(point.y - prevPoint.y) })
|
||||||
prevPoint = point
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
const samePoint = samePoints.sort((a, b) => a.size - b.size)[0].point
|
||||||
|
sortedPoints.push(samePoint)
|
||||||
|
prevPoint = samePoint
|
||||||
}
|
}
|
||||||
return sortedPoints
|
return sortedPoints
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user