테스트 중 직각일 경우 지붕 라인 그리기 처리.
This commit is contained in:
parent
e0a644c84e
commit
01faaead93
@ -27,6 +27,8 @@ export default class QPolygon extends fabric.Group {
|
||||
helpLines = []
|
||||
|
||||
wall
|
||||
ridges = []
|
||||
hips = []
|
||||
|
||||
constructor(points, options, canvas) {
|
||||
/*if (points.length !== 4 && points.length !== 6) {
|
||||
@ -672,11 +674,111 @@ export default class QPolygon extends fabric.Group {
|
||||
}
|
||||
|
||||
#drawHelpLineInOctagon(chon) {
|
||||
console.log(this.lines)
|
||||
this.drawRoofRidge()
|
||||
this.drawHips()
|
||||
this.connectLinePoint()
|
||||
}
|
||||
|
||||
let prevLine, currentLine, nextLine
|
||||
let point
|
||||
/*마루 그리기
|
||||
외벽의 모양이 돌출된 ㄷ의 형태일때
|
||||
현재 라인의 외벽길이가 붙어있는 두외벽의 길이보다 짧거나 같다면
|
||||
지붕의 두 꼭지점에서 외벽의 두 꼭지점으로 45도 방향으로 선을 그려 만나는 지점이 마루의 시작점이 되고
|
||||
시작점에서 부터 (가장 긴선 - ( 삼각형의 빗변 에서 직각까지의 수직길이 x 2))의 길이가 마루의 끝점이 된다.
|
||||
다만 마루의 길이는 나머지 나머지 두 지붕의 길이중 짧은선의 길이를 넘어갈수 없다.
|
||||
*/
|
||||
drawRoofRidge() {
|
||||
let prevLine, currentLine, nextLine, prevWall, currentWall, nextWall
|
||||
let startXPoint, startYPoint, endXPoint, endYPoint
|
||||
let dVector, ridgeMaxLength, ridgeMinLength, ridgeRun
|
||||
|
||||
this.lines.forEach(
|
||||
(value, index) => {
|
||||
if (index === 0) {
|
||||
prevLine = this.lines[this.lines.length - 1]
|
||||
prevWall = this.wall.lines[this.wall.lines.length - 1]
|
||||
} else {
|
||||
prevLine = this.lines[index - 1]
|
||||
prevWall = this.wall.lines[index - 1]
|
||||
}
|
||||
currentLine = this.lines[index]
|
||||
currentWall = this.wall.lines[index]
|
||||
|
||||
if (index === this.lines.length - 1) {
|
||||
nextLine = this.lines[0]
|
||||
nextWall = this.wall.lines[0]
|
||||
} else if (index === this.lines.length) {
|
||||
nextLine = this.lines[1]
|
||||
nextWall = this.wall.lines[1]
|
||||
} else {
|
||||
nextLine = this.lines[index + 1]
|
||||
nextWall = this.wall.lines[index + 1]
|
||||
}
|
||||
if (this.getLineDirection(prevLine) !== this.getLineDirection(nextLine)) {
|
||||
if (currentWall.length <= prevWall.length && currentWall.length <= nextWall.length) {
|
||||
ridgeMaxLength = Math.min(prevLine.length, currentLine.length, nextLine.length)
|
||||
ridgeMinLength = Math.max(prevLine.length, currentLine.length, nextLine.length) - currentLine.length
|
||||
ridgeRun = ridgeMinLength < ridgeMaxLength ? ridgeMinLength : ridgeMaxLength
|
||||
dVector = this.getDirectionForDegree(prevLine, currentLine)
|
||||
switch (dVector) {
|
||||
case 45:
|
||||
startXPoint = currentLine.x1 + (currentLine.length / 2)
|
||||
startYPoint = currentLine.y1 - (currentLine.length / 2)
|
||||
endXPoint = startXPoint
|
||||
endYPoint = startYPoint - ridgeRun
|
||||
break
|
||||
case 135:
|
||||
startXPoint = currentLine.x1 + (currentLine.length / 2)
|
||||
startYPoint = currentLine.y1 + (currentLine.length / 2)
|
||||
endXPoint = startXPoint + ridgeRun
|
||||
endYPoint = startYPoint
|
||||
break
|
||||
case 225:
|
||||
startXPoint = currentLine.x1 - (currentLine.length / 2)
|
||||
startYPoint = currentLine.y1 + (currentLine.length / 2)
|
||||
endXPoint = startXPoint
|
||||
endYPoint = startYPoint + ridgeRun
|
||||
break
|
||||
case 315:
|
||||
startXPoint = currentLine.x1 - (currentLine.length / 2)
|
||||
startYPoint = currentLine.y1 - (currentLine.length / 2)
|
||||
endXPoint = startXPoint - ridgeRun
|
||||
endYPoint = startYPoint
|
||||
break
|
||||
}
|
||||
if (this.ridges.length < this.getMaxRidge(this.lines.length)) {
|
||||
const ridge = new QLine([startXPoint, startYPoint, endXPoint, endYPoint], {
|
||||
fontSize: this.fontSize,
|
||||
stroke: 'blue',
|
||||
strokeWidth: 1,
|
||||
})
|
||||
this.addWithUpdate(ridge)
|
||||
this.ridges.push(ridge)
|
||||
}
|
||||
//마루와 연결될 추녀마루을 그려준다.
|
||||
const leftHip = new QLine([currentLine.x1, currentLine.y1, startXPoint, startYPoint], {
|
||||
fontSize: this.fontSize,
|
||||
stroke: 'red',
|
||||
strokeWidth: 1,
|
||||
})
|
||||
const rightHip = new QLine([currentLine.x2, currentLine.y2, startXPoint, startYPoint], {
|
||||
fontSize: this.fontSize,
|
||||
stroke: 'red',
|
||||
strokeWidth: 1,
|
||||
})
|
||||
this.addWithUpdate(leftHip)
|
||||
this.addWithUpdate(rightHip)
|
||||
this.hips.push(leftHip)
|
||||
this.hips.push(rightHip)
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
this.canvas.renderAll()
|
||||
}
|
||||
|
||||
drawHips() {
|
||||
let prevLine, currentLine, nextLine, endXPoint, endYPoint
|
||||
this.lines.forEach(
|
||||
(value, index) => {
|
||||
if (index === 0) {
|
||||
@ -689,52 +791,139 @@ export default class QPolygon extends fabric.Group {
|
||||
if (index === this.lines.length - 1) {
|
||||
nextLine = this.lines[0]
|
||||
} else if (index === this.lines.length) {
|
||||
nextLine = this.lines[0]
|
||||
nextLine = this.lines[1]
|
||||
} else {
|
||||
nextLine = this.lines[index + 1]
|
||||
}
|
||||
// point = this.getPointBetweenLine(currentLine, nextLine)
|
||||
|
||||
this.getRoofRidge(prevLine, currentLine, nextLine)
|
||||
if (!this.isAlreadyHip(currentLine)) {
|
||||
this.ridges.forEach(ridge => {
|
||||
if (Math.abs(currentLine.x1 - ridge.x1) === Math.abs(currentLine.y1 - ridge.y1)) {
|
||||
endXPoint = ridge.x1
|
||||
endYPoint = ridge.y1
|
||||
}
|
||||
if (Math.abs(currentLine.x1 - ridge.x2) === Math.abs(currentLine.y1 - ridge.y2)) {
|
||||
endXPoint = ridge.x2
|
||||
endYPoint = ridge.y2
|
||||
}
|
||||
// TODO [ljyoung] : 마루와 만나지 않는 hip 계산
|
||||
})
|
||||
|
||||
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.canvas.renderAll()
|
||||
}
|
||||
|
||||
getRoofRidge(prevLine, currentLine, nextLine) {
|
||||
if (this.getLineDirection(prevLine) !== this.getLineDirection(nextLine)) {
|
||||
console.log(this.getLineDirection(prevLine), this.getLineDirection(currentLine), this.getLineDirection(nextLine))
|
||||
console.log(currentLine.length)
|
||||
if (currentLine.length < prevLine.length && currentLine.length < nextLine.length) {
|
||||
console.log(currentLine.length)
|
||||
/*
|
||||
추녀마루(hip) 중복방지를 위해 마루와 함께 그려진 추녀마루를 확인한다
|
||||
*/
|
||||
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개 이상의 라인과 접해야 함.
|
||||
*/
|
||||
connectLinePoint() {
|
||||
let missedPoints = []
|
||||
let missedLine = []
|
||||
this.ridges.forEach(ridge => {
|
||||
if (this.findConnectionLineCount(ridge.x1, ridge.y1) < 2) {
|
||||
missedPoints.push({ x: ridge.x1, y: ridge.y1 })
|
||||
}
|
||||
if (this.findConnectionLineCount(ridge.x2, ridge.y2) < 2) {
|
||||
missedPoints.push({ x: ridge.x2, y: ridge.y2 })
|
||||
}
|
||||
})
|
||||
console.log(missedPoints)
|
||||
|
||||
missedPoints.forEach(p1 => {
|
||||
let nearX, nearY, diffX, diffY, diffMinX, diffMinY
|
||||
//가장 가까운 포인트를 확인
|
||||
missedPoints.forEach(p2 => {
|
||||
diffX = Math.abs(p1.x - p2.x)
|
||||
diffY = Math.abs(p1.y - p2.y)
|
||||
if (diffMinX === undefined && diffMinY === undefined && diffX > 0 && diffY > 0) {
|
||||
diffMinX = diffX
|
||||
diffMinY = diffY
|
||||
}
|
||||
console.log(nearX, nearY, diffX, diffY, diffMinX, diffMinY)
|
||||
if (diffX !== 0 && diffY !== 0 && (diffX === diffY)
|
||||
&& diffX <= diffMinX && diffY <= diffMinY) {
|
||||
nearX = p2.x
|
||||
nearY = p2.y
|
||||
diffMinX = Math.abs(p1.x - p2.x)
|
||||
diffMinY = Math.abs(p1.y - p2.y)
|
||||
}
|
||||
})
|
||||
console.log(nearX, nearY)
|
||||
if (nearX !== undefined && nearY !== undefined) {
|
||||
if (p1.x < nearX && p1.y < nearY) {
|
||||
missedLine.push({ x1: p1.x, y1: p1.y, x2: nearX, y2: nearY })
|
||||
} else if (p1.x > nearX && p1.y < nearY) {
|
||||
missedLine.push({ x1: nearX, y1: p1.y, x2: p1.x, y2: nearY })
|
||||
} else if (p1.x > nearX && p1.y > nearY) {
|
||||
missedLine.push({ x1: nearX, y1: nearY, x2: p1.x, y2: p1.y })
|
||||
} else if (p1.x < nearX && p1.y > nearY) {
|
||||
missedLine.push({ x1: nearX, y1: nearY, x2: p1.x, y2: p1.y })
|
||||
}
|
||||
}
|
||||
})
|
||||
// TODO [ljyoung] : 중복라인제거
|
||||
console.log(missedLine)
|
||||
missedLine.forEach(p => {
|
||||
const line = new QLine([p.x1, p.y1, p.x2, p.y2], {
|
||||
fontSize: this.fontSize,
|
||||
stroke: 'green',
|
||||
strokeWidth: 1,
|
||||
})
|
||||
this.addWithUpdate(line)
|
||||
})
|
||||
|
||||
this.canvas.renderAll()
|
||||
}
|
||||
|
||||
/*
|
||||
hip은 항상 마루에 연결되고 마루에는 2개 이상의 hip이 연결된다.
|
||||
hip의 시작은 처마꼭지점이며 끝은 마루이기 때문에 힙의 끝 좌표와 비교한다.
|
||||
*/
|
||||
findConnectionLineCount(x, y) {
|
||||
let count = 0
|
||||
this.hips.forEach((hip, index) => {
|
||||
if (x === hip.x2 && y === hip.y2) {
|
||||
count++
|
||||
}
|
||||
})
|
||||
return count
|
||||
}
|
||||
|
||||
/*
|
||||
최대 생성 마루 갯수
|
||||
*/
|
||||
getMaxRidge(length) {
|
||||
let a1 = 4
|
||||
let d = 2
|
||||
return ((length - a1) / d) + 1
|
||||
}
|
||||
|
||||
getPointBetweenLine(line1, line2) {
|
||||
let dVector = this.getDirectionForDegree(line1, line2)
|
||||
let xp = line1.x2, yp = line1.y2
|
||||
|
||||
console.log(xp, yp)
|
||||
|
||||
// let alpha = 45.0 * Math.PI / 180
|
||||
// let a = c * Math.sin(alpha)
|
||||
|
||||
switch (dVector) {
|
||||
case 45:
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
return 'a'
|
||||
}
|
||||
|
||||
/*
|
||||
두 라인의 사잇각 계산
|
||||
*/
|
||||
getDirectionForDegree(line1, line2) {
|
||||
let degree = this.getLineDirection(line1) + this.getLineDirection(line2)
|
||||
let vector
|
||||
@ -769,6 +958,9 @@ export default class QPolygon extends fabric.Group {
|
||||
return vector
|
||||
}
|
||||
|
||||
/*
|
||||
현재 라인의 방향을 계산
|
||||
*/
|
||||
getLineDirection(line) {
|
||||
let x1, x2, y1, y2, xp, yp
|
||||
x1 = Math.round(line.x1)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user