변별로 대응 중간 저장
This commit is contained in:
parent
d148077e6b
commit
a201d65ebe
@ -2389,7 +2389,7 @@ export const drawRoofByAttribute = (roofId, canvas, textMode) => {
|
|||||||
|
|
||||||
innerLines.push(drawHipLine(prevHipPoint, canvas, roof, textMode, null, prevDegree, prevDegree))
|
innerLines.push(drawHipLine(prevHipPoint, canvas, roof, textMode, null, prevDegree, prevDegree))
|
||||||
innerLines.push(drawHipLine(nextHipPoint, canvas, roof, textMode, null, nextDegree, nextDegree))
|
innerLines.push(drawHipLine(nextHipPoint, canvas, roof, textMode, null, nextDegree, nextDegree))
|
||||||
innerLines.push(drawRoofLine(gablePoint, canvas, roof, textMode))
|
// innerLines.push(drawRoofLine(gablePoint, canvas, roof, textMode))
|
||||||
|
|
||||||
//양옆이 처마일경우 두개의 선, 아닐때 한개의 선, 좌우가 처마가 아닐때 안그려져야하는데 기존에 그려지는 경우가 있음 이유를 알 수 없음.
|
//양옆이 처마일경우 두개의 선, 아닐때 한개의 선, 좌우가 처마가 아닐때 안그려져야하는데 기존에 그려지는 경우가 있음 이유를 알 수 없음.
|
||||||
if (prevLine.attributes.type === LINE_TYPE.WALLLINE.EAVES && nextLine.attributes.type === LINE_TYPE.WALLLINE.EAVES) {
|
if (prevLine.attributes.type === LINE_TYPE.WALLLINE.EAVES && nextLine.attributes.type === LINE_TYPE.WALLLINE.EAVES) {
|
||||||
@ -2499,8 +2499,8 @@ export const drawRoofByAttribute = (roofId, canvas, textMode) => {
|
|||||||
const currentDegree = getDegreeByChon(currentLine.attributes.pitch)
|
const currentDegree = getDegreeByChon(currentLine.attributes.pitch)
|
||||||
const checkVector = getHalfAngleVector(currentLine, prevLine)
|
const checkVector = getHalfAngleVector(currentLine, prevLine)
|
||||||
const checkPoint = {
|
const checkPoint = {
|
||||||
x: currentLine.x1 + (checkVector.x * analyze.length) / 2,
|
x: currentLine.x1 + (checkVector.x * 10) / 2,
|
||||||
y: currentLine.y1 + (checkVector.y * analyze.length) / 2,
|
y: currentLine.y1 + (checkVector.y * 10) / 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
let hipVector
|
let hipVector
|
||||||
@ -2558,74 +2558,6 @@ export const drawRoofByAttribute = (roofId, canvas, textMode) => {
|
|||||||
degree: currentDegree,
|
degree: currentDegree,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
/*//추녀마루 포인트중 겹치는 라인을 찾아 조정한다.
|
|
||||||
eavesHipLines.forEach((eavesHipLine) => {
|
|
||||||
const { hipPoint, line1, line2, degree } = eavesHipLine
|
|
||||||
const checkLine = new fabric.Line(hipPoint, {
|
|
||||||
stroke: 'blue',
|
|
||||||
strokeWidth: 2,
|
|
||||||
parentId: roofId,
|
|
||||||
name: 'check',
|
|
||||||
})
|
|
||||||
canvas.add(checkLine)
|
|
||||||
canvas.renderAll()
|
|
||||||
|
|
||||||
const hipEdge = { vertex1: { x: hipPoint[0], y: hipPoint[1] }, vertex2: { x: hipPoint[2], y: hipPoint[3] } }
|
|
||||||
const intersectPoints = []
|
|
||||||
eavesHipLines
|
|
||||||
.filter((line) => eavesHipLine !== line)
|
|
||||||
.forEach((hip) => {
|
|
||||||
const checkPoint = hip.hipPoint
|
|
||||||
const checkLine1 = hip.line1
|
|
||||||
const checkLine2 = hip.line2
|
|
||||||
const checkEdge = { vertex1: { x: checkPoint[0], y: checkPoint[1] }, vertex2: { x: checkPoint[2], y: checkPoint[3] } }
|
|
||||||
const intersect = edgesIntersection(checkEdge, hipEdge)
|
|
||||||
const checkLine = new fabric.Line(checkPoint, {
|
|
||||||
stroke: 'green',
|
|
||||||
strokeWidth: 2,
|
|
||||||
parentId: roofId,
|
|
||||||
name: 'check',
|
|
||||||
})
|
|
||||||
canvas.add(checkLine)
|
|
||||||
canvas.renderAll()
|
|
||||||
|
|
||||||
// 기준선내 겹치는 경우, line1, line2 중에서 비교선의 line1, line2가 겹칠때만 겹쳐질 수 있는 라인으로 판단한다. (샤프논문 참조)
|
|
||||||
if (
|
|
||||||
intersect &&
|
|
||||||
isPointOnLineNew({ x1: hipPoint[0], y1: hipPoint[1], x2: hipPoint[2], y2: hipPoint[3] }, intersect) &&
|
|
||||||
isPointOnLineNew({ x1: checkPoint[0], y1: checkPoint[1], x2: checkPoint[2], y2: checkPoint[3] }, intersect) &&
|
|
||||||
(line1 === checkLine1 || line1 === checkLine2 || line2 === checkLine1 || line2 === checkLine2)
|
|
||||||
) {
|
|
||||||
const dx = hipPoint[0] - intersect.x
|
|
||||||
const dy = hipPoint[1] - intersect.y
|
|
||||||
const length = Math.sqrt(dx * dx + dy * dy)
|
|
||||||
intersectPoints.push({ intersect, hip, length })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
intersectPoints.sort((a, b) => a.length - b.length)
|
|
||||||
if (intersectPoints.length === 0) {
|
|
||||||
innerLines.push(drawHipLine(hipPoint, canvas, roof, textMode, null, degree, degree))
|
|
||||||
} else {
|
|
||||||
const intersect = intersectPoints[0].intersect
|
|
||||||
const linePoint = [hipPoint[0], hipPoint[1], intersect.x, intersect.y]
|
|
||||||
innerLines.push(drawHipLine(linePoint, canvas, roof, textMode, null, degree, degree))
|
|
||||||
|
|
||||||
//다른라인에서 사용 되지 않게 조정
|
|
||||||
eavesHipLines.find((line) => line === eavesHipLine).hipPoint = linePoint
|
|
||||||
eavesHipLines.find((line) => line === intersectPoints[0].hip).hipPoint = [
|
|
||||||
intersectPoints[0].hip.hipPoint[0],
|
|
||||||
intersectPoints[0].hip.hipPoint[1],
|
|
||||||
intersect.x,
|
|
||||||
intersect.y,
|
|
||||||
]
|
|
||||||
}
|
|
||||||
canvas
|
|
||||||
.getObjects()
|
|
||||||
.filter((object) => object.name === 'check')
|
|
||||||
.forEach((object) => canvas.remove(object))
|
|
||||||
canvas.renderAll()
|
|
||||||
})*/
|
|
||||||
//4. 반절처(반절마루) 판단, 반절마루는 양옆이 처마여야 한다.
|
//4. 반절처(반절마루) 판단, 반절마루는 양옆이 처마여야 한다.
|
||||||
//5. 케라바 판단, 케라바는 양옆이 처마여야 한다.
|
//5. 케라바 판단, 케라바는 양옆이 처마여야 한다.
|
||||||
|
|
||||||
@ -2637,236 +2569,329 @@ export const drawRoofByAttribute = (roofId, canvas, textMode) => {
|
|||||||
while (linesAnalysis.length > 0 && iterations < MAX_ITERATIONS) {
|
while (linesAnalysis.length > 0 && iterations < MAX_ITERATIONS) {
|
||||||
iterations++
|
iterations++
|
||||||
|
|
||||||
|
linesAnalysis.forEach((line) => {
|
||||||
|
const checkLine = new fabric.Line([line.start.x, line.start.y, line.end.x, line.end.y], {
|
||||||
|
stroke: 'cyan',
|
||||||
|
strokeWidth: 3,
|
||||||
|
parentId: roofId,
|
||||||
|
name: 'checkAnalysis',
|
||||||
|
})
|
||||||
|
canvas.add(checkLine)
|
||||||
|
canvas.renderAll()
|
||||||
|
})
|
||||||
|
|
||||||
// 각 가선분의 최단 교점 찾기
|
// 각 가선분의 최단 교점 찾기
|
||||||
const intersections = []
|
const intersections = []
|
||||||
for (let i = 0; i < linesAnalysis.length; i++) {
|
for (let i = 0; i < linesAnalysis.length; i++) {
|
||||||
let minDistance = Infinity //최단거리
|
let minDistance = Infinity //최단거리
|
||||||
let intersectPoint = null //교점 좌표
|
let intersectPoint = null //교점 좌표
|
||||||
let intersectIndex = [] //교점 선분의 index
|
let partners = new Set() //교점 선분의 index
|
||||||
|
|
||||||
for (let j = 0; j < linesAnalysis.length; j++) {
|
for (let j = 0; j < linesAnalysis.length; j++) {
|
||||||
if (i === j) continue
|
if (i === j) continue
|
||||||
|
const intersection = lineIntersection(linesAnalysis[i].start, linesAnalysis[i].end, linesAnalysis[j].start, linesAnalysis[j].end, canvas)
|
||||||
const intersection = lineIntersection(linesAnalysis[i].start, linesAnalysis[i].end, linesAnalysis[j].start, linesAnalysis[j].end)
|
|
||||||
if (intersection) {
|
if (intersection) {
|
||||||
const distance = Math.sqrt((intersection.x - linesAnalysis[i].start.x) ** 2 + (intersection.y - linesAnalysis[i].start.y) ** 2)
|
const distance = Math.sqrt((intersection.x - linesAnalysis[i].start.x) ** 2 + (intersection.y - linesAnalysis[i].start.y) ** 2)
|
||||||
if (distance > EPSILON) {
|
if (distance < minDistance && !almostEqual(distance, minDistance)) {
|
||||||
if (distance < minDistance && !almostEqual(distance, minDistance)) {
|
minDistance = distance
|
||||||
// console.log('intersection :', intersection, intersectPoint)
|
intersectPoint = intersection
|
||||||
// console.log('distance :', distance, minDistance, almostEqual(distance, minDistance))
|
partners = new Set([j])
|
||||||
minDistance = distance
|
} else if (almostEqual(distance, minDistance)) {
|
||||||
intersectPoint = intersection
|
partners.add(j)
|
||||||
intersectIndex = [j]
|
|
||||||
} else if (almostEqual(distance, minDistance)) {
|
|
||||||
intersectIndex.push(j)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (intersectPoint) {
|
if (intersectPoint) {
|
||||||
intersections.push({ index: i, intersectPoint, intersectIndex, distance: minDistance })
|
intersections.push({ index: i, intersectPoint, partners, distance: minDistance })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 제일 가까운 교점부터 처리
|
||||||
|
intersections.sort((a, b) => a.distance - b.distance)
|
||||||
|
|
||||||
// 교점에 대한 적합 여부 판단 및 처리.
|
// 교점에 대한 적합 여부 판단 및 처리.
|
||||||
let newAnalysis = [] //신규 발생 선
|
let newAnalysis = [] //신규 발생 선
|
||||||
const processed = new Set() //처리된 선
|
const processed = new Set() //처리된 선
|
||||||
console.log('intersections : ', intersections)
|
for (const { index, intersectPoint, partners } of intersections) {
|
||||||
for (const { index, intersectPoint, intersectIndex } of intersections) {
|
|
||||||
const check1 = linesAnalysis[index]
|
|
||||||
const check2 = linesAnalysis[intersectIndex]
|
|
||||||
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 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 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: check2.start.x, top: check2.start.y, radius: 5, fill: 'red', parentId: roofId, name: 'check' })
|
|
||||||
const checkCircle3 = new fabric.Circle({ left: check1.end.x, top: check1.end.y, radius: 5, fill: 'green', 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(checkCircle1, checkCircle2, checkCircle3, checkCircle4)
|
|
||||||
canvas.add(checkLine1, checkLine2)
|
|
||||||
canvas.renderAll()
|
|
||||||
|
|
||||||
//교점이 없거나, 이미 처리된 선분이면 처리하지 않는다.
|
|
||||||
if (!intersectPoint || processed.has(index)) continue
|
|
||||||
|
|
||||||
const partner = intersections.find((p) => p.index === intersectIndex)
|
|
||||||
//교점이 없거나, 교점 선분이 없으면 처리하지 않는다.
|
|
||||||
if (!partner || !partner.intersectPoint) continue
|
|
||||||
|
|
||||||
//상호 최단 교점 여부 확인.
|
|
||||||
if (partner.intersectIndex === index) {
|
|
||||||
const line1 = linesAnalysis[index]
|
|
||||||
const line2 = linesAnalysis[intersectIndex]
|
|
||||||
|
|
||||||
//좌,우 선 중 공통 선 존재 확인.
|
|
||||||
const isSameLine = line1.left === line2.left || line1.left === line2.right || line1.right === line2.left || line1.right === line2.right
|
|
||||||
|
|
||||||
if (isSameLine) {
|
|
||||||
const point1 = [line1.start.x, line1.start.y, intersectPoint.x, intersectPoint.y]
|
|
||||||
const point2 = [line2.start.x, line2.start.y, intersectPoint.x, intersectPoint.y]
|
|
||||||
|
|
||||||
if (line1.type === 'hip') {
|
|
||||||
innerLines.push(drawHipLine(point1, canvas, roof, textMode, null, line1.degree, line1.degree))
|
|
||||||
} else if (line1.type === 'ridge') {
|
|
||||||
innerLines.push(drawRidgeLine(point1, canvas, roof, textMode))
|
|
||||||
} else if (line1.type === '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))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line2.type === 'hip') {
|
|
||||||
innerLines.push(drawHipLine(point2, canvas, roof, textMode, null, line2.degree, line2.degree))
|
|
||||||
} else if (line2.type === 'ridge') {
|
|
||||||
innerLines.push(drawRidgeLine(point2, canvas, roof, textMode))
|
|
||||||
} else if (line2.type === '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))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 연결점에서 새로운 가선분을 생성
|
|
||||||
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: 'green',
|
|
||||||
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) {
|
|
||||||
const is = intersectionsByRoof[0].is
|
|
||||||
const checkNewLine = new fabric.Line([intersectPoint.x, intersectPoint.y, is.x, is.y], {
|
|
||||||
stroke: 'cyan',
|
|
||||||
strokeWidth: 4,
|
|
||||||
parentId: roofId,
|
|
||||||
name: 'check',
|
|
||||||
})
|
|
||||||
canvas.add(checkNewLine)
|
|
||||||
canvas.renderAll()
|
|
||||||
newAnalysis.push({
|
|
||||||
start: { x: intersectPoint.x, y: intersectPoint.y },
|
|
||||||
end: { x: is.x, y: is.y },
|
|
||||||
left: uniqueLines[0],
|
|
||||||
right: uniqueLines[1],
|
|
||||||
type: 'new',
|
|
||||||
degree: line1.degree,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
canvas
|
|
||||||
.getObjects()
|
|
||||||
.filter((object) => object.name === 'check')
|
|
||||||
.forEach((object) => canvas.remove(object))
|
|
||||||
canvas.renderAll()
|
|
||||||
}
|
|
||||||
|
|
||||||
processed.add(index)
|
|
||||||
processed.add(intersectIndex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
canvas
|
canvas
|
||||||
.getObjects()
|
.getObjects()
|
||||||
.filter((object) => object.name === 'check')
|
.filter((object) => object.name === 'check')
|
||||||
.forEach((object) => canvas.remove(object))
|
.forEach((object) => canvas.remove(object))
|
||||||
canvas.renderAll()
|
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) {
|
||||||
|
// 현재 선이 처리 되었음을 표기
|
||||||
|
isProceed = true
|
||||||
|
const point1 = [line1.start.x, line1.start.y, intersectPoint.x, intersectPoint.y]
|
||||||
|
const point2 = [line2.start.x, line2.start.y, intersectPoint.x, intersectPoint.y]
|
||||||
|
const length1 = Math.sqrt((point1[2] - point1[0]) ** 2 + (point1[3] - point1[1]) ** 2)
|
||||||
|
const length2 = Math.sqrt((point2[2] - point2[0]) ** 2 + (point2[3] - point2[1]) ** 2)
|
||||||
|
|
||||||
|
if (length1 > 0 && !alreadyPoints(innerLines, point1)) {
|
||||||
|
if (line1.type === 'hip') {
|
||||||
|
innerLines.push(drawHipLine(point1, canvas, roof, textMode, null, line1.degree, line1.degree))
|
||||||
|
} else if (line1.type === 'ridge') {
|
||||||
|
innerLines.push(drawRidgeLine(point1, canvas, roof, textMode))
|
||||||
|
} else if (line1.type === '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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length2 > 0 && !alreadyPoints(innerLines, point2)) {
|
||||||
|
if (line2.type === 'hip') {
|
||||||
|
innerLines.push(drawHipLine(point2, canvas, roof, textMode, null, line2.degree, line2.degree))
|
||||||
|
} else if (line2.type === 'ridge') {
|
||||||
|
innerLines.push(drawRidgeLine(point2, canvas, roof, textMode))
|
||||||
|
} else if (line2.type === '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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 연결점에서 새로운 가선분을 생성
|
||||||
|
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) {
|
||||||
|
const is = intersectionsByRoof[0].is
|
||||||
|
const checkNewLine = new fabric.Line([intersectPoint.x, intersectPoint.y, is.x, is.y], {
|
||||||
|
stroke: 'cyan',
|
||||||
|
strokeWidth: 4,
|
||||||
|
parentId: roofId,
|
||||||
|
name: 'check',
|
||||||
|
})
|
||||||
|
canvas.add(checkNewLine)
|
||||||
|
canvas.renderAll()
|
||||||
|
newAnalysis.push({
|
||||||
|
start: { x: intersectPoint.x, y: intersectPoint.y },
|
||||||
|
end: { x: is.x, y: is.y },
|
||||||
|
left: uniqueLines[0],
|
||||||
|
right: uniqueLines[1],
|
||||||
|
type: 'new',
|
||||||
|
degree: line1.degree,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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 = linesAnalysis.filter((_, index) => !processed.has(index)).concat(newAnalysis)
|
linesAnalysis = newAnalysis.concat(linesAnalysis.filter((_, index) => !processed.has(index)))
|
||||||
console.log('lineAnalysis: ', linesAnalysis)
|
console.log('lineAnalysis: ', linesAnalysis)
|
||||||
/*
|
|
||||||
linesAnalysis.forEach((line) => {
|
|
||||||
const checkLine = new fabric.Line([line.start.x, line.start.y, line.end.x, line.end.y], {
|
|
||||||
stroke: 'red',
|
|
||||||
strokeWidth: 2,
|
|
||||||
parentId: roofId,
|
|
||||||
name: 'check',
|
|
||||||
})
|
|
||||||
canvas.add(checkLine)
|
|
||||||
canvas.renderAll()
|
|
||||||
})*/
|
|
||||||
|
|
||||||
canvas
|
canvas
|
||||||
.getObjects()
|
.getObjects()
|
||||||
.filter((object) => object.name === 'check')
|
.filter((object) => object.name === 'check' || object.name === 'checkAnalysis')
|
||||||
.forEach((object) => canvas.remove(object))
|
.forEach((object) => canvas.remove(object))
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
// 새로운 가선분이 없을때 종료
|
// 새로운 가선분이 없을때 종료
|
||||||
if (newAnalysis.length === 0) break
|
if (newAnalysis.length === 0) break
|
||||||
}
|
}
|
||||||
|
console.log('lineAnalysis: end ', linesAnalysis)
|
||||||
|
|
||||||
|
// 가선분 중 처리가 안되어있는 붙어있는 라인에 대한 예외처리.
|
||||||
|
const proceedAnalysis = []
|
||||||
|
linesAnalysis.forEach((currentLine) => {
|
||||||
|
if (proceedAnalysis.find((p) => p === currentLine)) return
|
||||||
|
//현재와 같으면 제외, 이미 처리된 라인은 제외, 현재와 공통선분이 존재하지 않으면 제외
|
||||||
|
linesAnalysis
|
||||||
|
.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 === 'hip') {
|
||||||
|
innerLines.push(drawHipLine(points, canvas, roof, textMode, null, currentDegree, currentDegree))
|
||||||
|
} else if (currentLine.type === 'ridge') {
|
||||||
|
innerLines.push(drawRidgeLine(points, canvas, roof, textMode))
|
||||||
|
} else if (currentLine.type === 'new') {
|
||||||
|
const isDiagonal = Math.abs(points[0] - points[2]) >= 1 && Math.abs(points[1] - points[3]) >= 1
|
||||||
|
if (isDiagonal) {
|
||||||
|
innerLines.push(drawHipLine(points, canvas, roof, textMode, null, currentDegree, currentDegree))
|
||||||
|
} else {
|
||||||
|
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)
|
||||||
|
})
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
//지붕 innerLines에 추가.
|
//지붕 innerLines에 추가.
|
||||||
roof.innerLines.push(...innerLines, ...ridgeLines)
|
roof.innerLines.push(...innerLines, ...ridgeLines)
|
||||||
@ -2886,16 +2911,31 @@ export const drawRoofByAttribute = (roofId, canvas, textMode) => {
|
|||||||
* @param line2End
|
* @param line2End
|
||||||
*/
|
*/
|
||||||
const lineIntersection = (line1Start, line1End, line2Start, line2End) => {
|
const lineIntersection = (line1Start, line1End, line2Start, line2End) => {
|
||||||
const denominator = (line2End.y - line2Start.y) * (line1End.x - line1Start.x) - (line2End.x - line2Start.x) * (line1End.y - line1Start.y)
|
const dx1 = line1End.x - line1Start.x
|
||||||
if (Math.abs(denominator) < EPSILON) return null // 평행
|
const dy1 = line1End.y - line1Start.y
|
||||||
|
const dx2 = line2End.x - line2Start.x
|
||||||
|
const dy2 = line2End.y - line2Start.y
|
||||||
|
// const denominator = (line2End.y - line2Start.y) * (line1End.x - line1Start.x) - (line2End.x - line2Start.x) * (line1End.y - line1Start.y)
|
||||||
|
const denominator = dy2 * dx1 - dx2 * dy1
|
||||||
|
if (Math.abs(denominator) < EPSILON) {
|
||||||
|
console.log('평행')
|
||||||
|
const isOpposite = dx1 * dx2 + dy1 * dy2 < 0
|
||||||
|
|
||||||
const ua = ((line2End.x - line2Start.x) * (line1Start.y - line2Start.y) - (line2End.y - line2Start.y) * (line1Start.x - line2Start.x)) / denominator
|
const isOverlap = isPointOnLineNew({ x1: line1Start.x, y1: line1Start.y, x2: line1End.x, y2: line1End.y }, { x: line2Start.x, y: line2Start.y })
|
||||||
const ub = ((line1End.x - line1Start.x) * (line1Start.y - line2Start.y) - (line1End.y - line1Start.y) * (line1Start.x - line2Start.x)) / denominator
|
|
||||||
|
if (isOpposite && isOverlap) {
|
||||||
|
return { x: line2Start.x, y: line2Start.y }
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
} // 평행
|
||||||
|
|
||||||
|
const ua = (dx2 * (line1Start.y - line2Start.y) - dy2 * (line1Start.x - line2Start.x)) / denominator
|
||||||
|
const ub = (dx1 * (line1Start.y - line2Start.y) - dy1 * (line1Start.x - line2Start.x)) / denominator
|
||||||
|
|
||||||
if (ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1) {
|
if (ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1) {
|
||||||
return {
|
return {
|
||||||
x: line1Start.x + ua * (line1End.x - line1Start.x),
|
x: line1Start.x + ua * dx1,
|
||||||
y: line1Start.y + ua * (line1End.y - line1Start.y),
|
y: line1Start.y + ua * dy1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
@ -2964,7 +3004,6 @@ const isParallel = (line1, line2) => {
|
|||||||
* 두 라인의 방향에 따라 이등분선의 vector를 구한다.
|
* 두 라인의 방향에 따라 이등분선의 vector를 구한다.
|
||||||
* @param line1
|
* @param line1
|
||||||
* @param line2
|
* @param line2
|
||||||
* @param polygon
|
|
||||||
*/
|
*/
|
||||||
const getBisectLines = (line1, line2) => {
|
const getBisectLines = (line1, line2) => {
|
||||||
const bisector = { x: 0, y: 0 }
|
const bisector = { x: 0, y: 0 }
|
||||||
@ -3009,27 +3048,7 @@ const getBisectLines = (line1, line2) => {
|
|||||||
* @param line2
|
* @param line2
|
||||||
* @param intersection
|
* @param intersection
|
||||||
*/
|
*/
|
||||||
const getBisectBaseLines = (line1, line2, intersection, canvas) => {
|
const getBisectBaseLines = (line1, line2, intersection) => {
|
||||||
const checkLine1 = new fabric.Line([line1.x1, line1.y1, line1.x2, line1.y2], {
|
|
||||||
stroke: 'red',
|
|
||||||
strokeWidth: 4,
|
|
||||||
name: 'check',
|
|
||||||
})
|
|
||||||
const checkLine2 = new fabric.Line([line2.x1, line2.y1, line2.x2, line2.y2], {
|
|
||||||
stroke: 'blue',
|
|
||||||
strokeWidth: 4,
|
|
||||||
name: 'check',
|
|
||||||
})
|
|
||||||
const checkCircle = new fabric.Circle({
|
|
||||||
left: intersection.x,
|
|
||||||
top: intersection.y,
|
|
||||||
radius: 5,
|
|
||||||
fill: 'cyan',
|
|
||||||
name: 'check',
|
|
||||||
})
|
|
||||||
canvas.add(checkLine1, checkLine2, checkCircle)
|
|
||||||
canvas.renderAll()
|
|
||||||
|
|
||||||
let bisector = { x: 0, y: 0 }
|
let bisector = { x: 0, y: 0 }
|
||||||
if (isParallel(line1, line2)) return bisector
|
if (isParallel(line1, line2)) return bisector
|
||||||
|
|
||||||
@ -3037,42 +3056,30 @@ const getBisectBaseLines = (line1, line2, intersection, canvas) => {
|
|||||||
const lineEdge2 = { vertex1: { x: line2.x1, y: line2.y1 }, vertex2: { x: line2.x2, y: line2.y2 } }
|
const lineEdge2 = { vertex1: { x: line2.x1, y: line2.y1 }, vertex2: { x: line2.x2, y: line2.y2 } }
|
||||||
const is = edgesIntersection(lineEdge1, lineEdge2)
|
const is = edgesIntersection(lineEdge1, lineEdge2)
|
||||||
if (is) {
|
if (is) {
|
||||||
const checkCircle = new fabric.Circle({
|
|
||||||
left: is.x,
|
|
||||||
top: is.y,
|
|
||||||
radius: 5,
|
|
||||||
fill: 'pink',
|
|
||||||
name: 'check',
|
|
||||||
})
|
|
||||||
canvas.add(checkCircle)
|
|
||||||
canvas.renderAll()
|
|
||||||
bisector = { x: Math.sign(intersection.x - is.x), y: Math.sign(intersection.y - is.y) }
|
bisector = { x: Math.sign(intersection.x - is.x), y: Math.sign(intersection.y - is.y) }
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas.remove(checkLine1, checkLine2, checkCircle)
|
|
||||||
canvas.renderAll()
|
|
||||||
|
|
||||||
return bisector
|
return bisector
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a 와 b 가 epsilon내 오차인지 확인한다.
|
||||||
|
* @param a
|
||||||
|
* @param b
|
||||||
|
* @param epsilon
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
const almostEqual = (a, b, epsilon = 1e-10) => {
|
const almostEqual = (a, b, epsilon = 1e-10) => {
|
||||||
if (a === Infinity || b === Infinity) return false
|
if (a === Infinity || b === Infinity) return false
|
||||||
const diff = Math.abs(a - b)
|
return Math.abs(a - b) <= epsilon
|
||||||
const larger = Math.max(Math.abs(a), Math.abs(b))
|
|
||||||
|
|
||||||
// 둘 다 0에 가까운 경우
|
|
||||||
if (larger < epsilon) {
|
|
||||||
return diff < epsilon
|
|
||||||
}
|
|
||||||
|
|
||||||
return diff <= larger * epsilon
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* segment가 fromPoint에서 떨어진 방향을 구한다.
|
||||||
|
* @param segment
|
||||||
|
* @param fromPoint
|
||||||
|
* @returns {{x, y}}
|
||||||
|
*/
|
||||||
const getDirection = (segment, fromPoint) => {
|
const getDirection = (segment, fromPoint) => {
|
||||||
// const dist1 = Math.sqrt(Math.pow(segment.x1 - fromPoint.x, 2) + Math.pow(segment.y1 - fromPoint.y, 2))
|
|
||||||
// const dist2 = Math.sqrt(Math.pow(segment.x2 - fromPoint.x, 2) + Math.pow(segment.y2 - fromPoint.y, 2))
|
|
||||||
|
|
||||||
// const target = dist1 > dist2 ? { x: segment.x1, y: segment.y1 } : { x: segment.x2, y: segment.y2 }
|
|
||||||
const target = { x: segment.x2, y: segment.y2 }
|
const target = { x: segment.x2, y: segment.y2 }
|
||||||
|
|
||||||
const dx = target.x - fromPoint.x
|
const dx = target.x - fromPoint.x
|
||||||
@ -3081,6 +3088,34 @@ const getDirection = (segment, fromPoint) => {
|
|||||||
|
|
||||||
return { x: dx / length, y: dy / length }
|
return { x: dx / length, y: dy / length }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lines중 points가 이미 존재하는지 확인한다.
|
||||||
|
* @param lines
|
||||||
|
* @param points
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
const alreadyPoints = (lines, points) => {
|
||||||
|
let has = false
|
||||||
|
|
||||||
|
lines.forEach((line) => {
|
||||||
|
const linePoints = [line.x1, line.y1, line.x2, line.y2]
|
||||||
|
if (
|
||||||
|
(almostEqual(linePoints[0], points[0], 1) &&
|
||||||
|
almostEqual(linePoints[1], points[1], 1) &&
|
||||||
|
almostEqual(linePoints[2], points[2], 1) &&
|
||||||
|
almostEqual(linePoints[3], points[3], 1)) ||
|
||||||
|
(almostEqual(linePoints[0], points[2], 1) &&
|
||||||
|
almostEqual(linePoints[1], points[3], 1) &&
|
||||||
|
almostEqual(linePoints[2], points[0], 1) &&
|
||||||
|
almostEqual(linePoints[3], points[1], 1))
|
||||||
|
) {
|
||||||
|
has = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return has
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 마루가 있는 지붕을 그린다.
|
* 마루가 있는 지붕을 그린다.
|
||||||
* @param roofId
|
* @param roofId
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user