다각형 시도 중
This commit is contained in:
parent
e29d581f10
commit
3feaf79306
@ -10,7 +10,6 @@ import { canvasSizeState, fontSizeState, sortedPolygonArray } from '@/store/canv
|
|||||||
import { QLine } from '@/components/fabric/QLine'
|
import { QLine } from '@/components/fabric/QLine'
|
||||||
import { getCanvasState, insertCanvasState } from '@/lib/canvas'
|
import { getCanvasState, insertCanvasState } from '@/lib/canvas'
|
||||||
import { calculateIntersection2 } from '@/util/canvas-util'
|
import { calculateIntersection2 } from '@/util/canvas-util'
|
||||||
import { CustomLine } from '@/components/fabric/QLine'
|
|
||||||
import { QPolygon } from '@/components/fabric/QPolygon'
|
import { QPolygon } from '@/components/fabric/QPolygon'
|
||||||
|
|
||||||
export default function Roof2() {
|
export default function Roof2() {
|
||||||
@ -45,6 +44,7 @@ export default function Roof2() {
|
|||||||
handleOuterlinesTest2,
|
handleOuterlinesTest2,
|
||||||
applyTemplateB,
|
applyTemplateB,
|
||||||
makeRoofPatternPolygon,
|
makeRoofPatternPolygon,
|
||||||
|
drawRoofPolygon,
|
||||||
} = useMode()
|
} = useMode()
|
||||||
|
|
||||||
// const [canvasState, setCanvasState] = useRecoilState(canvasAtom)
|
// const [canvasState, setCanvasState] = useRecoilState(canvasAtom)
|
||||||
@ -237,11 +237,32 @@ export default function Roof2() {
|
|||||||
{ x: 350, y: 100 },
|
{ x: 350, y: 100 },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const complicatedType = [
|
||||||
|
{ x: 100, y: 100 },
|
||||||
|
{ x: 100, y: 1100 },
|
||||||
|
{ x: 400, y: 1100 },
|
||||||
|
{ x: 400, y: 800 },
|
||||||
|
{ x: 700, y: 800 },
|
||||||
|
{ x: 700, y: 1100 },
|
||||||
|
{ x: 1000, y: 1100 },
|
||||||
|
{ x: 1000, y: 600 },
|
||||||
|
{ x: 700, y: 600 },
|
||||||
|
{ x: 700, y: 300 },
|
||||||
|
{ x: 1000, y: 300 },
|
||||||
|
{ x: 1000, y: 100 },
|
||||||
|
]
|
||||||
|
|
||||||
|
const diagonalType = [
|
||||||
|
{ x: 100, y: 100 },
|
||||||
|
{ x: 100, y: 600 },
|
||||||
|
{ x: 600, y: 600 },
|
||||||
|
{ x: 400, y: 100 }]
|
||||||
|
|
||||||
if (canvas) {
|
if (canvas) {
|
||||||
const polygon = new QPolygon(type1A, {
|
const polygon = new QPolygon(diagonalType, {
|
||||||
// const polygon = new QPolygon(eightPoint, {
|
// const polygon = new QPolygon(eightPoint, {
|
||||||
fill: 'transparent',
|
fill: 'transparent',
|
||||||
stroke: 'black',
|
stroke: 'green',
|
||||||
strokeWidth: 1,
|
strokeWidth: 1,
|
||||||
selectable: true,
|
selectable: true,
|
||||||
fontSize: fontSize,
|
fontSize: fontSize,
|
||||||
@ -249,8 +270,9 @@ export default function Roof2() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
canvas?.add(polygon)
|
canvas?.add(polygon)
|
||||||
|
drawRoofPolygon(polygon)
|
||||||
|
|
||||||
handleOuterlinesTest2(polygon)
|
// handleOuterlinesTest2(polygon)
|
||||||
|
|
||||||
// const lines = togglePolygonLine(polygon)
|
// const lines = togglePolygonLine(polygon)
|
||||||
// togglePolygonLine(lines[0])
|
// togglePolygonLine(lines[0])
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1,9 +1,22 @@
|
|||||||
import { useEffect, useRef, useState } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
import QRect from '@/components/fabric/QRect'
|
import QRect from '@/components/fabric/QRect'
|
||||||
import { findTopTwoIndexesByDistance, getCenterPoint, getDirection, getStartIndex, rearrangeArray } from '@/util/canvas-util'
|
import {
|
||||||
|
findTopTwoIndexesByDistance,
|
||||||
|
getCenterPoint,
|
||||||
|
getDirection,
|
||||||
|
getStartIndex,
|
||||||
|
rearrangeArray,
|
||||||
|
} from '@/util/canvas-util'
|
||||||
import { useRecoilState } from 'recoil'
|
import { useRecoilState } from 'recoil'
|
||||||
|
|
||||||
import { canvasSizeState, fontSizeState, roofPolygonPatternArrayState, roofState, sortedPolygonArray, wallState } from '@/store/canvasAtom'
|
import {
|
||||||
|
canvasSizeState,
|
||||||
|
fontSizeState,
|
||||||
|
roofPolygonPatternArrayState,
|
||||||
|
roofState,
|
||||||
|
sortedPolygonArray,
|
||||||
|
wallState,
|
||||||
|
} from '@/store/canvasAtom'
|
||||||
import { QLine } from '@/components/fabric/QLine'
|
import { QLine } from '@/components/fabric/QLine'
|
||||||
import { fabric } from 'fabric'
|
import { fabric } from 'fabric'
|
||||||
import { QPolygon } from '@/components/fabric/QPolygon'
|
import { QPolygon } from '@/components/fabric/QPolygon'
|
||||||
@ -1156,6 +1169,11 @@ export function useMode() {
|
|||||||
roof.drawHelpLine()
|
roof.drawHelpLine()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const drawRoofPolygon = (wall, offset = 71) => {
|
||||||
|
console.log(wall)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
const togglePolygonLine = (obj) => {
|
const togglePolygonLine = (obj) => {
|
||||||
const rtnLines = []
|
const rtnLines = []
|
||||||
if (obj.type === 'QPolygon') {
|
if (obj.type === 'QPolygon') {
|
||||||
@ -2252,7 +2270,13 @@ export function useMode() {
|
|||||||
canvas.add(centerLine2)
|
canvas.add(centerLine2)
|
||||||
canvas.remove(outLines[idx]) //기존 라인 삭제
|
canvas.remove(outLines[idx]) //기존 라인 삭제
|
||||||
|
|
||||||
halfHoriCenterLinePoint.push({ index: idx, x1: centerLine1.x1, y1: centerLine1.y1, x2: centerLine1.x2, y2: centerLine1.y2 }) //각 카라바 라인의 1번이 마지막점을 잡아서 센터선으로 설정
|
halfHoriCenterLinePoint.push({
|
||||||
|
index: idx,
|
||||||
|
x1: centerLine1.x1,
|
||||||
|
y1: centerLine1.y1,
|
||||||
|
x2: centerLine1.x2,
|
||||||
|
y2: centerLine1.y2,
|
||||||
|
}) //각 카라바 라인의 1번이 마지막점을 잡아서 센터선으로 설정
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -2453,7 +2477,13 @@ export function useMode() {
|
|||||||
canvas.add(centerLine2)
|
canvas.add(centerLine2)
|
||||||
canvas.remove(outline) //기존 라인 삭제
|
canvas.remove(outline) //기존 라인 삭제
|
||||||
|
|
||||||
halfHoriCenterLinePoint.push({ index: index, x1: centerLine1.x1, y1: centerLine1.y1, x2: centerLine1.x2, y2: centerLine1.y2 }) //각 카라바 라인의 1번이 마지막점을 잡아서 센터선으로 설정
|
halfHoriCenterLinePoint.push({
|
||||||
|
index: index,
|
||||||
|
x1: centerLine1.x1,
|
||||||
|
y1: centerLine1.y1,
|
||||||
|
x2: centerLine1.x2,
|
||||||
|
y2: centerLine1.y2,
|
||||||
|
}) //각 카라바 라인의 1번이 마지막점을 잡아서 센터선으로 설정
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -3211,5 +3241,6 @@ export function useMode() {
|
|||||||
handleOuterlinesTest,
|
handleOuterlinesTest,
|
||||||
handleOuterlinesTest2,
|
handleOuterlinesTest2,
|
||||||
makeRoofPatternPolygon,
|
makeRoofPatternPolygon,
|
||||||
|
drawRoofPolygon,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -285,7 +285,8 @@ export const drawHelpLineInHexagon = (polygon, chon) => {
|
|||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
export const drawHelpLineInHexagon2 = (polygon, chon) => {}
|
export const drawHelpLineInHexagon2 = (polygon, chon) => {
|
||||||
|
}
|
||||||
|
|
||||||
export const drawCenterLines = (polygon) => {
|
export const drawCenterLines = (polygon) => {
|
||||||
const centerLines = []
|
const centerLines = []
|
||||||
@ -384,3 +385,982 @@ const calculateAngle = (point1, point2) => {
|
|||||||
const angleInRadians = Math.atan2(deltaY, deltaX)
|
const angleInRadians = Math.atan2(deltaY, deltaX)
|
||||||
return angleInRadians * (180 / Math.PI)
|
return angleInRadians * (180 / Math.PI)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const drawHippedRoof = (polygon, chon) => {
|
||||||
|
drawRoofRidge(polygon, chon)
|
||||||
|
// drawHips(polygon, chon)
|
||||||
|
// connectLinePoint()
|
||||||
|
}
|
||||||
|
|
||||||
|
/*마루 그리기
|
||||||
|
외벽의 모양이 돌출된 ㄷ의 형태일때
|
||||||
|
현재 라인의 외벽길이가 붙어있는 두외벽의 길이보다 짧거나 같다면
|
||||||
|
지붕의 두 꼭지점에서 외벽의 두 꼭지점으로 45도 방향으로 선을 그려 만나는 지점이 마루의 시작점이 되고
|
||||||
|
시작점에서 부터 (가장 긴선 - ( 삼각형의 빗변 에서 직각까지의 수직길이 x 2))의 길이가 마루의 끝점이 된다.
|
||||||
|
다만 마루의 길이는 나머지 나머지 두 지붕의 길이중 짧은선의 길이를 넘어갈수 없다.
|
||||||
|
*/
|
||||||
|
const drawRoofRidge = (polygon) => {
|
||||||
|
let prevLine, currentLine, nextLine, prevWall, currentWall, nextWall
|
||||||
|
let startXPoint, startYPoint, endXPoint, endYPoint
|
||||||
|
let dVector, ridgeMaxLength, ridgeMinLength, ridgeRun
|
||||||
|
|
||||||
|
polygon.lines.forEach(
|
||||||
|
(value, index) => {
|
||||||
|
if (index === 0) {
|
||||||
|
prevLine = polygon.lines[polygon.lines.length - 1]
|
||||||
|
prevWall = polygon.wall.lines[polygon.wall.lines.length - 1]
|
||||||
|
} else {
|
||||||
|
prevLine = polygon.lines[index - 1]
|
||||||
|
prevWall = polygon.wall.lines[index - 1]
|
||||||
|
}
|
||||||
|
currentLine = polygon.lines[index]
|
||||||
|
currentWall = polygon.wall.lines[index]
|
||||||
|
|
||||||
|
if (index === polygon.lines.length - 1) {
|
||||||
|
nextLine = polygon.lines[0]
|
||||||
|
nextWall = polygon.wall.lines[0]
|
||||||
|
} else if (index === polygon.lines.length) {
|
||||||
|
nextLine = polygon.lines[1]
|
||||||
|
nextWall = polygon.wall.lines[1]
|
||||||
|
} else {
|
||||||
|
nextLine = polygon.lines[index + 1]
|
||||||
|
nextWall = polygon.wall.lines[index + 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(polygon.lines)
|
||||||
|
// let ridgeBaseLine = polygon.lines.filter((line) => line.idx === currentLine.idx)[0]
|
||||||
|
|
||||||
|
// if (this.getLineDirection(prevLine) !== this.getLineDirection(nextLine) && currentWall.length < currentLine.length) {
|
||||||
|
if (getLineDirection(prevWall) !== getLineDirection(nextWall) && currentWall.length < currentLine.length) {
|
||||||
|
dVector = getDirectionForDegree(prevWall, currentWall)
|
||||||
|
let {
|
||||||
|
minLineLength,
|
||||||
|
currentLineLength,
|
||||||
|
maxLineLength,
|
||||||
|
} = getRoofBaseLine(polygon, prevWall, currentWall, nextWall, dVector)
|
||||||
|
|
||||||
|
console.log('currentLine.length : ' + currentWall.length)
|
||||||
|
// 마루는 세개의 벽중에서 가장 길 수 없다.
|
||||||
|
console.log('currentLineLength : ', currentLineLength, 'minLineLength : ', minLineLength, 'maxLineLength : ', maxLineLength)
|
||||||
|
console.log('minLineLength <= currentLineLength <= maxLineLength', (minLineLength <= currentLineLength && currentLineLength <= maxLineLength))
|
||||||
|
|
||||||
|
if (currentLineLength <= maxLineLength) {
|
||||||
|
// console.log('currentLine.length : ' + currentLine.length)
|
||||||
|
ridgeMaxLength = Math.min(minLineLength, maxLineLength)
|
||||||
|
ridgeMinLength = Math.max(minLineLength, maxLineLength) - currentLineLength
|
||||||
|
ridgeRun = Math.min(ridgeMinLength, ridgeMaxLength)
|
||||||
|
// console.log(ridgeRun)
|
||||||
|
switch (dVector) {
|
||||||
|
case 45:
|
||||||
|
startXPoint = currentWall.x1 + (currentLineLength / 2)
|
||||||
|
startYPoint = currentWall.y1 - (currentLineLength / 2)
|
||||||
|
endXPoint = startXPoint
|
||||||
|
endYPoint = startYPoint - ridgeRun
|
||||||
|
break
|
||||||
|
case 135:
|
||||||
|
startXPoint = currentWall.x1 + (currentLineLength / 2)
|
||||||
|
startYPoint = currentWall.y1 + (currentLineLength / 2)
|
||||||
|
endXPoint = startXPoint + ridgeRun
|
||||||
|
endYPoint = startYPoint
|
||||||
|
break
|
||||||
|
case 225:
|
||||||
|
startXPoint = currentWall.x1 - (currentLineLength / 2)
|
||||||
|
startYPoint = currentWall.y1 + (currentLineLength / 2)
|
||||||
|
endXPoint = startXPoint
|
||||||
|
endYPoint = startYPoint + ridgeRun
|
||||||
|
break
|
||||||
|
case 315:
|
||||||
|
startXPoint = currentWall.x1 - (currentLineLength / 2)
|
||||||
|
startYPoint = currentWall.y1 - (currentLineLength / 2)
|
||||||
|
endXPoint = startXPoint - ridgeRun
|
||||||
|
endYPoint = startYPoint
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
let isDuplicate = false
|
||||||
|
polygon.ridges.forEach((ridge) => {
|
||||||
|
if (ridge.x1 === Math.min(startXPoint, endXPoint) && ridge.y1 === Math.min(startYPoint, endYPoint) && ridge.x2 === Math.max(startXPoint, endXPoint) && ridge.y2 === Math.max(startYPoint, endYPoint)) {
|
||||||
|
isDuplicate = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!isDuplicate && polygon.ridges.length < getMaxRidge(polygon.lines.length)) {
|
||||||
|
const ridge = new QLine([Math.min(startXPoint, endXPoint), Math.min(startYPoint, endYPoint), Math.max(startXPoint, endXPoint), Math.max(startYPoint, endYPoint)], {
|
||||||
|
fontSize: polygon.fontSize,
|
||||||
|
stroke: 'blue',
|
||||||
|
strokeWidth: 1,
|
||||||
|
})
|
||||||
|
polygon.canvas.add(ridge)
|
||||||
|
polygon.ridges.push(ridge)
|
||||||
|
polygon.innerLines.push(ridge)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const drawHips = (polygon) => {
|
||||||
|
/*
|
||||||
|
마루에서 시작되는 hip을 먼저 그립니다.
|
||||||
|
*/
|
||||||
|
this.ridges.forEach((ridge) => {
|
||||||
|
let leftTop, rightTop, leftBottom, rightBottom
|
||||||
|
if (ridge.x1 !== ridge.x2 && ridge.y1 === ridge.y2) {
|
||||||
|
// console.log('가로방향 마루')
|
||||||
|
//왼쪽 좌표 기준 225, 315도 방향 라인확인
|
||||||
|
leftTop = this.lines.filter((line) => line.x1 < ridge.x1 && line.y1 < ridge.y1
|
||||||
|
&& Math.abs(line.x1 - ridge.x1) === Math.abs(line.y1 - ridge.y1))
|
||||||
|
.reduce((prev, current) => {
|
||||||
|
if (prev <= 0) {
|
||||||
|
return current
|
||||||
|
} else {
|
||||||
|
return Math.min(ridge.x1 - current.x1) < Math.min(ridge.x1 - prev.x1) ? current : prev
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
leftBottom = this.lines.filter((line) => line.x1 < ridge.x1 && line.y1 > ridge.y1
|
||||||
|
&& Math.abs(line.x1 - ridge.x1) === Math.abs(line.y1 - ridge.y1))
|
||||||
|
.reduce((prev, current) => {
|
||||||
|
if (prev <= 0) {
|
||||||
|
return current
|
||||||
|
} else {
|
||||||
|
return Math.min(ridge.x1 - current.x1) < Math.min(ridge.x1 - prev.x1) ? current : prev
|
||||||
|
}
|
||||||
|
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
//오른쪽 좌표 기준 45, 135도 방향 라인확인
|
||||||
|
rightTop = this.lines.filter((line) => line.x1 > ridge.x2 && line.y1 < ridge.y2
|
||||||
|
&& Math.abs(line.x1 - ridge.x2) === Math.abs(line.y1 - ridge.y2))
|
||||||
|
.reduce((prev, current) => {
|
||||||
|
if (prev <= 0) {
|
||||||
|
return current
|
||||||
|
} else {
|
||||||
|
return Math.min(current.x1 - ridge.x2) < Math.min(prev.x1 - ridge.x2) ? current : prev
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
rightBottom = this.lines.filter((line) => line.x1 > ridge.x2 && line.y1 > ridge.y2
|
||||||
|
&& Math.abs(line.x1 - ridge.x2) === Math.abs(line.y1 - ridge.y2))
|
||||||
|
.reduce((prev, current) => {
|
||||||
|
if (prev <= 0) {
|
||||||
|
return current
|
||||||
|
} else {
|
||||||
|
return Math.min(current.x1 - ridge.x2) < Math.min(prev.x1 - ridge.x2) ? current : prev
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
if (leftTop.length > 0) {
|
||||||
|
const hip = new QLine([leftTop.x1, leftTop.y1, ridge.x1, ridge.y1], {
|
||||||
|
fontSize: this.fontSize,
|
||||||
|
stroke: 'red',
|
||||||
|
strokeWidth: 1,
|
||||||
|
})
|
||||||
|
this.addWithUpdate(hip)
|
||||||
|
this.hips.push(hip)
|
||||||
|
this.innerLines.push(hip)
|
||||||
|
}
|
||||||
|
if (leftBottom.length > 0) {
|
||||||
|
const hip = new QLine([leftBottom.x1, leftBottom.y1, ridge.x1, ridge.y1], {
|
||||||
|
fontSize: this.fontSize,
|
||||||
|
stroke: 'red',
|
||||||
|
strokeWidth: 1,
|
||||||
|
})
|
||||||
|
this.addWithUpdate(hip)
|
||||||
|
this.hips.push(hip)
|
||||||
|
this.innerLines.push(hip)
|
||||||
|
}
|
||||||
|
if (rightTop.length > 0) {
|
||||||
|
const hip = new QLine([rightTop.x1, rightTop.y1, ridge.x2, ridge.y2], {
|
||||||
|
fontSize: this.fontSize,
|
||||||
|
stroke: 'red',
|
||||||
|
strokeWidth: 1,
|
||||||
|
})
|
||||||
|
this.addWithUpdate(hip)
|
||||||
|
this.hips.push(hip)
|
||||||
|
this.innerLines.push(hip)
|
||||||
|
}
|
||||||
|
if (rightBottom.length > 0) {
|
||||||
|
const hip = new QLine([rightBottom.x1, rightBottom.y1, ridge.x2, ridge.y2], {
|
||||||
|
fontSize: this.fontSize,
|
||||||
|
stroke: 'red',
|
||||||
|
strokeWidth: 1,
|
||||||
|
})
|
||||||
|
this.addWithUpdate(hip)
|
||||||
|
this.hips.push(hip)
|
||||||
|
this.innerLines.push(hip)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ridge.y1 !== ridge.y2 && ridge.x1 === ridge.x2) {
|
||||||
|
// console.log('세로방향 마루')
|
||||||
|
//위쪽 좌표 기준 45, 315도 방향 라인확인
|
||||||
|
leftTop = this.lines.filter((line) => line.x1 < ridge.x1 && line.y1 < ridge.y1
|
||||||
|
&& Math.abs(line.x1 - ridge.x1) === Math.abs(line.y1 - ridge.y1))
|
||||||
|
.reduce((prev, current) => {
|
||||||
|
if (prev <= 0) {
|
||||||
|
return current
|
||||||
|
} else {
|
||||||
|
return Math.min(ridge.y1 - current.y1) < Math.min(ridge.y1 - prev.y1) ? current : prev
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
rightTop = this.lines.filter((line) => line.x1 > ridge.x1 && line.y1 < ridge.y1
|
||||||
|
&& Math.abs(line.x1 - ridge.x1) === Math.abs(line.y1 - ridge.y1))
|
||||||
|
.reduce((prev, current) => {
|
||||||
|
if (prev <= 0) {
|
||||||
|
return current
|
||||||
|
} else {
|
||||||
|
return Math.min(ridge.y1 - current.y1) < Math.min(ridge.y1 - prev.y1) ? current : prev
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
//아래쪽 좌표 기준 135, 225도 방향 라인확인
|
||||||
|
leftBottom = this.lines.filter((line) => line.x1 < ridge.x2 && line.y1 > ridge.y2
|
||||||
|
&& Math.abs(line.x1 - ridge.x2) === Math.abs(line.y1 - ridge.y2))
|
||||||
|
.reduce((prev, current) => {
|
||||||
|
if (prev <= 0) {
|
||||||
|
return current
|
||||||
|
} else {
|
||||||
|
return Math.min(current.y1 - ridge.y2) < Math.min(prev.y1 - ridge.y2) ? current : prev
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
rightBottom = this.lines.filter((line) => line.x1 > ridge.x2 && line.y1 > ridge.y2
|
||||||
|
&& Math.abs(line.x1 - ridge.x2) === Math.abs(line.y1 - ridge.y2))
|
||||||
|
.reduce((prev, current) => {
|
||||||
|
if (prev.length <= 0) {
|
||||||
|
return current
|
||||||
|
} else {
|
||||||
|
return Math.min(current.y1 - ridge.y2) < Math.min(prev.y1 - ridge.y2) ? current : prev
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
if (leftTop.length > 0) {
|
||||||
|
const hip = new QLine([leftTop.x1, leftTop.y1, ridge.x1, ridge.y1], {
|
||||||
|
fontSize: this.fontSize,
|
||||||
|
stroke: 'red',
|
||||||
|
strokeWidth: 1,
|
||||||
|
})
|
||||||
|
this.addWithUpdate(hip)
|
||||||
|
this.hips.push(hip)
|
||||||
|
this.innerLines.push(hip)
|
||||||
|
}
|
||||||
|
if (rightTop.length > 0) {
|
||||||
|
const hip = new QLine([rightTop.x1, rightTop.y1, ridge.x1, ridge.y1], {
|
||||||
|
fontSize: this.fontSize,
|
||||||
|
stroke: 'red',
|
||||||
|
strokeWidth: 1,
|
||||||
|
})
|
||||||
|
this.addWithUpdate(hip)
|
||||||
|
this.hips.push(hip)
|
||||||
|
this.innerLines.push(hip)
|
||||||
|
}
|
||||||
|
if (leftBottom.length > 0) {
|
||||||
|
const hip = new QLine([leftBottom.x1, leftBottom.y1, ridge.x2, ridge.y2], {
|
||||||
|
fontSize: this.fontSize,
|
||||||
|
stroke: 'red',
|
||||||
|
strokeWidth: 1,
|
||||||
|
})
|
||||||
|
this.addWithUpdate(hip)
|
||||||
|
this.hips.push(hip)
|
||||||
|
this.innerLines.push(hip)
|
||||||
|
}
|
||||||
|
if (rightBottom.length > 0) {
|
||||||
|
const hip = new QLine([rightBottom.x1, rightBottom.y1, ridge.x2, ridge.y2], {
|
||||||
|
fontSize: this.fontSize,
|
||||||
|
stroke: 'red',
|
||||||
|
strokeWidth: 1,
|
||||||
|
})
|
||||||
|
this.addWithUpdate(hip)
|
||||||
|
this.hips.push(hip)
|
||||||
|
this.innerLines.push(hip)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 가장 가까운 마루를 확인하여 그릴 수 있는 라인이 존재하면 먼저 그린다.
|
||||||
|
let prevLine, currentLine, nextLine
|
||||||
|
this.lines.forEach(
|
||||||
|
(value, index) => {
|
||||||
|
if (index === 0) {
|
||||||
|
prevLine = this.lines[this.lines.length - 1]
|
||||||
|
} else {
|
||||||
|
prevLine = this.lines[index - 1]
|
||||||
|
}
|
||||||
|
currentLine = this.lines[index]
|
||||||
|
|
||||||
|
if (index === this.lines.length - 1) {
|
||||||
|
nextLine = this.lines[0]
|
||||||
|
} else if (index === this.lines.length) {
|
||||||
|
nextLine = this.lines[1]
|
||||||
|
} else {
|
||||||
|
nextLine = this.lines[index + 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.isAlreadyHip(currentLine)) {
|
||||||
|
let dVector = this.getDirectionForDegree(prevLine, currentLine)
|
||||||
|
let nearRidge
|
||||||
|
|
||||||
|
switch (dVector) {
|
||||||
|
case 45:
|
||||||
|
nearRidge = this.ridges.filter(ridge => (currentLine.x1 < ridge.x1 && currentLine.y1 > ridge.y1)
|
||||||
|
|| (currentLine.x1 < ridge.x2 && currentLine.y1 > ridge.y2)
|
||||||
|
&& (Math.abs(currentLine.x1 - ridge.x1) === Math.abs(currentLine.y1 - ridge.y1)
|
||||||
|
|| Math.abs(currentLine.x1 - ridge.x2) === Math.abs(currentLine.y1 - ridge.y2)))
|
||||||
|
.reduce((prev, current) => {
|
||||||
|
if (prev !== undefined) {
|
||||||
|
if (Math.abs(currentLine.x1 - current.x1) === Math.abs(currentLine.y1 - current.y1)) {
|
||||||
|
return Math.min(Math.abs(current.x1 - currentLine.x1)) < Math.min(Math.abs(prev.x1 - currentLine.x1)) ? current : prev
|
||||||
|
} else if (Math.abs(currentLine.x1 - current.x2) === Math.abs(currentLine.y1 - current.y2)) {
|
||||||
|
return Math.min(Math.abs(current.x1 - currentLine.x1)) < Math.min(Math.abs(prev.x1 - currentLine.x1)) ? current : prev
|
||||||
|
} else {
|
||||||
|
return prev
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (Math.abs(currentLine.x1 - current.x1) === Math.abs(currentLine.y1 - current.y1)) {
|
||||||
|
return current
|
||||||
|
} else if (Math.abs(currentLine.x1 - current.x2) === Math.abs(currentLine.y1 - current.y2)) {
|
||||||
|
return current
|
||||||
|
} else {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, undefined)
|
||||||
|
break
|
||||||
|
case 135:
|
||||||
|
nearRidge = this.ridges.filter(ridge => (currentLine.x1 < ridge.x1 && currentLine.y1 < ridge.y1
|
||||||
|
|| currentLine.x1 < ridge.x2 && currentLine.y1 < ridge.y2)
|
||||||
|
&& (Math.abs(currentLine.x1 - ridge.x1) === Math.abs(currentLine.y1 - ridge.y1)
|
||||||
|
|| Math.abs(currentLine.x1 - ridge.x2) === Math.abs(currentLine.y1 - ridge.y2)))
|
||||||
|
.reduce((prev, current) => {
|
||||||
|
if (prev !== undefined) {
|
||||||
|
if (Math.abs(currentLine.x1 - current.x1) === Math.abs(currentLine.y1 - current.y1)) {
|
||||||
|
return Math.min(Math.abs(current.x1 - currentLine.x1)) < Math.min(Math.abs(prev.x1 - currentLine.x1)) ? current : prev
|
||||||
|
} else if (Math.abs(currentLine.x1 - current.x2) === Math.abs(currentLine.y1 - current.y2)) {
|
||||||
|
return Math.min(Math.abs(current.x1 - currentLine.x1)) < Math.min(Math.abs(prev.x1 - currentLine.x1)) ? current : prev
|
||||||
|
} else {
|
||||||
|
return prev
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (Math.abs(currentLine.x1 - current.x1) === Math.abs(currentLine.y1 - current.y1)) {
|
||||||
|
return current
|
||||||
|
} else if (Math.abs(currentLine.x1 - current.x2) === Math.abs(currentLine.y1 - current.y2)) {
|
||||||
|
return current
|
||||||
|
} else {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, undefined)
|
||||||
|
break
|
||||||
|
case 225:
|
||||||
|
nearRidge = this.ridges.filter(ridge => (currentLine.x1 > ridge.x1 && currentLine.y1 < ridge.y1
|
||||||
|
|| currentLine.x1 > ridge.x2 && currentLine.y1 < ridge.y2)
|
||||||
|
&& (Math.abs(currentLine.x1 - ridge.x1) === Math.abs(currentLine.y1 - ridge.y1)
|
||||||
|
|| Math.abs(currentLine.x1 - ridge.x2) === Math.abs(currentLine.y1 - ridge.y2)))
|
||||||
|
.reduce((prev, current) => {
|
||||||
|
if (prev !== undefined) {
|
||||||
|
if (Math.abs(currentLine.x1 - current.x1) === Math.abs(currentLine.y1 - current.y1)) {
|
||||||
|
return Math.min(Math.abs(current.x1 - currentLine.x1)) < Math.min(Math.abs(prev.x1 - currentLine.x1)) ? current : prev
|
||||||
|
} else if (Math.abs(currentLine.x1 - current.x2) === Math.abs(currentLine.y1 - current.y2)) {
|
||||||
|
return Math.min(Math.abs(current.x1 - currentLine.x1)) < Math.min(Math.abs(prev.x1 - currentLine.x1)) ? current : prev
|
||||||
|
} else {
|
||||||
|
return prev
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (Math.abs(currentLine.x1 - current.x1) === Math.abs(currentLine.y1 - current.y1)) {
|
||||||
|
return current
|
||||||
|
} else if (Math.abs(currentLine.x1 - current.x2) === Math.abs(currentLine.y1 - current.y2)) {
|
||||||
|
return current
|
||||||
|
} else {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, undefined)
|
||||||
|
break
|
||||||
|
case 315:
|
||||||
|
nearRidge = this.ridges.filter(ridge => (currentLine.x1 > ridge.x1 && currentLine.y1 > ridge.y1
|
||||||
|
|| currentLine.x1 > ridge.x2 && currentLine.y1 > ridge.y2)
|
||||||
|
&& (Math.abs(currentLine.x1 - ridge.x1) === Math.abs(currentLine.y1 - ridge.y1)
|
||||||
|
|| Math.abs(currentLine.x1 - ridge.x2) === Math.abs(currentLine.y1 - ridge.y2)))
|
||||||
|
.reduce((prev, current) => {
|
||||||
|
if (prev !== undefined) {
|
||||||
|
if (Math.abs(currentLine.x1 - current.x1) === Math.abs(currentLine.y1 - current.y1)) {
|
||||||
|
return Math.min(Math.abs(current.x1 - currentLine.x1)) < Math.min(Math.abs(prev.x1 - currentLine.x1)) ? current : prev
|
||||||
|
} else if (Math.abs(currentLine.x1 - current.x2) === Math.abs(currentLine.y1 - current.y2)) {
|
||||||
|
return Math.min(Math.abs(current.x1 - currentLine.x1)) < Math.min(Math.abs(prev.x1 - currentLine.x1)) ? current : prev
|
||||||
|
} else {
|
||||||
|
return prev
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (Math.abs(currentLine.x1 - current.x1) === Math.abs(currentLine.y1 - current.y1)) {
|
||||||
|
return current
|
||||||
|
} else if (Math.abs(currentLine.x1 - current.x2) === Math.abs(currentLine.y1 - current.y2)) {
|
||||||
|
return current
|
||||||
|
} else {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, undefined)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log('nearRidge : ', nearRidge)
|
||||||
|
|
||||||
|
if (nearRidge !== undefined && nearRidge.length > 0) {
|
||||||
|
let endXPoint, endYPoint
|
||||||
|
let minX, maxX, minY, maxY
|
||||||
|
|
||||||
|
switch (dVector) {
|
||||||
|
case 45:
|
||||||
|
if (currentLine.x1 < nearRidge.x1 && currentLine.y1 > nearRidge.y1
|
||||||
|
&& Math.abs(currentLine.x1 - nearRidge.x1) === Math.abs(currentLine.y1 - nearRidge.y1)) {
|
||||||
|
endXPoint = nearRidge.x1
|
||||||
|
endYPoint = nearRidge.y1
|
||||||
|
minX = Math.min(currentLine.x1, nearRidge.x1)
|
||||||
|
minY = Math.min(currentLine.y1, nearRidge.y1)
|
||||||
|
maxX = Math.max(currentLine.x1, nearRidge.x1)
|
||||||
|
maxY = Math.max(currentLine.y1, nearRidge.y1)
|
||||||
|
}
|
||||||
|
if (currentLine.x1 < nearRidge.x2 && currentLine.y1 > nearRidge.y2
|
||||||
|
&& Math.abs(currentLine.x1 - nearRidge.x2) === Math.abs(currentLine.y1 - nearRidge.y2)) {
|
||||||
|
endXPoint = nearRidge.x2
|
||||||
|
endYPoint = nearRidge.y2
|
||||||
|
minX = Math.min(currentLine.x1, nearRidge.x2)
|
||||||
|
minY = Math.min(currentLine.y1, nearRidge.y2)
|
||||||
|
maxX = Math.max(currentLine.x1, nearRidge.x2)
|
||||||
|
maxY = Math.max(currentLine.y1, nearRidge.y2)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 135:
|
||||||
|
if (currentLine.x1 < nearRidge.x1 && currentLine.y1 < nearRidge.y1
|
||||||
|
&& Math.abs(currentLine.x1 - nearRidge.x1) === Math.abs(currentLine.y1 - nearRidge.y1)) {
|
||||||
|
endXPoint = nearRidge.x1
|
||||||
|
endYPoint = nearRidge.y1
|
||||||
|
minX = Math.min(currentLine.x1, nearRidge.x1)
|
||||||
|
minY = Math.min(currentLine.y1, nearRidge.y1)
|
||||||
|
maxX = Math.max(currentLine.x1, nearRidge.x1)
|
||||||
|
maxY = Math.max(currentLine.y1, nearRidge.y1)
|
||||||
|
}
|
||||||
|
if (currentLine.x1 < nearRidge.x2 && currentLine.y1 < nearRidge.y2
|
||||||
|
&& Math.abs(currentLine.x1 - nearRidge.x2) === Math.abs(currentLine.y1 - nearRidge.y2)) {
|
||||||
|
endXPoint = nearRidge.x2
|
||||||
|
endYPoint = nearRidge.y2
|
||||||
|
minX = Math.min(currentLine.x1, nearRidge.x2)
|
||||||
|
minY = Math.min(currentLine.y1, nearRidge.y2)
|
||||||
|
maxX = Math.max(currentLine.x1, nearRidge.x2)
|
||||||
|
maxY = Math.max(currentLine.y1, nearRidge.y2)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 225:
|
||||||
|
if (currentLine.x1 > nearRidge.x1 && currentLine.y1 < nearRidge.y1
|
||||||
|
&& Math.abs(currentLine.x1 - nearRidge.x1) === Math.abs(currentLine.y1 - nearRidge.y1)) {
|
||||||
|
endXPoint = nearRidge.x1
|
||||||
|
endYPoint = nearRidge.y1
|
||||||
|
minX = Math.min(currentLine.x1, nearRidge.x1)
|
||||||
|
minY = Math.min(currentLine.y1, nearRidge.y1)
|
||||||
|
maxX = Math.max(currentLine.x1, nearRidge.x1)
|
||||||
|
maxY = Math.max(currentLine.y1, nearRidge.y1)
|
||||||
|
}
|
||||||
|
if (currentLine.x1 > nearRidge.x2 && currentLine.y1 < nearRidge.y2
|
||||||
|
&& Math.abs(currentLine.x1 - nearRidge.x2) === Math.abs(currentLine.y1 - nearRidge.y2)) {
|
||||||
|
endXPoint = nearRidge.x2
|
||||||
|
endYPoint = nearRidge.y2
|
||||||
|
minX = Math.min(currentLine.x1, nearRidge.x2)
|
||||||
|
minY = Math.min(currentLine.y1, nearRidge.y2)
|
||||||
|
maxX = Math.max(currentLine.x1, nearRidge.x2)
|
||||||
|
maxY = Math.max(currentLine.y1, nearRidge.y2)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 315:
|
||||||
|
if (currentLine.x1 > nearRidge.x1 && currentLine.y1 > nearRidge.y1
|
||||||
|
&& Math.abs(currentLine.x1 - nearRidge.x1) === Math.abs(currentLine.y1 - nearRidge.y1)) {
|
||||||
|
endXPoint = nearRidge.x1
|
||||||
|
endYPoint = nearRidge.y1
|
||||||
|
minX = Math.min(currentLine.x1, nearRidge.x1)
|
||||||
|
minY = Math.min(currentLine.y1, nearRidge.y1)
|
||||||
|
maxX = Math.max(currentLine.x1, nearRidge.x1)
|
||||||
|
maxY = Math.max(currentLine.y1, nearRidge.y1)
|
||||||
|
}
|
||||||
|
if (currentLine.x1 > nearRidge.x2 && currentLine.y1 > nearRidge.y2
|
||||||
|
&& Math.abs(currentLine.x1 - nearRidge.x2) === Math.abs(currentLine.y1 - nearRidge.y2)) {
|
||||||
|
endXPoint = nearRidge.x2
|
||||||
|
endYPoint = nearRidge.y2
|
||||||
|
minX = Math.min(currentLine.x1, nearRidge.x2)
|
||||||
|
minY = Math.min(currentLine.y1, nearRidge.y2)
|
||||||
|
maxX = Math.max(currentLine.x1, nearRidge.x2)
|
||||||
|
maxY = Math.max(currentLine.y1, nearRidge.y2)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
let lineCoordinate = [
|
||||||
|
{ x: minX, y: minY },
|
||||||
|
{ x: minX, y: maxY },
|
||||||
|
{ x: maxX, y: maxY },
|
||||||
|
{ x: maxX, y: minY },
|
||||||
|
]
|
||||||
|
|
||||||
|
let innerPoint = this.lines.filter(line => {
|
||||||
|
if (this.getPointInPolygon(lineCoordinate, { x: line.x1, y: line.y1 })) {
|
||||||
|
return line
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (innerPoint <= 0) {
|
||||||
|
const hip = new QLine([currentLine.x1, currentLine.y1, endXPoint, endYPoint], {
|
||||||
|
fontSize: this.fontSize,
|
||||||
|
stroke: 'red',
|
||||||
|
strokeWidth: 1,
|
||||||
|
})
|
||||||
|
this.addWithUpdate(hip)
|
||||||
|
this.hips.push(hip)
|
||||||
|
this.innerLines.push(hip)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 마루와 연결되지 않은 hip을 그린다.
|
||||||
|
console.log('마루와 연결되지 않은 hip')
|
||||||
|
this.lines.forEach((line, index) => {
|
||||||
|
if (!this.isAlreadyHip(line)) {
|
||||||
|
let prevLine, currentLine, nextLine
|
||||||
|
if (index === 0) {
|
||||||
|
prevLine = this.lines[this.lines.length - 1]
|
||||||
|
} else {
|
||||||
|
prevLine = this.lines[index - 1]
|
||||||
|
}
|
||||||
|
currentLine = this.lines[index]
|
||||||
|
|
||||||
|
if (index === this.lines.length - 1) {
|
||||||
|
nextLine = this.lines[0]
|
||||||
|
} else if (index === this.lines.length) {
|
||||||
|
nextLine = this.lines[1]
|
||||||
|
} else {
|
||||||
|
nextLine = this.lines[index + 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
let endXPoint, endYPoint
|
||||||
|
let dVector = this.getDirectionForDegree(prevLine, currentLine)
|
||||||
|
|
||||||
|
let minX = Math.min(currentLine.x1, currentLine.x2, prevLine.x1, nextLine.x2)
|
||||||
|
let maxX = Math.max(currentLine.x1, currentLine.x2, prevLine.x1, nextLine.x2)
|
||||||
|
let minY = Math.min(currentLine.y1, currentLine.y2, prevLine.y1, nextLine.y2)
|
||||||
|
let maxY = Math.max(currentLine.y1, currentLine.y2, prevLine.y1, nextLine.y2)
|
||||||
|
|
||||||
|
let lineCoordinate = [
|
||||||
|
{ x: minX, y: minY },
|
||||||
|
{ x: minX, y: maxY },
|
||||||
|
{ x: maxX, y: maxY },
|
||||||
|
{ x: maxX, y: minY },
|
||||||
|
]
|
||||||
|
|
||||||
|
let acrossLine = getAcrossLine(currentLine, dVector)
|
||||||
|
let hypotenuse, adjacent
|
||||||
|
|
||||||
|
if (this.getLineDirection(prevLine) === this.getLineDirection(nextLine)) {
|
||||||
|
hypotenuse = Math.round(getRoofHypotenuse(Math.abs(currentLine.x1 - acrossLine.x1) / 2))
|
||||||
|
} else {
|
||||||
|
hypotenuse = Math.min(Math.round(getRoofHypotenuse(currentLine.length / 2))
|
||||||
|
, Math.round(getRoofHypotenuse(Math.abs(currentLine.x1 - acrossLine.x1) / 2)))
|
||||||
|
}
|
||||||
|
|
||||||
|
adjacent = getAdjacent(hypotenuse)
|
||||||
|
|
||||||
|
switch (dVector) {
|
||||||
|
case 45:
|
||||||
|
endXPoint = currentLine.x1 + adjacent
|
||||||
|
endYPoint = currentLine.y1 - adjacent
|
||||||
|
break
|
||||||
|
case 135:
|
||||||
|
endXPoint = currentLine.x1 + adjacent
|
||||||
|
endYPoint = currentLine.y1 + adjacent
|
||||||
|
break
|
||||||
|
case 225:
|
||||||
|
endXPoint = currentLine.x1 - adjacent
|
||||||
|
endYPoint = currentLine.y1 + adjacent
|
||||||
|
break
|
||||||
|
case 315:
|
||||||
|
endXPoint = currentLine.x1 - adjacent
|
||||||
|
endYPoint = currentLine.y1 - adjacent
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
const hip = new QLine([currentLine.x1, currentLine.y1, endXPoint, endYPoint], {
|
||||||
|
fontSize: this.fontSize,
|
||||||
|
stroke: 'red',
|
||||||
|
strokeWidth: 1,
|
||||||
|
})
|
||||||
|
this.addWithUpdate(hip)
|
||||||
|
this.hips.push(hip)
|
||||||
|
this.innerLines.push(hip)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// this.canvas.renderAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
const getRoofBaseLine = (polygon, prevLine, currentLine, nextLine, dVector) => {
|
||||||
|
let minX = Math.min(currentLine.x1, currentLine.x2, prevLine.x1, nextLine.x2)
|
||||||
|
let maxX = Math.max(currentLine.x1, currentLine.x2, prevLine.x1, nextLine.x2)
|
||||||
|
let minY = Math.min(currentLine.y1, currentLine.y2, prevLine.y1, nextLine.y2)
|
||||||
|
let maxY = Math.max(currentLine.y1, currentLine.y2, prevLine.y1, nextLine.y2)
|
||||||
|
|
||||||
|
let lineCoordinate = [
|
||||||
|
{ x: minX, y: minY },
|
||||||
|
{ x: minX, y: maxY },
|
||||||
|
{ x: maxX, y: maxY },
|
||||||
|
{ x: maxX, y: minY },
|
||||||
|
]
|
||||||
|
|
||||||
|
let innerPointLine = polygon.lines.filter(line => {
|
||||||
|
if (getPointInPolygon(lineCoordinate, { x: line.x1, y: line.y1 })) {
|
||||||
|
return line
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
let coordinateLength
|
||||||
|
let innerPointX
|
||||||
|
|
||||||
|
if (innerPointLine.length > 0) {
|
||||||
|
innerPointX = innerPointLine.reduce((a, b) => {
|
||||||
|
return a.x1 < b.x1 ? a : b
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dVector === 45 || dVector === 225) {
|
||||||
|
if (innerPointX !== undefined) {
|
||||||
|
coordinateLength = Math.abs(currentLine.y1 - innerPointX.y1)
|
||||||
|
} else {
|
||||||
|
coordinateLength = Math.abs(lineCoordinate[0].y - lineCoordinate[2].y)
|
||||||
|
}
|
||||||
|
//계산된 좌표길이가 마루를 작성 할 최소 기준에 미치지 못하면 그릴수 없다.
|
||||||
|
if (coordinateLength < currentLine.length) {
|
||||||
|
return {
|
||||||
|
minLineLength: coordinateLength,
|
||||||
|
currentLineLength: currentLine.length,
|
||||||
|
maxLineLength: coordinateLength,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
minLineLength: Math.min(prevLine.length, nextLine.length),
|
||||||
|
currentLineLength: currentLine.length,
|
||||||
|
maxLineLength: coordinateLength,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dVector === 135 || dVector === 315) {
|
||||||
|
if (innerPointX !== undefined) {
|
||||||
|
coordinateLength = Math.abs(currentLine.x1 - innerPointX.x1)
|
||||||
|
} else {
|
||||||
|
coordinateLength = Math.abs(lineCoordinate[0].x - lineCoordinate[2].x)
|
||||||
|
}
|
||||||
|
//계산된 좌표길이가 마루를 작성 할 최소 기준에 미치지 못하면 그릴수 없다.
|
||||||
|
if (coordinateLength < currentLine.length) {
|
||||||
|
return {
|
||||||
|
minLineLength: coordinateLength,
|
||||||
|
currentLineLength: currentLine.length,
|
||||||
|
maxLineLength: coordinateLength,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
minLineLength: Math.min(prevLine.length, nextLine.length),
|
||||||
|
currentLineLength: currentLine.length,
|
||||||
|
maxLineLength: coordinateLength,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getPointInPolygon = (polygon, point) => {
|
||||||
|
let inside = false
|
||||||
|
let minX = Math.min(polygon[0].x, polygon[1].x, polygon[2].x, polygon[3].x),
|
||||||
|
maxX = Math.max(polygon[0].x, polygon[1].x, polygon[2].x, polygon[3].x),
|
||||||
|
minY = Math.min(polygon[0].y, polygon[1].y, polygon[2].y, polygon[3].y),
|
||||||
|
maxY = Math.max(polygon[0].y, polygon[1].y, polygon[2].y, polygon[3].y)
|
||||||
|
|
||||||
|
if (minX < point.x && point.x < maxX && minY < point.y && point.y < maxY) {
|
||||||
|
inside = true
|
||||||
|
}
|
||||||
|
return inside
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 라인과 마주하는 다른 라인과의 가장 가까운 거리를 구한다.
|
||||||
|
* @param currentLine 현재 라인
|
||||||
|
* @param dVector 현재 라인의 방향
|
||||||
|
* @returns {*[]|null}
|
||||||
|
*/
|
||||||
|
const getAcrossLine = (currentLine, dVector) => {
|
||||||
|
let acrossLine
|
||||||
|
|
||||||
|
switch (dVector) {
|
||||||
|
case 45:
|
||||||
|
acrossLine = this.lines.filter(line => line.x1 > currentLine.x1 && line.y1 <= currentLine.y1)
|
||||||
|
.reduce((prev, current) => {
|
||||||
|
if (prev.length > 0) {
|
||||||
|
return Math.abs(currentLine.x1 - current.x1) < Math.abs(currentLine.x1 - prev.x1) ? current : prev
|
||||||
|
} else {
|
||||||
|
return current
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
break
|
||||||
|
case 135:
|
||||||
|
acrossLine = this.lines.filter(line => line.x1 > currentLine.x1 && line.y1 >= currentLine.y1)
|
||||||
|
.reduce((prev, current) => {
|
||||||
|
if (prev.length > 0) {
|
||||||
|
return Math.abs(currentLine.x1 - current.x1) < Math.abs(currentLine.x1 - prev.x1) ? current : prev
|
||||||
|
} else {
|
||||||
|
return current
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
break
|
||||||
|
case 225:
|
||||||
|
acrossLine = this.lines.filter(line => line.x1 < currentLine.x1 && line.y1 >= currentLine.y1)
|
||||||
|
.reduce((prev, current) => {
|
||||||
|
if (prev.length > 0) {
|
||||||
|
return Math.abs(currentLine.x1 - current.x1) < Math.abs(currentLine.x1 - prev.x1) ? current : prev
|
||||||
|
} else {
|
||||||
|
return current
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
break
|
||||||
|
case 315:
|
||||||
|
acrossLine = this.lines.filter(line => line.x1 < currentLine.x1 && line.y1 <= currentLine.y1)
|
||||||
|
.reduce((prev, current) => {
|
||||||
|
if (prev.length > 0) {
|
||||||
|
return Math.abs(currentLine.x1 - current.x1) < Math.abs(currentLine.x1 - prev.x1) ? current : prev
|
||||||
|
} else {
|
||||||
|
return current
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return acrossLine
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
추녀마루(hip) 중복방지를 위해 마루와 함께 그려진 추녀마루를 확인한다
|
||||||
|
*/
|
||||||
|
const isAlreadyHip = (line) => {
|
||||||
|
let isAlreadyHip = false
|
||||||
|
this.hips.forEach(hip => {
|
||||||
|
if (line.x1 === hip.x1 && line.y1 === hip.y1) {
|
||||||
|
isAlreadyHip = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return isAlreadyHip
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
3개 이상 이어지지 않은 라인 포인트 계산
|
||||||
|
모임지붕에서 point는 3개 이상의 라인과 접해야 함.
|
||||||
|
*/
|
||||||
|
const connectLinePoint = () => {
|
||||||
|
// 연결되지 않은 모든 라인의 포인트를 구한다.
|
||||||
|
let missedPoints = []
|
||||||
|
//마루
|
||||||
|
this.ridges.forEach(ridge => {
|
||||||
|
if (this.hips.filter(hip => hip.x2 === ridge.x1 && hip.y2 === ridge.y1).length < 2) {
|
||||||
|
missedPoints.push({ x: ridge.x1, y: ridge.y1 })
|
||||||
|
}
|
||||||
|
if (this.hips.filter(hip => hip.x2 === ridge.x2 && hip.y2 === ridge.y2).length < 2) {
|
||||||
|
missedPoints.push({ x: ridge.x2, y: ridge.y2 })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
//추녀마루
|
||||||
|
this.hips.forEach(hip => {
|
||||||
|
let count = 0
|
||||||
|
count += this.ridges.filter(ridge =>
|
||||||
|
(ridge.x1 === hip.x2 && ridge.y1 === hip.y2) || (ridge.x2 === hip.x2 && ridge.y2 === hip.y2),
|
||||||
|
).length
|
||||||
|
count += this.hips.filter(hip2 =>
|
||||||
|
(hip2.x1 === hip.x2 && hip2.y1 === hip.y2) || (hip2.x2 === hip.x2 && hip2.y2 === hip.y2),
|
||||||
|
).length
|
||||||
|
|
||||||
|
if (count < 3) {
|
||||||
|
missedPoints.push({ x: hip.x2, y: hip.y2 })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
let missedLine = []
|
||||||
|
|
||||||
|
//중복포인트제거
|
||||||
|
missedPoints = [
|
||||||
|
...new Set(missedPoints.map((line) => JSON.stringify(line))),
|
||||||
|
].map((line) => JSON.parse(line))
|
||||||
|
|
||||||
|
missedPoints.forEach(p1 => {
|
||||||
|
let p2 = missedPoints.filter(p => p.x !== p1.x && p.y !== p1.y).reduce((prev, current) => {
|
||||||
|
if (prev !== undefined) {
|
||||||
|
return Math.sqrt(Math.pow(Math.abs(current.x - p1.x), 2) + Math.pow(Math.abs(current.y - p1.y), 2))
|
||||||
|
< Math.sqrt(Math.pow(Math.abs(prev.x - p1.x), 2) + Math.pow(Math.abs(prev.y - p1.y), 2)) ? current : prev
|
||||||
|
} else {
|
||||||
|
return current
|
||||||
|
}
|
||||||
|
}, undefined)
|
||||||
|
if (p2 !== undefined) {
|
||||||
|
if (p1.x < p2.x && p1.y < p2.y) {
|
||||||
|
missedLine.push({ x1: p1.x, y1: p1.y, x2: p2.x, y2: p2.y })
|
||||||
|
}
|
||||||
|
if (p1.x > p2.x && p1.y < p2.y) {
|
||||||
|
missedLine.push({ x1: p2.x, y1: p2.y, x2: p1.x, y2: p1.y })
|
||||||
|
}
|
||||||
|
if (p1.x > p2.x && p1.y > p2.y) {
|
||||||
|
missedLine.push({ x1: p2.x, y1: p2.y, x2: p1.x, y2: p1.y })
|
||||||
|
}
|
||||||
|
if (p1.x < p2.x && p1.y > p2.y) {
|
||||||
|
missedLine.push({ x1: p1.x, y1: p1.y, x2: p2.x, y2: p2.y })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
//중복라인제거
|
||||||
|
missedLine = [
|
||||||
|
...new Set(missedLine.map((line) => JSON.stringify(line))),
|
||||||
|
].map((line) => JSON.parse(line))
|
||||||
|
|
||||||
|
missedLine.forEach((p, index) => {
|
||||||
|
const line = new QLine([p.x1, p.y1, p.x2, p.y2], {
|
||||||
|
fontSize: this.fontSize,
|
||||||
|
stroke: 'green',
|
||||||
|
strokeWidth: 1,
|
||||||
|
})
|
||||||
|
this.addWithUpdate(line)
|
||||||
|
this.innerLines.push(line)
|
||||||
|
})
|
||||||
|
|
||||||
|
missedPoints = []
|
||||||
|
missedLine = []
|
||||||
|
|
||||||
|
this.innerLines.forEach((line, index) => {
|
||||||
|
if (this.innerLines.filter(innerLine => (line.x2 === innerLine.x1 && line.y2 === innerLine.y1)
|
||||||
|
|| (line.x2 === innerLine.x2 && line.y2 === innerLine.y2)).length < 3) {
|
||||||
|
missedPoints.push({ x: line.x2, y: line.y2 })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
missedPoints = [
|
||||||
|
...new Set(missedPoints.map((line) => JSON.stringify(line))),
|
||||||
|
].map((line) => JSON.parse(line))
|
||||||
|
|
||||||
|
console.log(missedPoints)
|
||||||
|
|
||||||
|
missedPoints.forEach(p1 => {
|
||||||
|
let p2 = missedPoints.filter(p => !(p.x === p1.x && p.y === p1.y)).reduce((prev, current) => {
|
||||||
|
console.log('current : ', current)
|
||||||
|
console.log('prev : ', prev)
|
||||||
|
if (prev !== undefined) {
|
||||||
|
return Math.abs(current.x - p1.x) + Math.abs(current.y - p1.y) < Math.abs(prev.x - p1.x) + Math.abs(prev.y - p1.y) ? current : prev
|
||||||
|
} else {
|
||||||
|
return current
|
||||||
|
}
|
||||||
|
}, undefined)
|
||||||
|
|
||||||
|
if (p2 !== undefined) {
|
||||||
|
console.log(p1.x, p2.x, p1.y, p2.y)
|
||||||
|
if (p1.x === p2.x && p1.y < p2.y) {
|
||||||
|
missedLine.push({ x1: p1.x, y1: p1.y, x2: p2.x, y2: p2.y })
|
||||||
|
}
|
||||||
|
if (p1.x === p2.x && p1.y > p2.y) {
|
||||||
|
missedLine.push({ x1: p1.x, y1: p2.y, x2: p2.x, y2: p1.y })
|
||||||
|
}
|
||||||
|
if (p1.x < p2.x && p1.y === p2.y) {
|
||||||
|
missedLine.push({ x1: p1.x, y1: p1.y, x2: p2.x, y2: p2.y })
|
||||||
|
}
|
||||||
|
if (p1.x > p2.x && p1.y === p2.y) {
|
||||||
|
missedLine.push({ x1: p2.x, y1: p1.y, x2: p1.x, y2: p2.y })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
//중복라인제거
|
||||||
|
missedLine = [
|
||||||
|
...new Set(missedLine.map((line) => JSON.stringify(line))),
|
||||||
|
].map((line) => JSON.parse(line))
|
||||||
|
|
||||||
|
console.log(missedLine)
|
||||||
|
|
||||||
|
missedLine.forEach((p, index) => {
|
||||||
|
const line = new QLine([p.x1, p.y1, p.x2, p.y2], {
|
||||||
|
fontSize: this.fontSize,
|
||||||
|
stroke: 'purple',
|
||||||
|
strokeWidth: 1,
|
||||||
|
})
|
||||||
|
this.addWithUpdate(line)
|
||||||
|
this.innerLines.push(line)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
최대 생성 마루 갯수
|
||||||
|
*/
|
||||||
|
const getMaxRidge = (length) => {
|
||||||
|
return ((length - 4) / 2) + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
두 라인의 사잇각 계산
|
||||||
|
*/
|
||||||
|
const getDirectionForDegree = (line1, line2) => {
|
||||||
|
let degree = getLineDirection(line1) + getLineDirection(line2)
|
||||||
|
let vector
|
||||||
|
|
||||||
|
switch (degree) {
|
||||||
|
case 'rb':
|
||||||
|
vector = 45
|
||||||
|
break
|
||||||
|
case 'br':
|
||||||
|
vector = 45
|
||||||
|
break
|
||||||
|
case 'lb':
|
||||||
|
vector = 135
|
||||||
|
break
|
||||||
|
case 'bl':
|
||||||
|
vector = 135
|
||||||
|
break
|
||||||
|
case 'lt':
|
||||||
|
vector = 225
|
||||||
|
break
|
||||||
|
case 'tl':
|
||||||
|
vector = 225
|
||||||
|
break
|
||||||
|
case 'rt':
|
||||||
|
vector = 315
|
||||||
|
break
|
||||||
|
case 'tr':
|
||||||
|
vector = 315
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return vector
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
현재 라인의 방향을 계산
|
||||||
|
*/
|
||||||
|
const getLineDirection = (line) => {
|
||||||
|
let x1, x2, y1, y2, xp, yp
|
||||||
|
x1 = Math.round(line.x1)
|
||||||
|
x2 = Math.round(line.x2)
|
||||||
|
y1 = Math.round(line.y1)
|
||||||
|
y2 = Math.round(line.y2)
|
||||||
|
|
||||||
|
xp = x1 - x2
|
||||||
|
yp = y1 - y2
|
||||||
|
|
||||||
|
if (xp === 0) {
|
||||||
|
if (yp < 0) {
|
||||||
|
return 'b'
|
||||||
|
} else {
|
||||||
|
return 't'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (yp === 0) {
|
||||||
|
if (xp < 0) {
|
||||||
|
return 'r'
|
||||||
|
} else {
|
||||||
|
return 'l'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user