diff --git a/src/components/Roof2.jsx b/src/components/Roof2.jsx index fad075bd..82ba40c1 100644 --- a/src/components/Roof2.jsx +++ b/src/components/Roof2.jsx @@ -431,7 +431,7 @@ export default function Roof2(props) { { x: 450, y: 850 }, ] - const polygon = new QPolygon(rectangleType2, { + const polygon = new QPolygon(type2, { fill: 'transparent', stroke: 'green', strokeWidth: 1, diff --git a/src/components/fabric/QPolygon.js b/src/components/fabric/QPolygon.js index 44cbfb37..8e450e77 100644 --- a/src/components/fabric/QPolygon.js +++ b/src/components/fabric/QPolygon.js @@ -2,7 +2,7 @@ import { fabric } from 'fabric' import { v4 as uuidv4 } from 'uuid' import { QLine } from '@/components/fabric/QLine' import { distanceBetweenPoints, findTopTwoIndexesByDistance, getDirectionByPoint, sortedPointLessEightPoint, sortedPoints } from '@/util/canvas-util' -import { calculateAngle, drawRidgeRoof, drawHippedRoof, inPolygon, toGeoJSON } from '@/util/qpolygon-utils' +import { calculateAngle, drawRidgeRoof, drawShedRoof, inPolygon, toGeoJSON } from '@/util/qpolygon-utils' import * as turf from '@turf/turf' import { LINE_TYPE } from '@/common/common' @@ -187,7 +187,7 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, { const eavesType = [LINE_TYPE.WALLLINE.EAVES, LINE_TYPE.WALLLINE.HIPANDGABLE] const gableType = [LINE_TYPE.WALLLINE.GABLE, LINE_TYPE.WALLLINE.JERKINHEAD] - const isEaves = types.every((type) => eavesType.includes(type)) + // const isEaves = types.every((type) => eavesType.includes(type)) const gableOdd = types.filter((type, i) => i % 2 === 0) const gableEven = types.filter((type, i) => i % 2 === 1) const hasShed = types.includes(LINE_TYPE.WALLLINE.SHED) @@ -199,18 +199,41 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, { ) { console.log('박공 지붕') } else if (hasShed) { - //편류지붕 - let shedIndex = 0 - types.forEach((type, i) => { - if (type === LINE_TYPE.WALLLINE.SHED) { - shedIndex = i - } + const sheds = this.lines.filter((line) => line.attributes !== undefined && line.attributes.type === LINE_TYPE.WALLLINE.SHED) + const areLinesParallel = function (line1, line2) { + const angle1 = calculateAngle(line1.startPoint, line1.endPoint) + const angle2 = calculateAngle(line2.startPoint, line2.endPoint) + return angle1 === angle2 + } + + let isShedRoof = true + sheds.forEach((shed, i) => { + isShedRoof = areLinesParallel(shed, sheds[(i + 1) % sheds.length]) }) - const shedOdd = types.filter((type, i) => i % 2 === shedIndex % 2).filter((type) => type !== LINE_TYPE.WALLLINE.SHED) - const shedEven = types.filter((type, i) => i % 2 !== shedIndex % 2) - types.forEach((type, i) => console.log(type, i, i % 2, shedIndex % 2, i % 2 === shedIndex % 2)) - if (shedOdd.every((type) => type === LINE_TYPE.WALLLINE.EAVES) && shedEven.every((type) => type === LINE_TYPE.WALLLINE.GABLE)) { - console.log('편류지붕') + if (isShedRoof) { + const eaves = this.lines + .filter((line) => line.attributes !== undefined && line.attributes.type === LINE_TYPE.WALLLINE.EAVES) + .filter((line) => { + const angle1 = calculateAngle(sheds[0].startPoint, sheds[0].endPoint) + const angle2 = calculateAngle(line.startPoint, line.endPoint) + if (Math.abs(angle1 - angle2) === 180) { + return line + } + }) + if (eaves.length > 0) { + const gables = this.lines.filter((line) => sheds.includes(line) === false && eaves.includes(line) === false) + const isGable = gables.every((line) => gableType.includes(line.attributes.type)) + console.log('isGable : ', isGable) + if (isGable) { + drawShedRoof(this.id, this.canvas) + } else { + drawRidgeRoof(this.id, this.canvas) + } + } else { + drawRidgeRoof(this.id, this.canvas) + } + } else { + drawRidgeRoof(this.id, this.canvas) } } else { drawRidgeRoof(this.id, this.canvas) diff --git a/src/hooks/useMode.js b/src/hooks/useMode.js index 486bc8e9..1b91fb7e 100644 --- a/src/hooks/useMode.js +++ b/src/hooks/useMode.js @@ -36,7 +36,7 @@ import { QPolygon } from '@/components/fabric/QPolygon' import offsetPolygon from '@/util/qpolygon-utils' import { isObjectNotEmpty } from '@/util/common-utils' import * as turf from '@turf/turf' -import { INPUT_TYPE, LINE_TYPE, Mode, POLYGON_TYPE } from '@/common/common' +import { INPUT_TYPE, Mode, POLYGON_TYPE } from '@/common/common' export function useMode() { const [mode, setMode] = useRecoilState(modeState) @@ -1515,9 +1515,17 @@ export function useMode() { pitch: 4, sleeve: true, } - /*if (index === 1 || index === 3) { + /*if (index === 1) { line.attributes = { - type: LINE_TYPE.WALLLINE.WALL, + type: LINE_TYPE.WALLLINE.SHED, + offset: 30, //출폭 + width: 30, //폭 + pitch: 4, //구배 + sleeve: true, //소매 + } + } else if (index === 5 || index === 3) { + line.attributes = { + type: LINE_TYPE.WALLLINE.EAVES, offset: 50, //출폭 width: 30, //폭 pitch: 4, //구배 @@ -1525,8 +1533,8 @@ export function useMode() { } } else { line.attributes = { - type: LINE_TYPE.WALLLINE.EAVES, - offset: 40, + type: LINE_TYPE.WALLLINE.GABLE, + offset: 20, width: 50, pitch: 4, sleeve: true, @@ -1750,8 +1758,13 @@ export function useMode() { roof.setWall(wall) roof.lines.forEach((line, index) => { + const lineLength = Math.sqrt( + Math.pow(Math.round(Math.abs(line.x1 - line.x2) * 10), 2) + Math.pow(Math.round(Math.abs(line.y1 - line.y2) * 10), 2), + ) line.attributes = { roofId: roof.id, + planeSize: lineLength, + actualSize: lineLength, wallLine: wall.lines[index].id, type: wall.lines[index].attributes.type, offset: wall.lines[index].attributes.offset, @@ -1770,9 +1783,6 @@ export function useMode() { line.attributes.currentRoof = roof.lines[index].id }) - console.log('drawRoofPolygon roof : ', roof) - console.log('drawRoofPolygon wall : ', wall) - setRoof(roof) setWall(wall) diff --git a/src/util/qpolygon-utils.js b/src/util/qpolygon-utils.js index e373df8d..a45fa6aa 100644 --- a/src/util/qpolygon-utils.js +++ b/src/util/qpolygon-utils.js @@ -1477,6 +1477,42 @@ function calculateAngleBetweenLines(line1, line2) { return (angleInRadians * 180) / Math.PI } +/** + * 한쪽흐름 지붕 + * @param roofId + * @param canvas + */ +export const drawShedRoof = (roofId, canvas) => { + const roof = canvas?.getObjects().find((object) => object.id === roofId) + const hasNonParallelLines = roof.lines.filter((line) => line.x1 !== line.x2 && line.y1 !== line.y2) + if (hasNonParallelLines.length > 0) { + alert('대각선이 존재합니다.') + return + } + + const sheds = roof.lines.filter((line) => line.attributes !== undefined && line.attributes.type === LINE_TYPE.WALLLINE.SHED) + const eaves = roof.lines.filter((line) => line.attributes !== undefined && line.attributes.type === LINE_TYPE.WALLLINE.EAVES) + const gables = roof.lines.filter((line) => line.attributes !== undefined && line.attributes.type === LINE_TYPE.WALLLINE.GABLE) + + console.log('gable', gables) + + let shedDegree = sheds[0].attributes.degree || 0 + const shedChon = sheds[0].attributes.pitch || 0 + + if (shedDegree === 0) { + shedDegree = getDegreeByChon(shedChon) + } + const getHeight = function (adjust, degree) { + return Math.tan(degree * (Math.PI / 180)) * adjust + } + + gables.forEach((gable) => { + const adjust = gable.attributes.planeSize + const height = getHeight(adjust, shedDegree) + gable.attributes.actualSize = Math.round(Math.sqrt(Math.pow(adjust, 2) + Math.pow(height, 2))) + }) +} + export const drawRidgeRoof = (roofId, canvas) => { const roof = canvas?.getObjects().find((object) => object.id === roofId) const hasNonParallelLines = roof.lines.filter((line) => line.x1 !== line.x2 && line.y1 !== line.y2) @@ -1904,8 +1940,6 @@ const drawHips = (roof, canvas) => { attributes: { roofId: roof.id, currentRoof: currentRoof.id, - planeSize: currentRoof.length, - actualSize: currentRoof.length, }, }) canvas.add(hip2) @@ -3505,8 +3539,13 @@ export const changeCurrentRoof = (currentRoof, canvas) => { newRoof.setWall(wall) newRoof.lines.forEach((line, index) => { + const lineLength = Math.sqrt( + Math.pow(Math.round(Math.abs(line.x1 - line.x2) * 10), 2) + Math.pow(Math.round(Math.abs(line.y1 - line.y2) * 10), 2), + ) line.attributes = { roofId: newRoof.id, + planeSize: lineLength, + actualSize: lineLength, wallLine: wall.lines[index].id, type: wall.lines[index].attributes.type, offset: wall.lines[index].attributes.offset, @@ -3561,6 +3600,19 @@ const reDrawPolygon = (polygon, canvas) => { line.attributes = l.attributes } }) + const lineLength = Math.sqrt( + Math.pow(Math.round(Math.abs(line.x1 - line.x2) * 10), 2) + Math.pow(Math.round(Math.abs(line.y1 - line.y2) * 10), 2), + ) + if (line.attributes !== undefined) { + line.attributes.planeSize = lineLength + line.attributes.actualSize = line + } else { + line.attributes = { + roofId: newPolygon.id, + planeSize: lineLength, + actualSize: lineLength, + } + } }) canvas?.add(newPolygon)