diff --git a/src/components/Roof2.jsx b/src/components/Roof2.jsx index d8b4c25e..e9da0e7a 100644 --- a/src/components/Roof2.jsx +++ b/src/components/Roof2.jsx @@ -405,6 +405,15 @@ export default function Roof2(props) { { x: 600, y: 100 }, ] + const type1C = [ + { x: 100, y: 100 }, + { x: 850, y: 100 }, + { x: 850, y: 800 }, + { x: 550, y: 800 }, + { x: 500, y: 400 }, + { x: 100, y: 400 }, + ] + const types = [type1, type2, type3, type4, type1A, type1B, eightPoint, eightPoint2, eightPoint3, eightPoint4, twelvePoint] const newP = [ { x: 450, y: 450 }, @@ -413,7 +422,7 @@ export default function Roof2(props) { { x: 450, y: 850 }, ] - const polygon = new QPolygon(twelvePoint, { + const polygon = new QPolygon(type1C, { fill: 'transparent', stroke: 'green', strokeWidth: 1, diff --git a/src/hooks/useMode.js b/src/hooks/useMode.js index d427b548..bc650216 100644 --- a/src/hooks/useMode.js +++ b/src/hooks/useMode.js @@ -1263,7 +1263,8 @@ export function useMode() { historyPoints.current = [] const wall = makePolygon(null, sort) - wall.set({ name: 'wall' }) + wall.name = 'wall' + // wall.set({ name: 'wall' }) return wall } @@ -1471,7 +1472,8 @@ export function useMode() { *벽 지붕 외곽선 생성 polygon을 입력받아 만들기 */ const handleOuterlinesTest2 = (polygon, offset = 50) => { - const offsetPoints = offsetPolygon(polygon.points, offset) + drawRoofPolygon(polygon, offset) + /*const offsetPoints = offsetPolygon(polygon.points, offset) const roof = makePolygon( offsetPoints.map((point) => { @@ -1484,287 +1486,211 @@ export function useMode() { setWall(polygon) roof.drawHelpLine() - roof.divideLine() + roof.divideLine()*/ } const drawRoofPolygon = (wall, offset = 50) => { - console.log(wall) - let points = wall.points, - expandedPoints = [] - - let minX = points[0].x, - minY = points[0].y, - maxX = points[0].x, - maxY = points[0].y - - points.forEach((point) => { - if (point.x < minX) minX = point.x - if (point.y < minY) minY = point.y - if (point.x > maxX) maxX = point.x - if (point.y > maxY) maxY = point.y - }) - - console.log(points) - points.forEach((point, index) => { - const prevIndex = index === 0 ? points.length - 1 : index - 1 - const nextIndex = index === points.length - 1 ? 0 : index + 1 - point.direction = getDirectionByPoint(point, points[nextIndex]) - point.length = Math.abs(point.x - points[nextIndex].x) === 0 ? Math.abs(point.y - points[nextIndex].y) : Math.abs(point.x - points[nextIndex].x) - // point.degree = Math.round(getDegreeBetweenTwoLines(points[prevIndex], point, points[nextIndex])) - }) - console.log('points : ', points) - - points.forEach((currentWall, index) => { - let prevWall = points[index === 0 ? points.length - 1 : index - 1] - let nextWall = points[index === points.length - 1 ? 0 : index + 1] - let isStartPointIn = minX < currentWall.x && currentWall.x < maxX && minY < currentWall.y && currentWall.y < maxY - // let isEndPointIn = minX < currentWall.x2 && currentWall.x2 < maxX && minY < currentWall.y2 && currentWall.y2 < maxY - - if (prevWall.direction !== nextWall.direction) { - if (currentWall.direction === 'top') { - console.log('prevWall degree : ', 45) - if (prevWall.direction === 'right') { - let addLength = getLineOffsetPoint(prevWall, currentWall, nextWall, offset) - expandedPoints.push({ - x: currentWall.x + addLength, - y: currentWall.y + addLength, - }) - } - if (prevWall.direction === 'left') { - console.log('prevWall degree : ', 225) - expandedPoints.push({ - x: currentWall.x - offset, - y: currentWall.y + offset, - }) - } - } - if (currentWall.direction === 'bottom') { - if (prevWall.direction === 'right') { - console.log('prevWall degree : ', 45) - let addLength = getLineOffsetPoint(prevWall, currentWall, nextWall, offset) - console.log(currentWall.x, '-', offset, '+', addLength) - console.log('addLength : ', addLength) - expandedPoints.push({ - x: currentWall.x + addLength, - y: currentWall.y - addLength, - }) - } - if (prevWall.direction === 'left') { - console.log('prevWall degree : ', 315) - let addLength = getLineOffsetPoint(prevWall, currentWall, nextWall, offset) - console.log(currentWall.x, '-', offset, '+', addLength) - console.log('addLength : ', addLength) - expandedPoints.push({ - x: currentWall.x - offset, - y: currentWall.y - offset, - }) - } - } - if (currentWall.direction === 'right') { - if (prevWall.direction === 'top') { - if (isStartPointIn) { - console.log('prevWall degree : ', 135) - expandedPoints.push({ - x: currentWall.x + offset, - y: currentWall.y + offset, - }) - } else { - console.log('prevWall degree : ', 315) - expandedPoints.push({ - x: currentWall.x - offset, - y: currentWall.y - offset, - }) - } - } - if (prevWall.direction === 'bottom') { - if (isStartPointIn) { - console.log('prevWall degree : ', 45) - - expandedPoints.push({ - x: currentWall.x + offset, - y: currentWall.y - offset, - }) - } else { - console.log('prevWall degree : ', 225) - let addLength = getLineOffsetPoint(prevWall, currentWall, nextWall, offset) - console.log('addLength : ', addLength) - expandedPoints.push({ - x: currentWall.x - offset, - y: currentWall.y + offset, - }) - } - } - } - if (currentWall.direction === 'left') { - if (prevWall.direction === 'top') { - if (isStartPointIn) { - console.log('prevWall degree : ', 225) - let addLength = getLineOffsetPoint(prevWall, currentWall, nextWall, offset) - console.log('addLength : ', addLength) - expandedPoints.push({ - x: currentWall.x - offset, - y: currentWall.y + offset, - }) - } else { - console.log('prevWall degree : ', 45) - - let addLength = getLineOffsetPoint(prevWall, currentWall, nextWall, offset) - - expandedPoints.push({ - x: currentWall.x + offset, - y: currentWall.y - offset, - }) - } - } - if (prevWall.direction === 'bottom') { - if (isStartPointIn) { - console.log('prevWall degree : ', 315) - expandedPoints.push({ - x: currentWall.x - offset, - y: currentWall.y - offset, - }) - } else { - console.log('prevWall degree : ', 135) - expandedPoints.push({ - x: currentWall.x + offset, - y: currentWall.y + offset, - }) - } - } + let walls = wall.lines + walls.forEach((wall, index) => { + if (index === 0) { + wall.attributes = { + type: 'gable', + width: 30, } } else { - console.log('else :::: ') - if (currentWall.direction === 'top') { - if (prevWall.direction === 'right') { - if (isStartPointIn) { - console.log('prevWall degree : ', 315) - expandedPoints.push({ - x: currentWall.x - offset, - y: currentWall.y - offset, - }) - } else { - console.log('prevWall degree : ', 135) - expandedPoints.push({ - x: currentWall.x + offset, - y: currentWall.y + offset, - }) - } - } - if (prevWall.direction === 'left') { - if (isStartPointIn) { - console.log('prevWall degree : ', 45) - expandedPoints.push({ - x: currentWall.x + offset, - y: currentWall.y - offset, - }) - } else { - console.log('prevWall degree : ', 225) - expandedPoints.push({ - x: currentWall.x - offset, - y: currentWall.y + offset, - }) - } - } - } - if (currentWall.direction === 'bottom') { - if (prevWall.direction === 'right') { - if (isStartPointIn) { - console.log('prevWall degree : ', 225) - expandedPoints.push({ - x: currentWall.x - offset, - y: currentWall.y + offset, - }) - } else { - console.log('prevWall degree : ', 45) - expandedPoints.push({ - x: currentWall.x + offset, - y: currentWall.y - offset, - }) - } - } - } - if (currentWall.direction === 'right') { - if (prevWall.direction === 'top') { - if (isStartPointIn) { - console.log('prevWall degree : ', 135) - expandedPoints.push({ - x: currentWall.x + offset, - y: currentWall.y + offset, - }) - } else { - console.log('prevWall degree : ', 315) - expandedPoints.push({ - x: currentWall.x - offset, - y: currentWall.y - offset, - }) - } - } - if (prevWall.direction === 'bottom') { - if (isStartPointIn) { - console.log('prevWall degree : ', 225) - expandedPoints.push({ - x: currentWall.x - offset, - y: currentWall.y + offset, - }) - } else { - console.log('prevWall degree : ', 45) - expandedPoints.push({ - x: currentWall.x + offset, - y: currentWall.y - offset, - }) - } - } - } - if (currentWall.direction === 'left') { - if (prevWall.direction === 'top') { - if (isStartPointIn) { - console.log('prevWall degree : ', 225) - expandedPoints.push({ - x: currentWall.x - offset, - y: currentWall.y + offset, - }) - } else { - console.log('prevWall degree : ', 45) - expandedPoints.push({ - x: currentWall.x + offset, - y: currentWall.y - offset, - }) - } - } - if (prevWall.direction === 'bottom') { - if (isStartPointIn) { - console.log('prevWall degree : ', 135) - expandedPoints.push({ - x: currentWall.x + offset, - y: currentWall.y + offset, - }) - } else { - console.log('prevWall degree : ', 315) - expandedPoints.push({ - x: currentWall.x - offset, - y: currentWall.y - offset, - }) - } - } + wall.attributes = { + type: 'hip', + width: 50, } } }) - console.log('expandedPoints : ', expandedPoints) + console.log('walls', walls) - /*const roof = new fabric.Polygon(expandedPoints, { - fill: 'transparent', - stroke: 'red', - strokeWidth: 1, - selectable: true, - fontSize: fontSize, - name: 'QPolygon1', + walls.forEach((currentWall, index) => { + let prevWall, nextWall + if (index === 0) { + prevWall = walls[walls.length - 1] + nextWall = walls[index + 1] + } else if (index === walls.length - 1) { + prevWall = walls[index - 1] + nextWall = walls[0] + } else { + prevWall = walls[index - 1] + nextWall = walls[index + 1] + } + + let p1 = [ + { x: currentWall.x1, y: currentWall.y1 }, + { x: currentWall.x2, y: currentWall.y2 }, + { x: prevWall.x1, y: prevWall.y1 }, + { x: prevWall.x2, y: prevWall.y2 }, + ], + p2 = [ + { x: currentWall.x1, y: currentWall.y1 }, + { x: currentWall.x2, y: currentWall.y2 }, + { x: nextWall.x1, y: nextWall.y1 }, + { x: nextWall.x2, y: nextWall.y2 }, + ] + + p1 = Array.from(new Set(p1.map((point) => JSON.stringify(point)))).map((point) => JSON.parse(point)) + p2 = Array.from(new Set(p2.map((point) => JSON.stringify(point)))).map((point) => JSON.parse(point)) + + let p1Lengths = [] + p1.forEach((point1, index) => { + let point2 + if (p1.length - 1 === index) { + point2 = p1[0] + } else { + point2 = p1[index + 1] + } + const dx = Math.abs(point2.x - point1.x) + const dy = Math.abs(point2.y - point1.y) + p1Lengths.push({ + length: Math.round(Math.sqrt(dx ** 2 + dy ** 2)), + coords: [ + { x: point1.x, y: point1.y }, + { x: point2.x, y: point2.y }, + ], + }) + }) + + let p2Lengths = [] + p2.forEach((point1, index) => { + let point2 + if (p2.length - 1 === index) { + point2 = p2[0] + } else { + point2 = p2[index + 1] + } + const dx = Math.abs(point2.x - point1.x) + const dy = Math.abs(point2.y - point1.y) + p2Lengths.push({ + length: Math.round(Math.sqrt(dx ** 2 + dy ** 2)), + coords: [ + { x: point1.x, y: point1.y }, + { x: point2.x, y: point2.y }, + ], + }) + }) + + let x1 = 0, + y1 = 0, + x2 = 0, + y2 = 0, + offsetX1 = 0, + offsetY1 = 0, + offsetX2 = 0, + offsetY2 = 0 + + let alfa = Math.round(Math.sqrt(Math.abs(currentWall.x1 - currentWall.x2) ** 2 + Math.abs(currentWall.y1 - currentWall.y2) ** 2)), + bravo = Math.round(Math.sqrt(Math.abs(prevWall.x1 - prevWall.x2) ** 2 + Math.abs(prevWall.y1 - prevWall.y2) ** 2)), + charlie = p1Lengths.filter((length) => length.length !== alfa && length.length !== bravo)[0], + alpha = Math.round(Math.acos((alfa ** 2 + charlie.length ** 2 - bravo ** 2) / (2 * alfa * charlie.length)) * (180 / Math.PI) * 100) / 100, + beta = Math.round(Math.acos((bravo ** 2 + charlie.length ** 2 - alfa ** 2) / (2 * bravo * charlie.length)) * (180 / Math.PI) * 100) / 100, + gamma = Math.round(Math.acos((alfa ** 2 + bravo ** 2 - charlie.length ** 2) / (2 * alfa * bravo)) * (180 / Math.PI) * 100) / 100, + isValley = checkValley(wall, currentWall, prevWall) + console.log('현재 라인 : ', alfa) + gamma = isValley ? Math.round(((360 - gamma) / 2) * 100) / 100 : Math.round((gamma / 2) * 100) / 100 + + console.log('이전 라인과의 각도', gamma) + + if (currentWall.x1 === currentWall.x2) { + offsetY1 = currentWall.attributes.width + offsetX1 = prevWall.attributes.width + x1 = Math.min(currentWall.x1, currentWall.x2) + offsetX1 + y1 = currentWall.y1 + offsetY1 + } else if (currentWall.y1 === currentWall.y2) { + offsetX1 = currentWall.attributes.width + offsetY1 = prevWall.attributes.width + x1 = currentWall.x1 + offsetX1 + y1 = Math.min(currentWall.y1, currentWall.y2) + offsetY1 + } else { + } + + bravo = Math.round(Math.sqrt(Math.abs(nextWall.x1 - nextWall.x2) ** 2 + Math.abs(nextWall.y1 - nextWall.y2) ** 2)) + charlie = p2Lengths.filter((length) => length.length !== alfa && length.length !== bravo)[0] + + // alpha = Math.round(Math.acos((alfa ** 2 + charlie ** 2 - bravo ** 2) / (2 * alfa * charlie)) * (180 / Math.PI)) + // betta = Math.round(Math.acos((bravo ** 2 + charlie ** 2 - alfa ** 2) / (2 * bravo * charlie)) * (180 / Math.PI)) + gamma = Math.round(Math.acos((alfa ** 2 + bravo ** 2 - charlie.length ** 2) / (2 * alfa * bravo)) * (180 / Math.PI) * 100) / 100 + isValley = checkValley(wall, currentWall, nextWall) + gamma = isValley ? Math.round(((360 - gamma) / 2) * 100) / 100 : Math.round((gamma / 2) * 100) / 100 + + console.log('다음 라인과의 각도', gamma) + + /*let offsetX = 0, + offsetY = 0 + let x1 = 0, + y1 = 0, + x2 = 0, + y2 = 0 + if (prevWall.direction !== nextWall.direction) { + if (currentWall.x1 === currentWall.x2) { + offsetX = prevWall.x1 < currentWall.x1 ? currentWall.attributes.width : -currentWall.attributes.width + x1 = currentWall.x1 + x2 = currentWall.x2 + y1 = Math.min(currentWall.y1, currentWall.y2) - Math.min(prevWall.attributes.width, nextWall.attributes.width) + y2 = Math.max(currentWall.y1, currentWall.y2) + Math.max(prevWall.attributes.width, nextWall.attributes.width) + } else { + offsetY = prevWall.y1 < currentWall.y1 ? currentWall.attributes.width : -currentWall.attributes.width + x1 = Math.min(currentWall.x1, currentWall.x2) - Math.min(prevWall.attributes.width, nextWall.attributes.width) + x2 = Math.max(currentWall.x1, currentWall.x2) + Math.max(prevWall.attributes.width, nextWall.attributes.width) + y1 = currentWall.y1 + y2 = currentWall.y2 + } + } else { + } + + x1 = x1 + offsetX + x2 = x2 + offsetX + y1 = y1 + offsetY + y2 = y2 + offsetY + + const roof = new QLine([x1, y1, x2, y2], { + fontSize: fontSize, + stroke: 'black', + strokeWidth: 1, + name: 'roofLine', + }) + canvas?.add(roof) + canvas?.renderAll()*/ }) + } - roof.wall = wall - canvas?.add(roof)*/ + /** + * 라인 사이가 지붕골 인지 확인. + * @param polygon + * @param line1 + * @param line2 + * @returns {boolean} + */ + const checkValley = (polygon, line1, line2) => { + let points = [ + { x: line1.x1, y: line1.y1 }, + { x: line1.x2, y: line1.y2 }, + { x: line2.x1, y: line2.y1 }, + { x: line2.x2, y: line2.y2 }, + ] + points = Array.from(new Set(points.map((point) => JSON.stringify(point)))).map((point) => JSON.parse(point)) + const centroidX = points.reduce((acc, point) => acc + point.x, 0) / points.length + const centroidY = points.reduce((acc, point) => acc + point.y, 0) / points.length - // roof.drawHelpLine() + let isValley = true + const pPoints = polygon.points + pPoints.forEach((point, index) => { + if (index < pPoints.length - 1) { + let j = index + 1 + let xi = pPoints[index].x + polygon.left, + yi = pPoints[index].y + polygon.top + let xj = pPoints[j].x + polygon.left, + yj = pPoints[j].y + polygon.top + + let intersect = yi > centroidY !== yj > centroidY && centroidX < ((xj - xi) * (centroidY - yi)) / (yj - yi) + xi + if (intersect) isValley = !isValley + } + }) + return isValley } /**