하단지붕선 작성 로직 추가.
This commit is contained in:
parent
fd024cf30b
commit
494b06bfe3
@ -4676,8 +4676,8 @@ export const drawRoofByAttribute = (roofId, canvas, textMode) => {
|
||||
}
|
||||
}
|
||||
}
|
||||
const checkNewLine = new fabric.Line(linePoint, { stroke: 'cyan', strokeWidth: 4, parentId: roofId, name: 'check' })
|
||||
canvas.add(checkNewLine).renderAll()
|
||||
// const checkNewLine = new fabric.Line(linePoint, { stroke: 'cyan', strokeWidth: 4, parentId: roofId, name: 'check' })
|
||||
// canvas.add(checkNewLine).renderAll()
|
||||
|
||||
newAnalysis.push({
|
||||
start: { x: linePoint[0], y: linePoint[1] },
|
||||
@ -4839,8 +4839,8 @@ export const drawRoofByAttribute = (roofId, canvas, textMode) => {
|
||||
})
|
||||
}
|
||||
|
||||
//하단 지붕 라인처리
|
||||
const downRoofLines = []
|
||||
//케라바에서 파생된 하단 지붕 라인처리
|
||||
const downRoofGable = []
|
||||
baseLines.forEach((baseLine, index) => {
|
||||
const nextLine = baseLines[(index + 1) % baseLines.length]
|
||||
const prevLine = baseLines[(index - 1 + baseLines.length) % baseLines.length]
|
||||
@ -4852,12 +4852,205 @@ export const drawRoofByAttribute = (roofId, canvas, textMode) => {
|
||||
if (
|
||||
prevLineVector.x === nextLineVector.x &&
|
||||
prevLineVector.y === nextLineVector.y &&
|
||||
baseLine.attributes.type === LINE_TYPE.WALLLINE.EAVES &&
|
||||
(prevLine.attributes.type === LINE_TYPE.WALLLINE.GABLE || nextLine.attributes.type === LINE_TYPE.WALLLINE.GABLE)
|
||||
) {
|
||||
downRoofLines.push(index)
|
||||
downRoofGable.push({ currLine: baseLine, currIndex: index })
|
||||
}
|
||||
})
|
||||
|
||||
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)) }
|
||||
|
||||
//어느쪽이 기준인지 확인.
|
||||
//대각선 제외
|
||||
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)) }
|
||||
|
||||
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 (currVector.x === -1) {
|
||||
if (prevVector.y === 1 && nextVector.y === 1) {
|
||||
gableLine = prevLine
|
||||
}
|
||||
if (prevVector.y === -1 && nextVector.y === -1) {
|
||||
gableLine = nextLine
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//세로선
|
||||
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 (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 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
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
//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))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
//추가된 하단 지붕 라인 innerLines에 추가.
|
||||
innerLines.push(...downRoofLines)
|
||||
|
||||
//지붕선에 따라 라인추가 작업 처리.
|
||||
const innerLinesPoints = []
|
||||
innerLines.forEach((line) => {
|
||||
@ -4869,9 +5062,8 @@ export const drawRoofByAttribute = (roofId, canvas, textMode) => {
|
||||
roof.lines.forEach((currentLine, index) => {
|
||||
const prevLine = roof.lines[(index - 1 + roof.lines.length) % roof.lines.length]
|
||||
const nextLine = roof.lines[(index + 1) % roof.lines.length]
|
||||
const prevDegree = getDegreeByChon(prevLine.attributes.pitch)
|
||||
const nextDegree = getDegreeByChon(nextLine.attributes.pitch)
|
||||
console.log('prevDegree, nextDegree: ', prevDegree, nextDegree)
|
||||
const prevDegree = prevLine.attributes.pitch ? getDegreeByChon(prevLine.attributes.pitch) : 0
|
||||
const nextDegree = nextLine.attributes.pitch ? getDegreeByChon(nextLine.attributes.pitch) : 0
|
||||
|
||||
const splitPoint = []
|
||||
let hasOverlapLine = false
|
||||
@ -4929,730 +5121,6 @@ export const drawRoofByAttribute = (roofId, canvas, textMode) => {
|
||||
.filter((object) => object.name === 'check')
|
||||
.forEach((object) => canvas.remove(object))
|
||||
canvas.renderAll()
|
||||
//return
|
||||
/*while (linesAnalysis.length > 0 && iterations < MAX_ITERATIONS) {
|
||||
iterations++
|
||||
|
||||
linesAnalysis.forEach((line) => {
|
||||
const point = [line.start.x, line.start.y, line.end.x, line.end.y]
|
||||
const checkLine = new fabric.Line(point, {
|
||||
stroke: 'red',
|
||||
strokeWidth: 2,
|
||||
parentId: roofId,
|
||||
name: 'check',
|
||||
})
|
||||
canvas.add(checkLine)
|
||||
canvas.renderAll()
|
||||
})
|
||||
// 각 가선분의 최단 교점 찾기
|
||||
const intersections = []
|
||||
for (let i = 0; i < linesAnalysis.length; i++) {
|
||||
let minDistance = Infinity //최단거리
|
||||
let intersectPoint = null //교점 좌표
|
||||
let partners = new Set() //교점 선분의 index
|
||||
|
||||
const lineI = linesAnalysis[i]
|
||||
const lengthI = Math.sqrt(Math.pow(lineI.end.x - lineI.start.x, 2) + Math.pow(lineI.end.y - lineI.start.y, 2))
|
||||
console.log('lengthI', lengthI)
|
||||
const checkLineI = new fabric.Line([lineI.start.x, lineI.start.y, lineI.end.x, lineI.end.y], {
|
||||
stroke: 'blue',
|
||||
strokeWidth: 2,
|
||||
parentId: roofId,
|
||||
name: 'check',
|
||||
})
|
||||
canvas.add(checkLineI).renderAll()
|
||||
|
||||
if (lineI.type === TYPES.GABLE_LINE && lineI.connectCnt > 1) continue
|
||||
|
||||
if (lengthI > EPSILON) {
|
||||
const otherLines = linesAnalysis.filter((j) => j !== lineI)
|
||||
const zeroLines = linesAnalysis.filter((j) => Math.sqrt(Math.pow(j.end.x - j.start.x, 2) + Math.pow(j.end.y - j.start.y, 2)) < EPSILON)
|
||||
if (otherLines.length === zeroLines.length) {
|
||||
zeroLines.forEach((j) => {
|
||||
const jIndex = linesAnalysis.indexOf(j)
|
||||
if (isPointOnLineNew({ x1: lineI.start.x, y1: lineI.start.y, x2: lineI.end.x, y2: lineI.end.y }, { x: j.start.x, y: j.start.y })) {
|
||||
const distance = Math.sqrt(Math.pow(j.start.x - lineI.start.x, 2) + Math.pow(j.start.y - lineI.start.y, 2))
|
||||
if (distance < minDistance) {
|
||||
minDistance = distance
|
||||
intersectPoint = { x: j.start.x, y: j.start.y }
|
||||
partners = new Set([jIndex])
|
||||
} else if (almostEqual(distance, minDistance)) {
|
||||
partners.add(jIndex)
|
||||
}
|
||||
}
|
||||
})
|
||||
if (intersectPoint) {
|
||||
intersections.push({ index: i, intersectPoint, partners, distance: minDistance })
|
||||
partners.forEach((j) => {
|
||||
const p = new Set([i])
|
||||
intersections.push({ index: j, intersectPoint, partners: p, distance: 0 })
|
||||
})
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let j = 0; j < linesAnalysis.length; j++) {
|
||||
const lineJ = linesAnalysis[j]
|
||||
if (lineI === lineJ) continue
|
||||
if (lineI.type === TYPES.GABLE_LINE && lineJ.type === TYPES.GABLE_LINE && i.gableId === lineJ.gableId) continue
|
||||
if (lineJ.type === TYPES.GABLE_LINE && lineJ.connectCnt > 1) continue
|
||||
|
||||
const intersection = lineIntersection(lineI.start, lineI.end, lineJ.start, lineJ.end, canvas)
|
||||
if (intersection) {
|
||||
const distance = Math.sqrt((intersection.x - lineI.start.x) ** 2 + (intersection.y - lineI.start.y) ** 2)
|
||||
const distance2 = Math.sqrt((intersection.x - lineJ.start.x) ** 2 + (intersection.y - lineJ.start.y) ** 2)
|
||||
if (lineI.type === TYPES.GABLE_LINE && distance < EPSILON) continue
|
||||
if (distance < minDistance && !almostEqual(distance, minDistance) && !(distance < EPSILON && distance2 < EPSILON)) {
|
||||
minDistance = distance
|
||||
intersectPoint = intersection
|
||||
partners = new Set([j])
|
||||
} else if (almostEqual(distance, minDistance)) {
|
||||
partners.add(j)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (intersectPoint) {
|
||||
intersections.push({ index: i, intersectPoint, partners, distance: minDistance })
|
||||
}
|
||||
canvas.remove(checkLineI).renderAll()
|
||||
}
|
||||
|
||||
// 제일 가까운 교점부터 처리
|
||||
intersections.sort((a, b) => a.distance - b.distance)
|
||||
|
||||
console.log('intersections', intersections)
|
||||
// 교점에 대한 적합 여부 판단 및 처리.
|
||||
let newAnalysis = [] //신규 발생 선
|
||||
const processed = new Set() //처리된 선
|
||||
for (const { index, intersectPoint, partners } of intersections) {
|
||||
canvas
|
||||
.getObjects()
|
||||
.filter((object) => object.name === 'check')
|
||||
.forEach((object) => canvas.remove(object))
|
||||
canvas.renderAll()
|
||||
let isProceed = false
|
||||
for (const pIndex of partners) {
|
||||
console.log('pIndex : ', pIndex)
|
||||
const check1 = linesAnalysis[index]
|
||||
const checkLine1 = new fabric.Line([check1.start.x, check1.start.y, check1.end.x, check1.end.y], {
|
||||
stroke: 'red',
|
||||
strokeWidth: 2,
|
||||
parentId: roofId,
|
||||
name: 'check',
|
||||
})
|
||||
const checkCircle1 = new fabric.Circle({ left: check1.start.x, top: check1.start.y, radius: 5, fill: 'red', parentId: roofId, name: 'check' })
|
||||
const checkCircle2 = new fabric.Circle({ left: check1.end.x, top: check1.end.y, radius: 5, fill: 'green', parentId: roofId, name: 'check' })
|
||||
canvas.add(checkLine1, checkCircle1, checkCircle2)
|
||||
canvas.renderAll()
|
||||
|
||||
const check2 = linesAnalysis[pIndex]
|
||||
const checkLine2 = new fabric.Line([check2.start.x, check2.start.y, check2.end.x, check2.end.y], {
|
||||
stroke: 'green',
|
||||
strokeWidth: 2,
|
||||
parentId: roofId,
|
||||
name: 'check',
|
||||
})
|
||||
|
||||
const checkCircle3 = new fabric.Circle({ left: check2.start.x, top: check2.start.y, radius: 5, fill: 'red', parentId: roofId, name: 'check' })
|
||||
const checkCircle4 = new fabric.Circle({ left: check2.end.x, top: check2.end.y, radius: 5, fill: 'green', parentId: roofId, name: 'check' })
|
||||
canvas.add(checkLine2, checkCircle3, checkCircle4)
|
||||
canvas.renderAll()
|
||||
|
||||
console.log('!intersectPoint || processed.has(index)', !intersectPoint, processed.has(index))
|
||||
//교점이 없거나, 이미 처리된 선분이면 처리하지 않는다.
|
||||
if (!intersectPoint || processed.has(index)) continue
|
||||
|
||||
const partner = intersections.find((p) => p.index === pIndex)
|
||||
//교점이 없거나, 교점 선분이 없으면 처리하지 않는다.
|
||||
if (!partner || !partner.intersectPoint) continue
|
||||
|
||||
//상호 최단 교점 여부 확인.
|
||||
if (partner.partners.has(index)) {
|
||||
const line1 = linesAnalysis[index]
|
||||
const line2 = linesAnalysis[pIndex]
|
||||
|
||||
//좌,우 선 중 공통 선 존재 확인.
|
||||
const isSameLine = line1.left === line2.left || line1.left === line2.right || line1.right === line2.left || line1.right === line2.right
|
||||
if (isSameLine) {
|
||||
// 현재 선이 처리 되었음을 표기
|
||||
let point1 = [line1.start.x, line1.start.y, intersectPoint.x, intersectPoint.y]
|
||||
let point2 = [line2.start.x, line2.start.y, intersectPoint.x, intersectPoint.y]
|
||||
let length1 = Math.sqrt((point1[2] - point1[0]) ** 2 + (point1[3] - point1[1]) ** 2)
|
||||
let length2 = Math.sqrt((point2[2] - point2[0]) ** 2 + (point2[3] - point2[1]) ** 2)
|
||||
if (length1 < EPSILON && length2 < EPSILON) continue
|
||||
isProceed = true
|
||||
|
||||
//gable라인과 붙는경우 length가 0에 가까우면 포인트를 뒤집는다.
|
||||
if (line1.type === TYPES.GABLE_LINE && length2 < EPSILON) {
|
||||
point2 = [line2.end.x, line2.end.y, intersectPoint.x, intersectPoint.y]
|
||||
length2 = Math.sqrt((point2[2] - point2[0]) ** 2 + (point2[3] - point2[1]) ** 2)
|
||||
}
|
||||
if (line2.type === TYPES.GABLE_LINE && length1 < EPSILON) {
|
||||
point1 = [line1.end.x, line1.end.y, intersectPoint.x, intersectPoint.y]
|
||||
length1 = Math.sqrt((point1[2] - point1[0]) ** 2 + (point1[3] - point1[1]) ** 2)
|
||||
}
|
||||
|
||||
if (length1 > 0 && !alreadyPoints(innerLines, point1)) {
|
||||
if (line1.type === TYPES.HIP) {
|
||||
innerLines.push(drawHipLine(point1, canvas, roof, textMode, null, line1.degree, line1.degree))
|
||||
} else if (line1.type === TYPES.RIDGE) {
|
||||
innerLines.push(drawRidgeLine(point1, canvas, roof, textMode))
|
||||
} else if (line1.type === TYPES.NEW) {
|
||||
const isDiagonal = Math.abs(point1[0] - point1[2]) >= 1 && Math.abs(point1[1] - point1[3]) >= 1
|
||||
if (isDiagonal) {
|
||||
innerLines.push(drawHipLine(point1, canvas, roof, textMode, null, line1.degree, line1.degree))
|
||||
} else {
|
||||
innerLines.push(drawRidgeLine(point1, canvas, roof, textMode))
|
||||
}
|
||||
} else if (line1.type === TYPES.GABLE_LINE) {
|
||||
if (line1.degree > 0) {
|
||||
innerLines.push(drawHipLine(point1, canvas, roof, textMode, null, line1.degree, line1.degree))
|
||||
} else {
|
||||
innerLines.push(drawRidgeLine(point1, canvas, roof, textMode))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (length2 > 0 && !alreadyPoints(innerLines, point2)) {
|
||||
if (line2.type === TYPES.HIP) {
|
||||
innerLines.push(drawHipLine(point2, canvas, roof, textMode, null, line2.degree, line2.degree))
|
||||
} else if (line2.type === TYPES.RIDGE) {
|
||||
innerLines.push(drawRidgeLine(point2, canvas, roof, textMode))
|
||||
} else if (line2.type === TYPES.NEW) {
|
||||
const isDiagonal = Math.abs(point2[0] - point2[2]) >= 1 && Math.abs(point2[1] - point2[3]) >= 1
|
||||
if (isDiagonal) {
|
||||
innerLines.push(drawHipLine(point2, canvas, roof, textMode, null, line2.degree, line2.degree))
|
||||
} else {
|
||||
innerLines.push(drawRidgeLine(point2, canvas, roof, textMode))
|
||||
}
|
||||
} else if (line2.type === TYPES.GABLE_LINE) {
|
||||
if (line2.degree > 0) {
|
||||
innerLines.push(drawHipLine(point2, canvas, roof, textMode, null, line2.degree, line2.degree))
|
||||
} else {
|
||||
innerLines.push(drawRidgeLine(point2, canvas, roof, textMode))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (line1.type === TYPES.GABLE_LINE || line2.type === TYPES.GABLE_LINE) {
|
||||
console.log('gableLine newAnalyze start')
|
||||
const gableLine = line1.type === TYPES.GABLE_LINE ? line1 : line2
|
||||
gableLine.connectCnt++
|
||||
|
||||
const checkLine = new fabric.Line([gableLine.start.x, gableLine.start.y, gableLine.end.x, gableLine.end.y], {
|
||||
stroke: 'red',
|
||||
strokeWidth: 4,
|
||||
parentId: roofId,
|
||||
name: 'check',
|
||||
})
|
||||
const checkCircle = new fabric.Circle({
|
||||
left: intersectPoint.x,
|
||||
top: intersectPoint.y,
|
||||
radius: 5,
|
||||
parentId: roofId,
|
||||
name: 'check',
|
||||
})
|
||||
canvas.add(checkLine, checkCircle)
|
||||
canvas.renderAll()
|
||||
|
||||
const relationBaseLines = [line1.left, line1.right, line2.left, line2.right]
|
||||
const uniqueBaseLines = [...new Set(relationBaseLines)]
|
||||
if (uniqueBaseLines.length === 3) {
|
||||
const linesCounts = new Map()
|
||||
relationBaseLines.forEach((e) => {
|
||||
linesCounts.set(e, (linesCounts.get(e) || 0) + 1)
|
||||
})
|
||||
const uniqueLines = Array.from(linesCounts.entries())
|
||||
.filter(([_, count]) => count === 1)
|
||||
.map(([line, _]) => line)
|
||||
|
||||
if (uniqueLines.length === 2) {
|
||||
if (gableLine.connectCnt < 2) {
|
||||
newAnalysis.push({
|
||||
start: { x: intersectPoint.x, y: intersectPoint.y },
|
||||
end: { x: gableLine.end.x, y: gableLine.end.y },
|
||||
left: gableLine.left,
|
||||
right: gableLine.right,
|
||||
type: TYPES.GABLE_LINE,
|
||||
degree: getDegreeByChon(baseLines[gableLine.right].attributes.pitch),
|
||||
gableId: gableLine.gableId,
|
||||
connectCnt: gableLine.connectCnt,
|
||||
})
|
||||
}
|
||||
if (gableLine.connectCnt >= 2) {
|
||||
//가선분 발생만 시키는 더미 생성.
|
||||
newAnalysis.push({
|
||||
start: { x: intersectPoint.x, y: intersectPoint.y },
|
||||
end: { x: intersectPoint.x, y: intersectPoint.y },
|
||||
left: gableLine.gableId,
|
||||
right: gableLine.gableId,
|
||||
type: TYPES.HIP,
|
||||
degree: 0,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log('gableLine newAnalyze end')
|
||||
} else {
|
||||
// 연결점에서 새로운 가선분을 생성
|
||||
const relationBaseLines = [line1.left, line1.right, line2.left, line2.right]
|
||||
const uniqueBaseLines = [...new Set(relationBaseLines)]
|
||||
if (uniqueBaseLines.length === 3) {
|
||||
const linesCounts = new Map()
|
||||
relationBaseLines.forEach((e) => {
|
||||
linesCounts.set(e, (linesCounts.get(e) || 0) + 1)
|
||||
})
|
||||
|
||||
const uniqueLines = Array.from(linesCounts.entries())
|
||||
.filter(([_, count]) => count === 1)
|
||||
.map(([line, _]) => line)
|
||||
|
||||
if (uniqueLines.length === 2) {
|
||||
// 두 변의 이등분선 방향 계산
|
||||
// uniqueLines.sort((a, b) => a - b)
|
||||
console.log('uniqueLines : ', uniqueLines)
|
||||
const baseLine1 = baseLines[uniqueLines[0]]
|
||||
const baseLine2 = baseLines[uniqueLines[1]]
|
||||
|
||||
const checkLine1 = new fabric.Line([baseLine1.x1, baseLine1.y1, baseLine1.x2, baseLine1.y2], {
|
||||
stroke: 'yellow',
|
||||
strokeWidth: 4,
|
||||
parentId: roofId,
|
||||
name: 'check',
|
||||
})
|
||||
const checkLine2 = new fabric.Line([baseLine2.x1, baseLine2.y1, baseLine2.x2, baseLine2.y2], {
|
||||
stroke: 'blue',
|
||||
strokeWidth: 4,
|
||||
parentId: roofId,
|
||||
name: 'check',
|
||||
})
|
||||
canvas.add(checkLine1, checkLine2)
|
||||
canvas.renderAll()
|
||||
let bisector
|
||||
console.log('isParallel(baseLine1, baseLine2)', isParallel(baseLine1, baseLine2))
|
||||
if (isParallel(baseLine1, baseLine2)) {
|
||||
bisector = getBisectLines(
|
||||
{ x1: line1.start.x, x2: line1.end.x, y1: line1.start.y, y2: line1.end.y },
|
||||
{ x1: line2.start.x, y1: line2.start.y, x2: line2.end.x, y2: line2.end.y },
|
||||
)
|
||||
} else {
|
||||
//이등분선
|
||||
bisector = getBisectBaseLines(baseLine1, baseLine2, intersectPoint, canvas)
|
||||
}
|
||||
|
||||
//마주하는 지붕선을 찾는다.
|
||||
const intersectionsByRoof = []
|
||||
const checkEdge = {
|
||||
vertex1: { x: intersectPoint.x, y: intersectPoint.y },
|
||||
vertex2: { x: intersectPoint.x + bisector.x, y: intersectPoint.y + bisector.y },
|
||||
}
|
||||
const checkVector = {
|
||||
x: Math.sign(checkEdge.vertex1.x - checkEdge.vertex2.x),
|
||||
y: Math.sign(checkEdge.vertex1.y - checkEdge.vertex2.y),
|
||||
}
|
||||
roof.lines.forEach((line) => {
|
||||
const lineEdge = { vertex1: { x: line.x1, y: line.y1 }, vertex2: { x: line.x2, y: line.y2 } }
|
||||
const is = edgesIntersection(lineEdge, checkEdge)
|
||||
if (is && isPointOnLineNew(line, is)) {
|
||||
const distance = Math.sqrt((is.x - intersectPoint.x) ** 2 + (is.y - intersectPoint.y) ** 2)
|
||||
const isVector = { x: Math.sign(intersectPoint.x - is.x), y: Math.sign(intersectPoint.y - is.y) }
|
||||
if (isVector.x === checkVector.x && isVector.y === checkVector.y) {
|
||||
intersectionsByRoof.push({ is, distance })
|
||||
}
|
||||
}
|
||||
})
|
||||
intersectionsByRoof.sort((a, b) => a.distance - b.distance)
|
||||
//지붕 선과의 교점이 존재 할때
|
||||
if (intersectionsByRoof.length > 0) {
|
||||
let is = intersectionsByRoof[0].is
|
||||
let linePoint = [intersectPoint.x, intersectPoint.y, is.x, is.y]
|
||||
const isDiagonal = Math.abs(is.x - intersectPoint.x) >= 1 && Math.abs(is.y - intersectPoint.y) >= 1
|
||||
const length = Math.sqrt((linePoint[2] - linePoint[0]) ** 2 + (linePoint[3] - linePoint[1]) ** 2)
|
||||
if (!isDiagonal) {
|
||||
const line1 = baseLines[uniqueLines[0]]
|
||||
const line2 = baseLines[uniqueLines[1]]
|
||||
const vector1 = { x: Math.sign(line1.x1 - line1.x2), y: Math.sign(line1.y1 - line1.y2) }
|
||||
|
||||
const prevLine = checkVector.x === vector1.x && checkVector.y === vector1.y ? line2 : line1
|
||||
const nextLine = checkVector.x === vector1.x && checkVector.y === vector1.y ? line1 : line2
|
||||
const drivePoint = getRidgeDrivePoint(linePoint, prevLine, nextLine, baseLines)
|
||||
if (drivePoint !== null) {
|
||||
const driveLength = Math.sqrt((drivePoint.x - intersectPoint.x) ** 2 + (drivePoint.y - intersectPoint.y) ** 2)
|
||||
|
||||
if (driveLength < length) {
|
||||
linePoint = [intersectPoint.x, intersectPoint.y, drivePoint.x, drivePoint.y]
|
||||
}
|
||||
}
|
||||
}
|
||||
const checkNewLine = new fabric.Line(linePoint, { stroke: 'cyan', strokeWidth: 4, parentId: roofId, name: 'check' })
|
||||
canvas.add(checkNewLine).renderAll()
|
||||
|
||||
newAnalysis.push({
|
||||
start: { x: linePoint[0], y: linePoint[1] },
|
||||
end: { x: linePoint[2], y: linePoint[3] },
|
||||
left: uniqueLines[0],
|
||||
right: uniqueLines[1],
|
||||
type: TYPES.NEW,
|
||||
degree: isDiagonal ? line1.degree : 0,
|
||||
})
|
||||
}
|
||||
}
|
||||
canvas
|
||||
.getObjects()
|
||||
.filter((object) => object.name === 'check')
|
||||
.forEach((object) => canvas.remove(object))
|
||||
canvas.renderAll()
|
||||
}
|
||||
}
|
||||
processed.add(pIndex)
|
||||
}
|
||||
}
|
||||
canvas
|
||||
.getObjects()
|
||||
.filter((object) => object.name === 'check')
|
||||
.forEach((object) => canvas.remove(object))
|
||||
canvas.renderAll()
|
||||
}
|
||||
if (isProceed) {
|
||||
processed.add(index)
|
||||
break
|
||||
}
|
||||
}
|
||||
// 처리된 가선분 제외
|
||||
linesAnalysis = newAnalysis.concat(linesAnalysis.filter((_, index) => !processed.has(index)))
|
||||
console.log('lineAnalysis: ', linesAnalysis)
|
||||
|
||||
canvas
|
||||
.getObjects()
|
||||
.filter((object) => object.name === 'check' || object.name === 'checkAnalysis')
|
||||
.forEach((object) => canvas.remove(object))
|
||||
canvas.renderAll()
|
||||
// 새로운 가선분이 없을때 종료
|
||||
console.log('newAnalysis.length : ', newAnalysis.length)
|
||||
if (newAnalysis.length === 0) break
|
||||
}
|
||||
console.log('lineAnalysis: end ', linesAnalysis)*/
|
||||
|
||||
// 가선분 중 처리가 안되어있는 붙어있는 라인에 대한 예외처리.
|
||||
/* const proceedAnalysis = []
|
||||
linesAnalysis
|
||||
.filter((line) => {
|
||||
const dx = line.end.x - line.start.x
|
||||
const dy = line.end.y - line.start.y
|
||||
const length = Math.sqrt(dx ** 2 + dy ** 2)
|
||||
return length > 0
|
||||
})
|
||||
.forEach((currentLine) => {
|
||||
if (proceedAnalysis.find((p) => p === currentLine)) return
|
||||
//현재와 같으면 제외, 이미 처리된 라인은 제외, 현재와 공통선분이 존재하지 않으면 제외
|
||||
linesAnalysis
|
||||
.filter((line) => {
|
||||
const dx = line.end.x - line.start.x
|
||||
const dy = line.end.y - line.start.y
|
||||
const length = Math.sqrt(dx ** 2 + dy ** 2)
|
||||
return length > 0
|
||||
})
|
||||
.filter(
|
||||
(partnerLine) =>
|
||||
partnerLine !== currentLine &&
|
||||
!proceedAnalysis.find((p) => p === partnerLine) &&
|
||||
(currentLine.left === partnerLine.left ||
|
||||
currentLine.left === partnerLine.right ||
|
||||
partnerLine.left === currentLine.left ||
|
||||
partnerLine.left === currentLine.right),
|
||||
)
|
||||
.forEach((partnerLine) => {
|
||||
const dx1 = currentLine.end.x - currentLine.start.x
|
||||
const dy1 = currentLine.end.y - currentLine.start.y
|
||||
const dx2 = partnerLine.end.x - partnerLine.start.x
|
||||
const dy2 = partnerLine.end.y - partnerLine.start.y
|
||||
const denominator = dy2 * dx1 - dx2 * dy1
|
||||
const isOpposite = dx1 * dx2 + dy1 * dy2 < 0
|
||||
//평행하지 않으면 제외
|
||||
if (Math.abs(denominator) > EPSILON) return
|
||||
|
||||
const currentDegree = getDegreeByChon(baseLines[currentLine.left].attributes.pitch)
|
||||
if (isOpposite) {
|
||||
const points = [currentLine.start.x, currentLine.start.y, partnerLine.start.x, partnerLine.start.y]
|
||||
const length = Math.sqrt((points[0] - points[2]) ** 2 + (points[1] - points[3]) ** 2)
|
||||
|
||||
if (length > 0) {
|
||||
if (currentLine.type === TYPES.HIP) {
|
||||
innerLines.push(drawHipLine(points, canvas, roof, textMode, null, currentDegree, currentDegree))
|
||||
} else if (currentLine.type === TYPES.RIDGE) {
|
||||
innerLines.push(drawRidgeLine(points, canvas, roof, textMode))
|
||||
} else if (currentLine.type === TYPES.NEW) {
|
||||
const isDiagonal = Math.abs(points[0] - points[2]) >= 1 && Math.abs(points[1] - points[3]) >= 1
|
||||
if (isDiagonal && almostEqual(Math.abs(points[0] - points[2]), Math.abs(points[1] - points[3]))) {
|
||||
innerLines.push(drawHipLine(points, canvas, roof, textMode, null, currentDegree, currentDegree))
|
||||
}
|
||||
if (!isDiagonal) {
|
||||
innerLines.push(drawRidgeLine(points, canvas, roof, textMode))
|
||||
}
|
||||
}
|
||||
proceedAnalysis.push(currentLine, partnerLine)
|
||||
}
|
||||
} else {
|
||||
const allPoints = [currentLine.start, currentLine.end, partnerLine.start, partnerLine.end]
|
||||
let points = []
|
||||
allPoints.forEach((point) => {
|
||||
let count = 0
|
||||
allPoints.forEach((p) => {
|
||||
if (almostEqual(point.x, p.x) && almostEqual(point.y, p.y)) count++
|
||||
})
|
||||
if (count === 1) points.push(point)
|
||||
})
|
||||
|
||||
if (points.length === 2) {
|
||||
const length = Math.sqrt((points[0].x - points[1].x) ** 2 + (points[0].y - points[1].y) ** 2)
|
||||
if (length < EPSILON) return
|
||||
const isDiagonal = Math.abs(points[0].x - points[1].x) >= 1 && Math.abs(points[0].y - points[1].y) >= 1
|
||||
if (isDiagonal) {
|
||||
innerLines.push(
|
||||
drawHipLine([points[0].x, points[0].y, points[1].x, points[1].y], canvas, roof, textMode, null, currentDegree, currentDegree),
|
||||
)
|
||||
} else {
|
||||
innerLines.push(drawRidgeLine([points[0].x, points[0].y, points[1].x, points[1].y], canvas, roof, textMode))
|
||||
}
|
||||
proceedAnalysis.push(currentLine, partnerLine)
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
linesAnalysis = linesAnalysis.filter((line) => !proceedAnalysis.find((p) => p === line))*/
|
||||
|
||||
//하단 지붕 라인처리
|
||||
/* const downRoofLines = []
|
||||
baseLines.forEach((baseLine, index) => {
|
||||
const nextLine = baseLines[(index + 1) % baseLines.length]
|
||||
const prevLine = baseLines[(index - 1 + baseLines.length) % baseLines.length]
|
||||
|
||||
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) }
|
||||
|
||||
//반절마루 생성불가이므로 지붕선 분기를 해야하는지 확인 후 처리.
|
||||
if (
|
||||
prevLineVector.x === nextLineVector.x &&
|
||||
prevLineVector.y === nextLineVector.y &&
|
||||
(prevLine.attributes.type === LINE_TYPE.WALLLINE.GABLE || nextLine.attributes.type === LINE_TYPE.WALLLINE.GABLE)
|
||||
) {
|
||||
downRoofLines.push(index)
|
||||
}
|
||||
})*/
|
||||
|
||||
/*if (downRoofLines.length > 0) {
|
||||
downRoofLines.forEach((index) => {
|
||||
const currentLine = baseLines[index]
|
||||
// const nextLine = baseLines[(index + 1) % baseLines.length]
|
||||
// const prevLine = baseLines[(index - 1 + baseLines.length) % baseLines.length]
|
||||
|
||||
const analyze = analyzeLine(currentLine)
|
||||
if (analyze.isDiagonal) {
|
||||
return
|
||||
}
|
||||
|
||||
const roofLine = analyze.roofLine
|
||||
let roofPoint = [analyze.startPoint.x, analyze.startPoint.y, analyze.endPoint.x, analyze.endPoint.y]
|
||||
|
||||
if (analyze.isVertical) {
|
||||
roofPoint[0] = roofLine.x1
|
||||
roofPoint[2] = roofLine.x2
|
||||
}
|
||||
if (analyze.isHorizontal) {
|
||||
roofPoint[1] = roofLine.y1
|
||||
roofPoint[3] = roofLine.y2
|
||||
}
|
||||
|
||||
console.log('analyze: ', analyze)
|
||||
const findRidgeVector = { x: 0, y: 0 }
|
||||
if (analyze.isVertical) {
|
||||
// noinspection JSSuspiciousNameCombination
|
||||
findRidgeVector.x = analyze.directionVector.y
|
||||
}
|
||||
if (analyze.isHorizontal) {
|
||||
// noinspection JSSuspiciousNameCombination
|
||||
findRidgeVector.y = analyze.directionVector.x
|
||||
}
|
||||
|
||||
console.log('findRidgeVector: ', findRidgeVector)
|
||||
innerLines
|
||||
.filter((line) => {
|
||||
if (line.name === LINE_TYPE.SUBLINE.RIDGE) {
|
||||
if (analyze.isVertical) {
|
||||
const signX = Math.sign(currentLine.x1 - line.x1)
|
||||
console.log('signX: ', signX)
|
||||
return signX === findRidgeVector.x
|
||||
}
|
||||
if (analyze.isHorizontal) {
|
||||
const signY = Math.sign(currentLine.y1 - line.y1)
|
||||
console.log('signY: ', signY)
|
||||
return signY === findRidgeVector.y
|
||||
}
|
||||
return false
|
||||
}
|
||||
return false
|
||||
})
|
||||
.forEach((line) => {
|
||||
if (line.name === LINE_TYPE.SUBLINE.RIDGE) {
|
||||
const checkLine = new fabric.Line([line.x1, line.y1, line.x2, line.y2], {
|
||||
stroke: 'red',
|
||||
strokeWidth: 4,
|
||||
parentId: roofId,
|
||||
name: 'check',
|
||||
})
|
||||
canvas.add(checkLine)
|
||||
canvas.renderAll()
|
||||
}
|
||||
})
|
||||
|
||||
/!*const oppositeLines = []
|
||||
baseLines
|
||||
.filter((line) => {
|
||||
//평행한 반대방향 라인인지 확인.
|
||||
const lineAnalyze = analyzeLine(line)
|
||||
return (
|
||||
(analyze.isHorizontal &&
|
||||
lineAnalyze.directionVector.x !== analyze.directionVector.x &&
|
||||
lineAnalyze.directionVector.y === analyze.directionVector.y) ||
|
||||
(analyze.isVertical &&
|
||||
lineAnalyze.directionVector.x === analyze.directionVector.x &&
|
||||
lineAnalyze.directionVector.y !== analyze.directionVector.y)
|
||||
)
|
||||
})
|
||||
.filter((line) => {
|
||||
//라인이 현재라인에 overlap 되거나, 현재 라인을 full overlap하는지 확인.
|
||||
if (analyze.isHorizontal) {
|
||||
const currentMinX = Math.min(currentLine.x1, currentLine.x2)
|
||||
const currentMaxX = Math.max(currentLine.x1, currentLine.x2)
|
||||
const minX = Math.min(line.x1, line.x2)
|
||||
const maxX = Math.max(line.x1, line.x2)
|
||||
//full overlap
|
||||
if (minX <= currentMinX && maxX >= currentMaxX) {
|
||||
return true
|
||||
}
|
||||
//라인 포인트중 하나라도 현재 라인의 범위에 들어와있으면 overlap으로 판단.
|
||||
if ((currentMinX <= minX && minX <= currentMaxX) || (currentMinX <= maxX && maxX <= currentMaxX)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if (analyze.isVertical) {
|
||||
const currentMinY = Math.min(currentLine.y1, currentLine.y2)
|
||||
const currentMaxY = Math.max(currentLine.y1, currentLine.y2)
|
||||
const minY = Math.min(line.y1, line.y2)
|
||||
const maxY = Math.max(line.y1, line.y2)
|
||||
//full overlap
|
||||
if (minY <= currentMinY && maxY >= currentMaxY) {
|
||||
return true
|
||||
}
|
||||
//라인 포인트중 하나라도 현재 라인의 범위에 들어와있으면 overlap으로 판단.
|
||||
if ((currentMinY <= minY && minY <= currentMaxY) || (currentMinY <= maxY && maxY <= currentMaxY)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
})
|
||||
.forEach((line, i) => {
|
||||
const checkLine = new fabric.Line([line.x1, line.y1, line.x2, line.y2], {
|
||||
stroke: 'green',
|
||||
strokeWidth: 4,
|
||||
parentId: roofId,
|
||||
name: 'check',
|
||||
})
|
||||
canvas.add(checkLine)
|
||||
canvas.renderAll()
|
||||
})*!/
|
||||
|
||||
// innerLines.push(drawRoofLine(roofPoint, canvas, roof, textMode))
|
||||
})
|
||||
}*/
|
||||
|
||||
/*if (linesAnalysis.length > 0) {
|
||||
linesAnalysis
|
||||
.filter((line) => {
|
||||
const dx = line.end.x - line.start.x
|
||||
const dy = line.end.y - line.start.y
|
||||
const length = Math.sqrt(dx ** 2 + dy ** 2)
|
||||
return length > 0
|
||||
})
|
||||
.forEach((line) => {
|
||||
const startOnLine = roof.lines.find((l) => isPointOnLineNew(l, line.start))
|
||||
const endOnLine = roof.lines.find((l) => isPointOnLineNew(l, line.end))
|
||||
console.log('startOnLine, endOnLine: ', startOnLine, endOnLine)
|
||||
const allLinesPoints = []
|
||||
innerLines.forEach((innerLine) => {
|
||||
allLinesPoints.push({ x: innerLine.x1, y: innerLine.y1 }, { x: innerLine.x2, y: innerLine.y2 })
|
||||
})
|
||||
|
||||
if (
|
||||
allLinesPoints.filter((p) => almostEqual(p.x, line.start.x) && almostEqual(p.y, line.start.y)).length < 3 &&
|
||||
allLinesPoints.filter((p) => almostEqual(p.x, line.end.x) && almostEqual(p.y, line.end.y)).length === 0
|
||||
) {
|
||||
if (startOnLine || endOnLine) {
|
||||
if (line.degree === 0) {
|
||||
innerLines.push(drawRoofLine([line.start.x, line.start.y, line.end.x, line.end.y], canvas, roof, textMode))
|
||||
} else {
|
||||
innerLines.push(
|
||||
drawHipLine([line.start.x, line.start.y, line.end.x, line.end.y], canvas, roof, textMode, null, line.degree, line.degree),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}*/
|
||||
|
||||
//지붕선에 따라 라인추가 작업 처리.
|
||||
/*const innerLinesPoints = []
|
||||
innerLines.forEach((line) => {
|
||||
const hasCoord1 = innerLinesPoints.find((p) => p.x === line.x1 && p.y === line.y1)
|
||||
const hasCoord2 = innerLinesPoints.find((p) => p.x === line.x2 && p.y === line.y2)
|
||||
if (!hasCoord1) innerLinesPoints.push({ x: line.x1, y: line.y1 })
|
||||
if (!hasCoord2) innerLinesPoints.push({ x: line.x2, y: line.y2 })
|
||||
})
|
||||
roof.lines.forEach((line) => {
|
||||
const splitPoint = []
|
||||
let hasOverlapLine = false
|
||||
const minX = Math.min(line.x1, line.x2)
|
||||
const maxX = Math.max(line.x1, line.x2)
|
||||
const minY = Math.min(line.y1, line.y2)
|
||||
const maxY = Math.max(line.y1, line.y2)
|
||||
innerLines.forEach((innerLine) => {
|
||||
const innerLineMinX = Math.min(innerLine.x1, innerLine.x2)
|
||||
const innerLineMaxX = Math.max(innerLine.x1, innerLine.x2)
|
||||
const innerLineMinY = Math.min(innerLine.y1, innerLine.y2)
|
||||
const innerLineMaxY = Math.max(innerLine.y1, innerLine.y2)
|
||||
if (innerLineMinX <= minX && innerLineMaxX >= maxX && innerLineMinY <= minY && innerLineMaxY >= maxY) {
|
||||
hasOverlapLine = true
|
||||
}
|
||||
if (minX <= innerLineMinX && maxX >= innerLineMaxX && minY <= innerLineMinY && maxY >= innerLineMaxY) {
|
||||
hasOverlapLine = true
|
||||
}
|
||||
})
|
||||
if (hasOverlapLine) return
|
||||
|
||||
innerLinesPoints.forEach((point) => {
|
||||
if (
|
||||
isPointOnLineNew(line, point) &&
|
||||
!(almostEqual(line.x1, point.x) && almostEqual(line.y1, point.y)) &&
|
||||
!(almostEqual(line.x2, point.x) && almostEqual(line.y2, point.y))
|
||||
) {
|
||||
const distance = Math.sqrt((point.x - line.x1) ** 2 + (point.y - line.y1) ** 2)
|
||||
splitPoint.push({ point, distance })
|
||||
}
|
||||
})
|
||||
if (splitPoint.length > 0) {
|
||||
splitPoint.sort((a, b) => a[1] - b[1])
|
||||
let startPoint = { x: line.x1, y: line.y1 }
|
||||
for (let i = 0; i < splitPoint.length; i++) {
|
||||
const point = splitPoint[i].point
|
||||
innerLines.push(drawRoofLine([startPoint.x, startPoint.y, point.x, point.y], canvas, roof, textMode))
|
||||
startPoint = point
|
||||
}
|
||||
innerLines.push(drawRoofLine([startPoint.x, startPoint.y, line.x2, line.y2], canvas, roof, textMode))
|
||||
} else {
|
||||
innerLines.push(drawRoofLine([line.x1, line.y1, line.x2, line.y2], canvas, roof, textMode))
|
||||
}
|
||||
})*/
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user