diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index 8e234cf0..c2e68e5d 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -11,6 +11,7 @@ import { useContext } from 'react' import { QcastContext } from '@/app/QcastProvider' import { useCircuitTrestle } from '@/hooks/useCirCuitTrestle' import { useMessage } from '@/hooks/useMessage' +import { groupPoints } from '@/util/module-utils' // 모듈간 같은 행, 열의 마진이 10 이하인 경우는 같은 행, 열로 간주 const MODULE_MARGIN = 10 @@ -1804,7 +1805,7 @@ export const useTrestle = () => { const bracket = new fabric.Rect({ left: startPointX, top: startPointY, - fill: 'green', + fill: i === 0 || i === count - 1 ? 'red' : 'green', name: TRESTLE_MATERIAL.BRACKET, parentId: module.id, surfaceId: module.surfaceId, @@ -2216,7 +2217,7 @@ export const useTrestle = () => { }) // 완전 노출 하면 계산 - const groupPoints = groupCoordinates(centerPoints, modules[0], direction) + const groupPoints = groupCoordinates(centerPoints, modules[0], direction, +roofSizeSet) groupPoints.forEach((group) => { let maxY = group.reduce((acc, cur) => (acc.y > cur.y ? acc : cur)).y @@ -2305,182 +2306,8 @@ export const useTrestle = () => { return groups } - function areConnected(m1, m2, surface) { - /*const m1Fill = m1.fill - const m2Fill = m2.fill - m1.set({ fill: 'red' }) - m2.set({ fill: 'blue' }) - canvas.renderAll()*/ - - let sizes = [] - - const { width: currentWidth, height: currentHeight, moduleInfo: currentModuleInfo } = m1 - const { width: neighborWidth, height: neighborHeight, moduleInfo: neighborModuleInfo } = m2 - - const maxWidth = Math.max(currentWidth, neighborWidth) - const maxHeight = Math.max(currentHeight, neighborHeight) - - const { moduleTpCd: currentModuleTpCd } = currentModuleInfo - const { moduleTpCd: neighborModuleTpCd } = neighborModuleInfo - const { x: m1X, y: m1Y } = m1.getCenterPoint() - const { x: m2X, y: m2Y } = m2.getCenterPoint() - - sizes.push({ width: currentWidth, height: currentHeight }) - - if (currentModuleTpCd !== neighborModuleTpCd) { - sizes.push({ width: neighborWidth, height: neighborHeight }) - } - - /*m1.set({ fill: m1Fill }) - m2.set({ fill: m2Fill }) - canvas.renderAll()*/ - - return sizes.some(({ width, height }) => { - let maxX - let maxY - let halfMaxX - let halfMaxY - const { direction, trestleDetail } = surface - let moduleIntvlHor, moduleIntvlVer - if (+roofSizeSet === 3) { - //육지붕의 경우 값 고정 - moduleIntvlHor = 300 - moduleIntvlVer = 100 - } else { - moduleIntvlHor = trestleDetail.moduleIntvlHor - moduleIntvlVer = trestleDetail.moduleIntvlVer - } - - if (direction === 'south' || direction === 'north') { - maxX = width + moduleIntvlHor / 10 - maxY = height + moduleIntvlVer / 10 - halfMaxX = moduleIntvlHor / 10 - halfMaxY = moduleIntvlVer / 10 - - const leftTopPoint = { x: m1X - width - moduleIntvlHor / 10, y: m1Y - height - moduleIntvlVer / 10 } - const rightTopPoint = { x: m1X + width + moduleIntvlHor / 10, y: m1Y - height - moduleIntvlVer / 10 } - const leftBottomPoint = { x: m1X - width - moduleIntvlHor / 10, y: m1Y + height + moduleIntvlVer / 10 } - const rightBottomPoint = { x: m1X + width + moduleIntvlHor / 10, y: m1Y + height + moduleIntvlVer / 10 } - // {x: m2X, y: m2Y} 가 leftTopPoint, rightTopPoint, leftBottomPoint, rightBottomPoint 내부에 있는지 확인한다. - if ( - isPointInRect( - { - x: leftTopPoint.x, - y: leftTopPoint.y, - width: Math.abs(rightTopPoint.x - leftTopPoint.x), - height: Math.abs(leftTopPoint.y - leftBottomPoint.y), - }, - { x: m2X, y: m2Y }, - ) - ) { - return true - } - if (currentModuleTpCd !== neighborModuleTpCd) { - maxX = currentWidth / 2 + neighborWidth / 2 + moduleIntvlHor / 10 - maxY = currentHeight / 2 + neighborHeight / 2 + moduleIntvlVer / 10 - } - - // console.log(maxX, maxY, halfMaxX, halfMaxY) - - if (Math.abs(m1X - m2X) < 1) { - return Math.abs(Math.abs(m1Y - m2Y) - maxY) < 1 || Math.abs(m2Y - m1Y) <= halfMaxY - } else if (Math.abs(m1Y - m2Y) < 1) { - return Math.abs(Math.abs(m1X - m2X) - maxX) < 1 || Math.abs(m2X - m1X) <= halfMaxX - } - - return ( - (Math.abs(m1X - m2X) < maxX - moduleIntvlHor / 10 + 1 && Math.abs(m1Y - m2Y) < maxY - moduleIntvlVer / 10) || - (Math.abs(Math.abs(m1X - m2X) - maxX / 2) < halfMaxX + 1 && Math.abs(Math.abs(m1Y - m2Y) - maxY) < halfMaxY + 1) || - (Math.abs(Math.abs(m1X - m2X) - maxX) < halfMaxX + 1 && Math.abs(Math.abs(m1Y - m2Y) - maxY / 2) < halfMaxY + 1) - ) - } else if (direction === 'east' || direction === 'west') { - maxX = height + moduleIntvlHor / 10 - maxY = width + moduleIntvlVer / 10 - halfMaxX = moduleIntvlVer / 10 - halfMaxY = moduleIntvlHor / 10 - - // 모듈을 기준으로 왼쪽 상, 오른쪽 상, 왼쪽 하, 오른쪽 하의 각 포인트를 계산 - const leftTopPoint = { x: m1X - width - moduleIntvlVer / 10, y: m1Y + height + moduleIntvlHor / 10 } - const rightTopPoint = { x: m1X - width - moduleIntvlVer / 10, y: m1Y - height - moduleIntvlHor / 10 } - const leftBottomPoint = { x: m1X + width + moduleIntvlVer / 10, y: m1Y + height + moduleIntvlHor / 10 } - const rightBottomPoint = { x: m1X + width + +moduleIntvlVer / 10, y: m1Y - height - moduleIntvlHor / 10 } - - // {x: m2X, y: m2Y} 가 leftTopPoint, rightTopPoint, leftBottomPoint, rightBottomPoint 내부에 있는지 확인한다. - if ( - isPointInRect( - { - x: rightTopPoint.x, - y: rightTopPoint.y, - width: Math.abs(rightBottomPoint.x - rightTopPoint.x), - height: Math.abs(leftTopPoint.y - rightTopPoint.y), - }, - { x: m2X, y: m2Y }, - ) - ) { - return true - } - - if (currentModuleTpCd !== neighborModuleTpCd) { - maxX = currentHeight / 2 + neighborHeight / 2 + moduleIntvlVer / 10 - maxY = currentWidth / 2 + neighborWidth / 2 + moduleIntvlHor / 10 - } - - if (Math.abs(m1X - m2X) < 1) { - return Math.abs(Math.abs(m1Y - m2Y) - maxX) < 1 || Math.abs(m2Y - m1Y) <= halfMaxY - } else if (Math.abs(m1Y - m2Y) < 1) { - return Math.abs(Math.abs(m1X - m2X) - maxY) < 1 || Math.abs(m2X - m1X) <= halfMaxX - } - - return ( - (Math.abs(m1X - m2X) <= maxY - moduleIntvlVer / 10 && Math.abs(m1Y - m2Y) <= maxX - moduleIntvlHor / 10) || - (Math.abs(Math.abs(m1X - m2X) - maxY / 2) < halfMaxY + 1 && Math.abs(Math.abs(m1Y - m2Y) - maxX) < halfMaxX + 1) || - (Math.abs(Math.abs(m1X - m2X) - maxY) < halfMaxY + 1 && Math.abs(Math.abs(m1Y - m2Y) - maxX / 2) < halfMaxX + 1) - ) - } - }) - } - - function isPointInRect(rect, point) { - return point.x >= rect.x && point.x <= rect.x + rect.width && point.y >= rect.y && point.y <= rect.y + rect.height - } - // 25-04-02 추가 // 그룹화 - function groupPoints(modules, surface) { - const groups = [] - const visited = new Set() - - for (const point of modules) { - const { x: pointX, y: pointY } = point.getCenterPoint() - const key = `${pointX},${pointY}` - if (visited.has(key)) continue - - const queue = [point] - const group = [] - - while (queue.length > 0) { - const current = queue.shift() - const { x: currentX, y: currentY } = current.getCenterPoint() - const currentKey = `${currentX},${currentY}` - if (visited.has(currentKey)) continue - - visited.add(currentKey) - group.push(current) - - for (const neighbor of modules) { - const { x: neighborX, y: neighborY } = neighbor.getCenterPoint() - const neighborKey = `${neighborX},${neighborY}` - if (!visited.has(neighborKey) && areConnected(current, neighbor, surface)) { - queue.push(neighbor) - } - } - } - - groups.push(group) - } - - return groups - } // 각도에 따른 길이 반환 function getTrestleLength(length, degree, surface) { diff --git a/src/hooks/surface/useSurfaceShapeBatch.js b/src/hooks/surface/useSurfaceShapeBatch.js index 863de4bf..3423e8b5 100644 --- a/src/hooks/surface/useSurfaceShapeBatch.js +++ b/src/hooks/surface/useSurfaceShapeBatch.js @@ -1,17 +1,16 @@ 'use client' -import { useEffect } from 'react' -import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil' +import { useRecoilValue, useResetRecoilState } from 'recoil' import { canvasSettingState, canvasState, currentCanvasPlanState, globalPitchState } from '@/store/canvasAtom' -import { MENU, POLYGON_TYPE, LINE_TYPE } from '@/common/common' -import { getIntersectionPoint, toFixedWithoutRounding } from '@/util/canvas-util' +import { LINE_TYPE, MENU, POLYGON_TYPE } from '@/common/common' +import { getDegreeByChon, getIntersectionPoint, toFixedWithoutRounding } from '@/util/canvas-util' import { degreesToRadians } from '@turf/turf' import { QPolygon } from '@/components/fabric/QPolygon' import { useSwal } from '@/hooks/useSwal' import { useMessage } from '@/hooks/useMessage' import { useEvent } from '@/hooks/useEvent' import { usePopup } from '@/hooks/usePopup' -import { roofDisplaySelector } from '@/store/settingAtom' +import { basicSettingState, roofDisplaySelector } from '@/store/settingAtom' import { usePolygon } from '@/hooks/usePolygon' import { fontSelector } from '@/store/fontAtom' import { slopeSelector } from '@/store/commonAtom' @@ -20,9 +19,8 @@ import { useRoofFn } from '@/hooks/common/useRoofFn' import { outerLinePointsState } from '@/store/outerLineAtom' import { placementShapeDrawingPointsState } from '@/store/placementShapeDrawingAtom' import { getBackGroundImage } from '@/lib/imageActions' -import PlacementSurfaceLineProperty from '@/components/floor-plan/modal/placementShape/PlacementSurfaceLineProperty' -import { v4 as uuidv4 } from 'uuid' import { useCanvasSetting } from '@/hooks/option/useCanvasSetting' +import { calcLineActualSizeByPlaneSize } from '@/util/qpolygon-utils' export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { const { getMessage } = useMessage() @@ -42,6 +40,7 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { const { setSurfaceShapePattern } = useRoofFn() const currentCanvasPlan = useRecoilValue(currentCanvasPlanState) const { fetchSettings } = useCanvasSetting(false) + const roofSizeSet = useRecoilValue(basicSettingState).roofSizeSet const applySurfaceShape = (surfaceRefs, selectedType, id) => { let length1, length2, length3, length4, length5 @@ -91,7 +90,19 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { } const pointer = canvas?.getPointer(e.e) canvas?.remove(...canvas?.getObjects().filter((obj) => obj.name === MENU.BATCH_CANVAS.SURFACE_SHAPE_BATCH_TEMP)) - points = getSurfaceShape(surfaceId, pointer, { length1, length2, length3, length4, length5 }) + points = getSurfaceShape( + surfaceId, + pointer, + { + length1, + length2, + length3, + length4, + length5, + }, + azimuth, + surfaceRefs, + ) const { xInversion, yInversion, rotate } = surfaceRefs const options = { @@ -352,9 +363,14 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { } //면형상 가져오기 - const getSurfaceShape = (surfaceId, pointer, lengths) => { + const getSurfaceShape = (surfaceId, pointer, lengths, azimuth, ref) => { + const { rotate } = ref + let points = [] - const { length1, length2, length3, length4, length5 } = lengths + let { length1, length2, length3, length4, length5 } = lengths + const degree = getDegreeByChon(globalPitch) + const isRotated = rotate === 90 || rotate === 270 + const isVerticalAzimuth = azimuth === 'up' || azimuth === 'down' switch (surfaceId) { case 1: { @@ -364,15 +380,35 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { newLength2 = Math.sqrt(length3 ** 2 - (length1 / 2) ** 2) } + if ((isRotated && isVerticalAzimuth) || (!isRotated && !isVerticalAzimuth)) { + //가로 선 + // length1 = calcLineActualSizeByPlaneSize(length1, degree) + length1 = Math.sqrt((length1 * Math.tan((degree * Math.PI) / 180)) ** 2 + length1 ** 2) + if (length3 !== 0) { + length3 = Math.sqrt((length1 / 2) ** 2 + newLength2 ** 2) + } + } else { + //세로 선 + newLength2 = calcLineActualSizeByPlaneSize(newLength2, degree) + } + points = [ - { x: pointer.x, y: pointer.y - parseInt(newLength2) / 2 }, - { x: pointer.x - parseInt(length1) / 2, y: pointer.y + parseInt(newLength2) / 2 }, - { x: pointer.x + parseInt(length1) / 2, y: pointer.y + parseInt(newLength2) / 2 }, + { x: pointer.x, y: pointer.y - newLength2 / 2 }, + { x: pointer.x - length1 / 2, y: pointer.y + newLength2 / 2 }, + { x: pointer.x + length1 / 2, y: pointer.y + newLength2 / 2 }, ] break } case 2: { + if ((isRotated && isVerticalAzimuth) || (!isRotated && !isVerticalAzimuth)) { + //가로 선 + length1 = calcLineActualSizeByPlaneSize(length1, degree) + } else { + //세로 선 + length2 = calcLineActualSizeByPlaneSize(length2, degree) + } + points = [ { x: pointer.x - length1 / 2, y: pointer.y + length2 / 2 }, { x: pointer.x + length1 / 2, y: pointer.y + length2 / 2 }, @@ -383,6 +419,13 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { break } case 3: { + if ((isRotated && isVerticalAzimuth) || (!isRotated && !isVerticalAzimuth)) { + length1 = calcLineActualSizeByPlaneSize(length1, degree) + length3 = calcLineActualSizeByPlaneSize(length3, degree) + } else { + length2 = calcLineActualSizeByPlaneSize(length2, degree) + } + points = [ { x: pointer.x - length1 / 2, y: pointer.y + length2 / 2 }, { x: pointer.x + length1 / 2, y: pointer.y + length2 / 2 }, @@ -393,6 +436,12 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { break } case 4: { + if ((isRotated && isVerticalAzimuth) || (!isRotated && !isVerticalAzimuth)) { + length1 = calcLineActualSizeByPlaneSize(length1, degree) + } else { + length2 = calcLineActualSizeByPlaneSize(length2, degree) + } + points = [ { x: pointer.x - length1 / 2, y: pointer.y + length2 / 2 }, { x: pointer.x + length1 / 2, y: pointer.y + length2 / 2 }, @@ -402,6 +451,13 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { break } case 5: { + if ((isRotated && isVerticalAzimuth) || (!isRotated && !isVerticalAzimuth)) { + length1 = calcLineActualSizeByPlaneSize(length1, degree) + } else { + length2 = calcLineActualSizeByPlaneSize(length2, degree) + length3 = calcLineActualSizeByPlaneSize(length3, degree) + } + points = [ { x: pointer.x - length1 / 2, y: pointer.y - length3 / 2 }, { x: pointer.x - length1 / 2, y: pointer.y + length3 / 2 }, @@ -412,7 +468,24 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { break } case 6: { - const angleInRadians = Math.asin(length2 / length3) + let angleInRadians = Math.asin(length2 / length3) + + if (+roofSizeSet === 1) { + if ((isRotated && isVerticalAzimuth) || (!isRotated && !isVerticalAzimuth)) { + length1 = calcLineActualSizeByPlaneSize(length1, degree) + const a = Math.sqrt(length3 ** 2 - length2 ** 2) + const x = Math.sqrt((a * Math.tan((degree * Math.PI) / 180)) ** 2 + a ** 2) + length3 = Math.sqrt(x ** 2 + length2 ** 2) + } else { + const originLength2 = length2 + length2 = calcLineActualSizeByPlaneSize(length2, degree) + const h = originLength2 * Math.tan((degree * Math.PI) / 180) + length3 = Math.sqrt(length3 ** 2 + h ** 2) + } + + angleInRadians = Math.asin(length2 / length3) + } + points = [ { x: pointer.x - length1 / 2, y: pointer.y + length2 / 2 }, { @@ -429,6 +502,16 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { break } case 7: { + if ((isRotated && isVerticalAzimuth) || (!isRotated && !isVerticalAzimuth)) { + //가로 선 + length1 = calcLineActualSizeByPlaneSize(length1, degree) + length2 = calcLineActualSizeByPlaneSize(length2, degree) + length3 = calcLineActualSizeByPlaneSize(length3, degree) + } else { + //세로 선 + length4 = calcLineActualSizeByPlaneSize(length4, degree) + length5 = calcLineActualSizeByPlaneSize(length5, degree) + } points = [ { x: pointer.x - (length1 + length2 + length3) / 2, y: pointer.y - (length4 + length5) / 2 }, { x: pointer.x - (length1 + length2 + length3) / 2, y: pointer.y + (length4 + length5) / 2 }, @@ -458,6 +541,15 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { break } case 8: { + if ((isRotated && isVerticalAzimuth) || (!isRotated && !isVerticalAzimuth)) { + //가로 선 + length1 = calcLineActualSizeByPlaneSize(length1, degree) + length2 = calcLineActualSizeByPlaneSize(length2, degree) + } else { + //세로 선 + length3 = calcLineActualSizeByPlaneSize(length3, degree) + length4 = calcLineActualSizeByPlaneSize(length4, degree) + } points = [ { x: pointer.x - length1 / 2, y: pointer.y + length4 / 2 }, { x: pointer.x - length1 / 2 + length1, y: pointer.y + length4 / 2 }, @@ -476,6 +568,16 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { break } case 9: { + if ((isRotated && isVerticalAzimuth) || (!isRotated && !isVerticalAzimuth)) { + //가로 선 + length1 = calcLineActualSizeByPlaneSize(length1, degree) + length2 = calcLineActualSizeByPlaneSize(length2, degree) + length3 = calcLineActualSizeByPlaneSize(length3, degree) + } else { + //세로 선 + length4 = calcLineActualSizeByPlaneSize(length4, degree) + length5 = calcLineActualSizeByPlaneSize(length5, degree) + } points = [ { x: pointer.x - length1 / 2, y: pointer.y + length4 / 2 }, { x: pointer.x - length1 / 2 + length1, y: pointer.y + length4 / 2 }, @@ -493,6 +595,16 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { break } case 10: { + if ((isRotated && isVerticalAzimuth) || (!isRotated && !isVerticalAzimuth)) { + //가로 선 + length1 = calcLineActualSizeByPlaneSize(length1, degree) + length2 = calcLineActualSizeByPlaneSize(length2, degree) + length3 = calcLineActualSizeByPlaneSize(length3, degree) + } else { + //세로 선 + length4 = calcLineActualSizeByPlaneSize(length4, degree) + length5 = calcLineActualSizeByPlaneSize(length5, degree) + } points = [ { x: pointer.x + length1 / 2 - length1, y: pointer.y + length4 / 2 - length5 }, { x: pointer.x + length1 / 2 - length1, y: pointer.y + length4 / 2 }, @@ -510,6 +622,16 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { break } case 11: { + if ((isRotated && isVerticalAzimuth) || (!isRotated && !isVerticalAzimuth)) { + //가로 선 + length1 = calcLineActualSizeByPlaneSize(length1, degree) + length2 = calcLineActualSizeByPlaneSize(length2, degree) + length3 = calcLineActualSizeByPlaneSize(length3, degree) + } else { + //세로 선 + length4 = calcLineActualSizeByPlaneSize(length4, degree) + length5 = calcLineActualSizeByPlaneSize(length5, degree) + } points = [ { x: pointer.x - length1 / 2, y: pointer.y + length4 / 2 }, { x: pointer.x - length1 / 2 + length1, y: pointer.y + length4 / 2 }, @@ -527,6 +649,15 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { break } case 12: { + if ((isRotated && isVerticalAzimuth) || (!isRotated && !isVerticalAzimuth)) { + //가로 선 + length1 = calcLineActualSizeByPlaneSize(length1, degree) + length2 = calcLineActualSizeByPlaneSize(length2, degree) + } else { + //세로 선 + length3 = calcLineActualSizeByPlaneSize(length3, degree) + length4 = calcLineActualSizeByPlaneSize(length4, degree) + } const leftHypotenuse = Math.sqrt(((length1 - length2) / 2) ** 2 + length3 ** 2) const rightHypotenuse = (length4 / length3) * leftHypotenuse @@ -552,6 +683,15 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { break } case 13: { + if ((isRotated && isVerticalAzimuth) || (!isRotated && !isVerticalAzimuth)) { + //가로 선 + length1 = calcLineActualSizeByPlaneSize(length1, degree) + length2 = calcLineActualSizeByPlaneSize(length2, degree) + } else { + //세로 선 + length3 = calcLineActualSizeByPlaneSize(length3, degree) + length4 = calcLineActualSizeByPlaneSize(length4, degree) + } const pointsArray = [ { x: 0, y: 0 }, { x: 0, y: 0 }, @@ -618,6 +758,16 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { break } case 14: { + if ((isRotated && isVerticalAzimuth) || (!isRotated && !isVerticalAzimuth)) { + //가로 선 + length1 = calcLineActualSizeByPlaneSize(length1, degree) + length2 = calcLineActualSizeByPlaneSize(length2, degree) + length3 = calcLineActualSizeByPlaneSize(length3, degree) + } else { + //세로 선 + length4 = calcLineActualSizeByPlaneSize(length4, degree) + length5 = calcLineActualSizeByPlaneSize(length5, degree) + } points = [ { x: pointer.x - length1 / 2, y: pointer.y + length4 / 2 - length4 }, { x: pointer.x - length1 / 2, y: pointer.y + length4 / 2 }, @@ -634,6 +784,14 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { } case 15: { + if ((isRotated && isVerticalAzimuth) || (!isRotated && !isVerticalAzimuth)) { + //가로 선 + length1 = calcLineActualSizeByPlaneSize(length1, degree) + } else { + //세로 선 + length2 = calcLineActualSizeByPlaneSize(length2, degree) + length3 = calcLineActualSizeByPlaneSize(length3, degree) + } points = [ { x: pointer.x - length1 / 2, y: pointer.y + length2 - length2 / 2 - length3 }, { x: pointer.x - length1 / 2, y: pointer.y + length2 - length2 / 2 }, @@ -645,6 +803,15 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { } case 16: { + if ((isRotated && isVerticalAzimuth) || (!isRotated && !isVerticalAzimuth)) { + //가로 선 + length1 = calcLineActualSizeByPlaneSize(length1, degree) + length2 = calcLineActualSizeByPlaneSize(length2, degree) + } else { + //세로 선 + length3 = calcLineActualSizeByPlaneSize(length3, degree) + length4 = calcLineActualSizeByPlaneSize(length4, degree) + } points = [ { x: pointer.x - length1 / 2 + (length1 - length2) / 2, @@ -674,9 +841,60 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { break } case 17: { - const angle = (Math.asin(length3 / length4) * 180) / Math.PI // 높이와 빗변으로 먼저 각도구하기 + const X = ((length1 - length2) / 2) * Math.tan(Math.asin(length3 / length4)) + console.log('X', X) + const a2 = Math.sqrt(((length1 - length2) / 2) ** 2 + X ** 2) // 오른쪽 상단 대각 + const b2 = length4 - a2 // 오른쪽 하단 대각 - const topL = (length1 - length2) / 2 / Math.cos((angle * Math.PI) / 180) // 꺽이는부분 윗쪽 길이 + const originLength1 = Number(length1) + const originLength2 = Number(length2) + const originLength3 = Number(length3) + const originLength4 = Number(length4) + + let rightBottomDiagonal, rightTopDiagonal + + let angle = (Math.asin(length3 / length4) * 180) / Math.PI // 높이와 빗변으로 먼저 각도구하기 + + if ((isRotated && isVerticalAzimuth) || (!isRotated && !isVerticalAzimuth)) { + const x = length3 / Math.tan(Math.asin(length3 / length4)) + //가로 선 + length1 = calcLineActualSizeByPlaneSize(length1, degree) + length2 = calcLineActualSizeByPlaneSize(length2, degree) + const e6_h = x * Math.tan((degree * Math.PI) / 180) + const e6_a = Math.sqrt(e6_h ** 2 + x ** 2) + length4 = Math.sqrt(length3 ** 2 + e6_a ** 2) // 빗변 구하기 + + const g6_a = Math.sqrt(b2 ** 2 - (originLength3 - X) ** 2) + const g6_h = g6_a * Math.tan((degree * Math.PI) / 180) + const g6_b = Math.sqrt(g6_h ** 2 + g6_a ** 2) + rightBottomDiagonal = Math.sqrt(g6_b ** 2 + (originLength3 - X) ** 2) + + const f6_h = ((originLength1 - originLength2) / 2) * Math.tan((degree * Math.PI) / 180) + console.log('f6_h', f6_h) + + const f6_a = Math.sqrt(f6_h ** 2 + ((originLength1 - originLength2) / 2) ** 2) + angle = (Math.asin(length3 / length4) * 180) / Math.PI // 높이와 빗변으로 먼저 각도구하기 + rightTopDiagonal = Math.sqrt(f6_a ** 2 + X ** 2) + } else { + //세로 선 + const x = length3 / Math.tan(Math.asin(length3 / length4)) + length3 = calcLineActualSizeByPlaneSize(length3, degree) + length4 = Math.sqrt(length3 ** 2 + x ** 2) // 빗변 구하기 + + angle = (Math.asin(length3 / length4) * 180) / Math.PI // 높이와 빗변으로 먼저 각도구하기 + + //오른쪽 하단 대각 길이 + const c6_a = Math.sqrt(b2 ** 2 - (originLength3 - X) ** 2) + const c6_h = (originLength3 - X) * Math.tan((degree * Math.PI) / 180) + const c6_b = Math.sqrt(c6_h ** 2 + (originLength3 - X) ** 2) + + rightBottomDiagonal = Math.sqrt(c6_a ** 2 + c6_b ** 2) + + //오른쪽 상단 대각 길이 + const b6_h = X * Math.tan((degree * Math.PI) / 180) + const b6_a = Math.sqrt(b6_h ** 2 + X ** 2) + rightTopDiagonal = Math.sqrt(b6_a ** 2 + ((originLength1 - originLength2) / 2) ** 2) + } points = [ { @@ -688,22 +906,89 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { y: pointer.y + length3 / 2, }, { - x: pointer.x - length1 / 2 + length4 * Math.cos(degreesToRadians(angle)) + length2 + topL * Math.cos(degreesToRadians(angle)), - y: pointer.y + length3 / 2 - length4 * Math.sin(degreesToRadians(angle)) + topL * Math.sin(degreesToRadians(angle)), + x: pointer.x - length1 / 2 + length1 + rightBottomDiagonal * Math.cos(degreesToRadians(angle)), + y: pointer.y + length3 / 2 - rightBottomDiagonal * Math.sin(degreesToRadians(angle)), }, { - x: pointer.x - length1 / 2 + length4 * Math.cos(degreesToRadians(angle)) + length2, - y: pointer.y + length3 / 2 - length4 * Math.sin(degreesToRadians(angle)), + x: + pointer.x - + length1 / 2 + + length1 + + rightBottomDiagonal * Math.cos(degreesToRadians(angle)) - + rightTopDiagonal * Math.cos(degreesToRadians(angle)), + y: + pointer.y + + length3 / 2 - + rightBottomDiagonal * Math.sin(degreesToRadians(angle)) - + rightTopDiagonal * Math.sin(degreesToRadians(angle)), }, { - x: pointer.x - length1 / 2 + length4 * Math.cos(degreesToRadians(angle)), - y: pointer.y + length3 / 2 - length4 * Math.sin(degreesToRadians(angle)), + x: + pointer.x - + length1 / 2 + + length1 + + rightBottomDiagonal * Math.cos(degreesToRadians(angle)) - + rightTopDiagonal * Math.cos(degreesToRadians(angle)) - + length2, + y: + pointer.y + + length3 / 2 - + rightBottomDiagonal * Math.sin(degreesToRadians(angle)) - + rightTopDiagonal * Math.sin(degreesToRadians(angle)), }, ] break } case 18: { + const X = Math.sqrt(length3 ** 2 - length2 ** 2) + const a2 = Math.sqrt((length1 / 2) ** 2 + ((length2 * (length1 / 2)) / X) ** 2) + const b2 = length3 - a2 + const originLength1 = Number(length1) + const originLength2 = Number(length2) + const originLength3 = Number(length3) + const originLength4 = Number(length4) + let rightBottomDiagonal, rightTopDiagonal + + if ((isRotated && isVerticalAzimuth) || (!isRotated && !isVerticalAzimuth)) { + //가로 선 + length1 = calcLineActualSizeByPlaneSize(length1, degree) + + const e6_h = X * Math.tan((degree * Math.PI) / 180) + const e6_a = Math.sqrt(e6_h ** 2 + X ** 2) + length3 = Math.sqrt(length2 ** 2 + e6_a ** 2) // 빗변 구하기 + + const g6_Y = (originLength2 * (originLength1 / 2)) / X + const g6_Z = originLength2 - g6_Y + const g6_a = Math.sqrt(b2 ** 2 - g6_Z ** 2) + const g6_h = g6_a * Math.tan((degree * Math.PI) / 180) + const g6_b = Math.sqrt(g6_h ** 2 + g6_a ** 2) + rightBottomDiagonal = Math.sqrt(g6_b ** 2 + g6_Z ** 2) + + const f6_Y = (originLength2 * (originLength1 / 2)) / X + const f6_h = (originLength1 / 2) * Math.tan((degree * Math.PI) / 180) + const f6_Z = Math.sqrt(f6_h ** 2 + (originLength1 / 2) ** 2) + rightTopDiagonal = Math.sqrt(f6_Z ** 2 + f6_Y ** 2) + } else { + //세로 선 + length2 = calcLineActualSizeByPlaneSize(length2, degree) + + const a6_h = originLength2 * Math.tan((degree * Math.PI) / 180) + const a6_a = Math.sqrt(a6_h ** 2 + originLength2 ** 2) + length3 = Math.sqrt(a6_a ** 2 + X ** 2) // 빗변 구하기 + + const c6_Y = (originLength2 * (originLength1 / 2)) / X + const c6_Z = originLength2 - c6_Y + const c6_h = c6_Z * Math.tan((degree * Math.PI) / 180) + const c6_b = Math.sqrt(c6_h ** 2 + c6_Z ** 2) + const c6_a = Math.sqrt(b2 ** 2 - c6_Z ** 2) + rightBottomDiagonal = Math.sqrt(c6_a ** 2 + c6_b ** 2) + + const b6_Y = (originLength2 * (originLength1 / 2)) / X + const b6_h = b6_Y * Math.tan((degree * Math.PI) / 180) + const b6_a = Math.sqrt(b6_h ** 2 + b6_Y ** 2) + rightTopDiagonal = Math.sqrt(b6_a ** 2 + (originLength1 / 2) ** 2) + } const a = Math.sqrt(length3 * length3 - length2 * length2) // 입력된 밑변과 높이 const sinA = a / length3 @@ -718,12 +1003,12 @@ export function useSurfaceShapeBatch({ isHidden, setIsHidden }) { { x: pointer.x - (length1 + b) / 2, y: pointer.y + length2 / 2 }, { x: pointer.x + length1 / 2 - b / 2, y: pointer.y + length2 / 2 }, { - x: pointer.x + length1 / 2 - b / 2 + d * Math.cos(newAngleInRadians), - y: pointer.y + length2 / 2 - d * Math.sin(newAngleInRadians), + x: pointer.x + length1 / 2 - b / 2 + rightBottomDiagonal * Math.cos(newAngleInRadians), + y: pointer.y + length2 / 2 - rightBottomDiagonal * Math.sin(newAngleInRadians), }, { - x: pointer.x - (length1 + b) / 2 + length3 * Math.cos(newAngleInRadians), - y: pointer.y + length2 / 2 - length3 * Math.sin(newAngleInRadians), + x: pointer.x + length1 / 2 - b / 2 + rightBottomDiagonal * Math.cos(newAngleInRadians) - rightTopDiagonal * Math.cos(newAngleInRadians), + y: pointer.y + length2 / 2 - rightBottomDiagonal * Math.sin(newAngleInRadians) - rightTopDiagonal * Math.sin(newAngleInRadians), }, ] break diff --git a/src/hooks/useCirCuitTrestle.js b/src/hooks/useCirCuitTrestle.js index 12e1b28b..b40c7576 100644 --- a/src/hooks/useCirCuitTrestle.js +++ b/src/hooks/useCirCuitTrestle.js @@ -10,11 +10,13 @@ import { selectedModelsState, seriesState, } from '@/store/circuitTrestleAtom' -import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions' +import { selectedModuleState } from '@/store/selectedModuleOptions' import { useContext, useEffect } from 'react' import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil' import { useMessage } from './useMessage' import Big from 'big.js' +import { groupPoints } from '@/util/module-utils' +import { basicSettingState } from '@/store/settingAtom' export function useCircuitTrestle(executeEffect = false) { const [makers, setMakers] = useRecoilState(makersState) @@ -28,6 +30,7 @@ export function useCircuitTrestle(executeEffect = false) { const canvas = useRecoilValue(canvasState) const setModuleStatistics = useSetRecoilState(moduleStatisticsState) const resetModuleStatistics = useResetRecoilState(moduleStatisticsState) + const roofSizeSet = useRecoilValue(basicSettingState).roofSizeSet const { getMessage } = useMessage() useEffect(() => { @@ -132,6 +135,8 @@ export function useCircuitTrestle(executeEffect = false) { // 모듈 목록 const getModuleList = (surface) => { + let group = groupPoints(surface.modules, surface, +roofSizeSet) + let moduleList = [] let [xObj, yObj] = [{}, {}] let [xPoints, yPoints] = [[], []] @@ -145,62 +150,65 @@ export function useCircuitTrestle(executeEffect = false) { yPoints.push(module.top) } }) - switch (surface.direction) { - case 'south': - xPoints.sort((a, b) => a - b) - yPoints.sort((a, b) => b - a) - yPoints.forEach((y, index) => { - let temp = surface.modules.filter((m) => m.top === y) - if (index % 2 === 0) { - temp.sort((a, b) => a.left - b.left) - } else { - temp.sort((a, b) => b.left - a.left) - } - moduleList = [...moduleList, ...temp] - }) - break - case 'north': - xPoints.sort((a, b) => b - a) - yPoints.sort((a, b) => a - b) - yPoints.forEach((y, index) => { - let temp = surface.modules.filter((m) => m.top === y) - if (index % 2 === 0) { - temp.sort((a, b) => b.left - a.left) - } else { - temp.sort((a, b) => a.left - b.left) - } - moduleList = [...moduleList, ...temp] - }) - break - case 'west': - xPoints.sort((a, b) => a - b) - yPoints.sort((a, b) => a - b) - xPoints.forEach((x, index) => { - let temp = surface.modules.filter((m) => m.left === x) - if (index % 2 === 0) { - temp.sort((a, b) => a.top - b.top) - } else { - temp.sort((a, b) => b.top - a.top) - } - moduleList = [...moduleList, ...temp] - }) - break - case 'east': - xPoints.sort((a, b) => b - a) - yPoints.sort((a, b) => b - a) - xPoints.forEach((x, index) => { - let temp = surface.modules.filter((m) => m.left === x) - if (index % 2 === 0) { - temp.sort((a, b) => b.top - a.top) - } else { - temp.sort((a, b) => a.top - b.top) - } - moduleList = [...moduleList, ...temp] - }) - break - default: - return [] - } + group.forEach((groupModules) => { + switch (surface.direction) { + case 'south': + xPoints.sort((a, b) => a - b) + yPoints.sort((a, b) => b - a) + yPoints.forEach((y, index) => { + let temp = groupModules.filter((m) => m.top === y) + if (index % 2 === 0) { + temp.sort((a, b) => a.left - b.left) + } else { + temp.sort((a, b) => b.left - a.left) + } + moduleList = [...moduleList, ...temp] + }) + break + case 'north': + xPoints.sort((a, b) => b - a) + yPoints.sort((a, b) => a - b) + yPoints.forEach((y, index) => { + let temp = groupModules.filter((m) => m.top === y) + if (index % 2 === 0) { + temp.sort((a, b) => b.left - a.left) + } else { + temp.sort((a, b) => a.left - b.left) + } + moduleList = [...moduleList, ...temp] + }) + break + case 'west': + xPoints.sort((a, b) => a - b) + yPoints.sort((a, b) => a - b) + xPoints.forEach((x, index) => { + let temp = groupModules.filter((m) => m.left === x) + if (index % 2 === 0) { + temp.sort((a, b) => a.top - b.top) + } else { + temp.sort((a, b) => b.top - a.top) + } + moduleList = [...moduleList, ...temp] + }) + break + case 'east': + xPoints.sort((a, b) => b - a) + yPoints.sort((a, b) => b - a) + xPoints.forEach((x, index) => { + let temp = groupModules.filter((m) => m.left === x) + if (index % 2 === 0) { + temp.sort((a, b) => b.top - a.top) + } else { + temp.sort((a, b) => a.top - b.top) + } + moduleList = [...moduleList, ...temp] + }) + break + default: + return [] + } + }) + return moduleList } diff --git a/src/util/module-utils.js b/src/util/module-utils.js new file mode 100644 index 00000000..7ebd346b --- /dev/null +++ b/src/util/module-utils.js @@ -0,0 +1,174 @@ +export function groupPoints(modules, surface, roofSizeSet) { + const groups = [] + const visited = new Set() + + for (const point of modules) { + const { x: pointX, y: pointY } = point.getCenterPoint() + const key = `${pointX},${pointY}` + if (visited.has(key)) continue + + const queue = [point] + const group = [] + + while (queue.length > 0) { + const current = queue.shift() + const { x: currentX, y: currentY } = current.getCenterPoint() + const currentKey = `${currentX},${currentY}` + if (visited.has(currentKey)) continue + + visited.add(currentKey) + group.push(current) + + for (const neighbor of modules) { + const { x: neighborX, y: neighborY } = neighbor.getCenterPoint() + const neighborKey = `${neighborX},${neighborY}` + if (!visited.has(neighborKey) && areConnected(current, neighbor, surface, roofSizeSet)) { + queue.push(neighbor) + } + } + } + + groups.push(group) + } + + return groups +} + +function areConnected(m1, m2, surface, roofSizeSet) { + /*const m1Fill = m1.fill + const m2Fill = m2.fill + m1.set({ fill: 'red' }) + m2.set({ fill: 'blue' }) + canvas.renderAll()*/ + + let sizes = [] + + const { width: currentWidth, height: currentHeight, moduleInfo: currentModuleInfo } = m1 + const { width: neighborWidth, height: neighborHeight, moduleInfo: neighborModuleInfo } = m2 + + const maxWidth = Math.max(currentWidth, neighborWidth) + const maxHeight = Math.max(currentHeight, neighborHeight) + + const { moduleTpCd: currentModuleTpCd } = currentModuleInfo + const { moduleTpCd: neighborModuleTpCd } = neighborModuleInfo + const { x: m1X, y: m1Y } = m1.getCenterPoint() + const { x: m2X, y: m2Y } = m2.getCenterPoint() + + sizes.push({ width: currentWidth, height: currentHeight }) + + if (currentModuleTpCd !== neighborModuleTpCd) { + sizes.push({ width: neighborWidth, height: neighborHeight }) + } + + /*m1.set({ fill: m1Fill }) + m2.set({ fill: m2Fill }) + canvas.renderAll()*/ + + return sizes.some(({ width, height }) => { + let maxX + let maxY + let halfMaxX + let halfMaxY + const { direction, trestleDetail } = surface + let moduleIntvlHor, moduleIntvlVer + if (+roofSizeSet === 3) { + //육지붕의 경우 값 고정 + moduleIntvlHor = 300 + moduleIntvlVer = 100 + } else { + moduleIntvlHor = trestleDetail.moduleIntvlHor + moduleIntvlVer = trestleDetail.moduleIntvlVer + } + + if (direction === 'south' || direction === 'north') { + maxX = width + moduleIntvlHor / 10 + maxY = height + moduleIntvlVer / 10 + halfMaxX = moduleIntvlHor / 10 + halfMaxY = moduleIntvlVer / 10 + + const leftTopPoint = { x: m1X - width - moduleIntvlHor / 10, y: m1Y - height - moduleIntvlVer / 10 } + const rightTopPoint = { x: m1X + width + moduleIntvlHor / 10, y: m1Y - height - moduleIntvlVer / 10 } + const leftBottomPoint = { x: m1X - width - moduleIntvlHor / 10, y: m1Y + height + moduleIntvlVer / 10 } + const rightBottomPoint = { x: m1X + width + moduleIntvlHor / 10, y: m1Y + height + moduleIntvlVer / 10 } + // {x: m2X, y: m2Y} 가 leftTopPoint, rightTopPoint, leftBottomPoint, rightBottomPoint 내부에 있는지 확인한다. + if ( + isPointInRect( + { + x: leftTopPoint.x, + y: leftTopPoint.y, + width: Math.abs(rightTopPoint.x - leftTopPoint.x), + height: Math.abs(leftTopPoint.y - leftBottomPoint.y), + }, + { x: m2X, y: m2Y }, + ) + ) { + return true + } + if (currentModuleTpCd !== neighborModuleTpCd) { + maxX = currentWidth / 2 + neighborWidth / 2 + moduleIntvlHor / 10 + maxY = currentHeight / 2 + neighborHeight / 2 + moduleIntvlVer / 10 + } + + // console.log(maxX, maxY, halfMaxX, halfMaxY) + + if (Math.abs(m1X - m2X) < 1) { + return Math.abs(Math.abs(m1Y - m2Y) - maxY) < 1 || Math.abs(m2Y - m1Y) <= halfMaxY + } else if (Math.abs(m1Y - m2Y) < 1) { + return Math.abs(Math.abs(m1X - m2X) - maxX) < 1 || Math.abs(m2X - m1X) <= halfMaxX + } + + return ( + (Math.abs(m1X - m2X) < maxX - moduleIntvlHor / 10 + 1 && Math.abs(m1Y - m2Y) < maxY - moduleIntvlVer / 10) || + (Math.abs(Math.abs(m1X - m2X) - maxX / 2) < halfMaxX + 1 && Math.abs(Math.abs(m1Y - m2Y) - maxY) < halfMaxY + 1) || + (Math.abs(Math.abs(m1X - m2X) - maxX) < halfMaxX + 1 && Math.abs(Math.abs(m1Y - m2Y) - maxY / 2) < halfMaxY + 1) + ) + } else if (direction === 'east' || direction === 'west') { + maxX = height + moduleIntvlHor / 10 + maxY = width + moduleIntvlVer / 10 + halfMaxX = moduleIntvlVer / 10 + halfMaxY = moduleIntvlHor / 10 + + // 모듈을 기준으로 왼쪽 상, 오른쪽 상, 왼쪽 하, 오른쪽 하의 각 포인트를 계산 + const leftTopPoint = { x: m1X - width - moduleIntvlVer / 10, y: m1Y + height + moduleIntvlHor / 10 } + const rightTopPoint = { x: m1X - width - moduleIntvlVer / 10, y: m1Y - height - moduleIntvlHor / 10 } + const leftBottomPoint = { x: m1X + width + moduleIntvlVer / 10, y: m1Y + height + moduleIntvlHor / 10 } + const rightBottomPoint = { x: m1X + width + +moduleIntvlVer / 10, y: m1Y - height - moduleIntvlHor / 10 } + + // {x: m2X, y: m2Y} 가 leftTopPoint, rightTopPoint, leftBottomPoint, rightBottomPoint 내부에 있는지 확인한다. + if ( + isPointInRect( + { + x: rightTopPoint.x, + y: rightTopPoint.y, + width: Math.abs(rightBottomPoint.x - rightTopPoint.x), + height: Math.abs(leftTopPoint.y - rightTopPoint.y), + }, + { x: m2X, y: m2Y }, + ) + ) { + return true + } + + if (currentModuleTpCd !== neighborModuleTpCd) { + maxX = currentHeight / 2 + neighborHeight / 2 + moduleIntvlVer / 10 + maxY = currentWidth / 2 + neighborWidth / 2 + moduleIntvlHor / 10 + } + + if (Math.abs(m1X - m2X) < 1) { + return Math.abs(Math.abs(m1Y - m2Y) - maxX) < 1 || Math.abs(m2Y - m1Y) <= halfMaxY + } else if (Math.abs(m1Y - m2Y) < 1) { + return Math.abs(Math.abs(m1X - m2X) - maxY) < 1 || Math.abs(m2X - m1X) <= halfMaxX + } + + return ( + (Math.abs(m1X - m2X) <= maxY - moduleIntvlVer / 10 && Math.abs(m1Y - m2Y) <= maxX - moduleIntvlHor / 10) || + (Math.abs(Math.abs(m1X - m2X) - maxY / 2) < halfMaxY + 1 && Math.abs(Math.abs(m1Y - m2Y) - maxX) < halfMaxX + 1) || + (Math.abs(Math.abs(m1X - m2X) - maxY) < halfMaxY + 1 && Math.abs(Math.abs(m1Y - m2Y) - maxX / 2) < halfMaxX + 1) + ) + } + }) +} + +function isPointInRect(rect, point) { + return point.x >= rect.x && point.x <= rect.x + rect.width && point.y >= rect.y && point.y <= rect.y + rect.height +} diff --git a/src/util/qpolygon-utils.js b/src/util/qpolygon-utils.js index 482693dc..b6ce68c0 100644 --- a/src/util/qpolygon-utils.js +++ b/src/util/qpolygon-utils.js @@ -1324,18 +1324,60 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { const secondHipLine = drawHipLine(secondHipPoint, canvas, roof, textMode, null, degree, degree) const secondRoofLine = drawHipLine(secondRoofPoint, canvas, roof, textMode, null, nextDegree, nextDegree) const connectHipLine = drawRoofLine(connectHipPoint, canvas, roof, textMode) - baseHipLines.push({ x1: firstHipLine.x1, y1: firstHipLine.y1, x2: firstHipLine.x2, y2: firstHipLine.y2, line: firstHipLine }) - baseHipLines.push({ x1: firstRoofLine.x1, y1: firstRoofLine.y1, x2: firstRoofLine.x2, y2: firstRoofLine.y2, line: firstRoofLine }) - baseHipLines.push({ x1: secondHipLine.x1, y1: secondHipLine.y1, x2: secondHipLine.x2, y2: secondHipLine.y2, line: secondHipLine }) - baseHipLines.push({ x1: secondRoofLine.x1, y1: secondRoofLine.y1, x2: secondRoofLine.x2, y2: secondRoofLine.y2, line: secondRoofLine }) - baseHipLines.push({ x1: connectHipLine.x1, y1: connectHipLine.y1, x2: connectHipLine.x2, y2: connectHipLine.y2, line: connectHipLine }) + baseHipLines.push({ + x1: firstHipLine.x1, + y1: firstHipLine.y1, + x2: firstHipLine.x2, + y2: firstHipLine.y2, + line: firstHipLine, + }) + baseHipLines.push({ + x1: firstRoofLine.x1, + y1: firstRoofLine.y1, + x2: firstRoofLine.x2, + y2: firstRoofLine.y2, + line: firstRoofLine, + }) + baseHipLines.push({ + x1: secondHipLine.x1, + y1: secondHipLine.y1, + x2: secondHipLine.x2, + y2: secondHipLine.y2, + line: secondHipLine, + }) + baseHipLines.push({ + x1: secondRoofLine.x1, + y1: secondRoofLine.y1, + x2: secondRoofLine.x2, + y2: secondRoofLine.y2, + line: secondRoofLine, + }) + baseHipLines.push({ + x1: connectHipLine.x1, + y1: connectHipLine.y1, + x2: connectHipLine.x2, + y2: connectHipLine.y2, + line: connectHipLine, + }) } else { const firstHipPoint = [currentRoof.x1, currentRoof.y1, currentMidX.toNumber(), currentMidY.toNumber()] const secondHipPoint = [currentRoof.x2, currentRoof.y2, currentMidX.toNumber(), currentMidY.toNumber()] const firstHipLine = drawHipLine(firstHipPoint, canvas, roof, textMode, null, prevDegree, prevDegree) const secondHipLine = drawHipLine(secondHipPoint, canvas, roof, textMode, null, nextDegree, nextDegree) - baseHipLines.push({ x1: firstHipLine.x1, y1: firstHipLine.y1, x2: firstHipLine.x2, y2: firstHipLine.y2, line: firstHipLine }) - baseHipLines.push({ x1: secondHipLine.x1, y1: secondHipLine.y1, x2: secondHipLine.x2, y2: secondHipLine.y2, line: secondHipLine }) + baseHipLines.push({ + x1: firstHipLine.x1, + y1: firstHipLine.y1, + x2: firstHipLine.x2, + y2: firstHipLine.y2, + line: firstHipLine, + }) + baseHipLines.push({ + x1: secondHipLine.x1, + y1: secondHipLine.y1, + x2: secondHipLine.x2, + y2: secondHipLine.y2, + line: secondHipLine, + }) } if (baseRidgeCount < getMaxRidge(baseLines.length)) { @@ -1599,18 +1641,60 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { const secondHipLine = drawHipLine(secondHipPoint, canvas, roof, textMode, null, degree, degree) const secondRoofLine = drawHipLine(secondRoofPoint, canvas, roof, textMode, null, nextDegree, nextDegree) const connectHipLine = drawRoofLine(connectHipPoint, canvas, roof, textMode) - baseHipLines.push({ x1: firstHipLine.x1, y1: firstHipLine.y1, x2: firstHipLine.x2, y2: firstHipLine.y2, line: firstHipLine }) - baseHipLines.push({ x1: firstRoofLine.x1, y1: firstRoofLine.y1, x2: firstRoofLine.x2, y2: firstRoofLine.y2, line: firstRoofLine }) - baseHipLines.push({ x1: secondHipLine.x1, y1: secondHipLine.y1, x2: secondHipLine.x2, y2: secondHipLine.y2, line: secondHipLine }) - baseHipLines.push({ x1: secondRoofLine.x1, y1: secondRoofLine.y1, x2: secondRoofLine.x2, y2: secondRoofLine.y2, line: secondRoofLine }) - baseHipLines.push({ x1: connectHipLine.x1, y1: connectHipLine.y1, x2: connectHipLine.x2, y2: connectHipLine.y2, line: connectHipLine }) + baseHipLines.push({ + x1: firstHipLine.x1, + y1: firstHipLine.y1, + x2: firstHipLine.x2, + y2: firstHipLine.y2, + line: firstHipLine, + }) + baseHipLines.push({ + x1: firstRoofLine.x1, + y1: firstRoofLine.y1, + x2: firstRoofLine.x2, + y2: firstRoofLine.y2, + line: firstRoofLine, + }) + baseHipLines.push({ + x1: secondHipLine.x1, + y1: secondHipLine.y1, + x2: secondHipLine.x2, + y2: secondHipLine.y2, + line: secondHipLine, + }) + baseHipLines.push({ + x1: secondRoofLine.x1, + y1: secondRoofLine.y1, + x2: secondRoofLine.x2, + y2: secondRoofLine.y2, + line: secondRoofLine, + }) + baseHipLines.push({ + x1: connectHipLine.x1, + y1: connectHipLine.y1, + x2: connectHipLine.x2, + y2: connectHipLine.y2, + line: connectHipLine, + }) } else { const firstHipPoint = [currentRoof.x1, currentRoof.y1, currentMidX.toNumber(), currentMidY.toNumber()] const secondHipPoint = [currentRoof.x2, currentRoof.y2, currentMidX.toNumber(), currentMidY.toNumber()] const firstHipLine = drawHipLine(firstHipPoint, canvas, roof, textMode, null, prevDegree, prevDegree) const secondHipLine = drawHipLine(secondHipPoint, canvas, roof, textMode, null, nextDegree, nextDegree) - baseHipLines.push({ x1: firstHipLine.x1, y1: firstHipLine.y1, x2: firstHipLine.x2, y2: firstHipLine.y2, line: firstHipLine }) - baseHipLines.push({ x1: secondHipLine.x1, y1: secondHipLine.y1, x2: secondHipLine.x2, y2: secondHipLine.y2, line: secondHipLine }) + baseHipLines.push({ + x1: firstHipLine.x1, + y1: firstHipLine.y1, + x2: firstHipLine.x2, + y2: firstHipLine.y2, + line: firstHipLine, + }) + baseHipLines.push({ + x1: secondHipLine.x1, + y1: secondHipLine.y1, + x2: secondHipLine.x2, + y2: secondHipLine.y2, + line: secondHipLine, + }) } if (baseRidgeCount < getMaxRidge(baseLines.length)) { @@ -2129,18 +2213,60 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { const secondHipLine = drawHipLine(secondHipPoint, canvas, roof, textMode, null, degree, degree) const secondRoofLine = drawHipLine(secondRoofPoint, canvas, roof, textMode, null, nextDegree, nextDegree) const connectHipLine = drawRoofLine(connectHipPoint, canvas, roof, textMode) - baseHipLines.push({ x1: firstHipLine.x1, y1: firstHipLine.y1, x2: firstHipLine.x2, y2: firstHipLine.y2, line: firstHipLine }) - baseHipLines.push({ x1: firstRoofLine.x1, y1: firstRoofLine.y1, x2: firstRoofLine.x2, y2: firstRoofLine.y2, line: firstRoofLine }) - baseHipLines.push({ x1: secondHipLine.x1, y1: secondHipLine.y1, x2: secondHipLine.x2, y2: secondHipLine.y2, line: secondHipLine }) - baseHipLines.push({ x1: secondRoofLine.x1, y1: secondRoofLine.y1, x2: secondRoofLine.x2, y2: secondRoofLine.y2, line: secondRoofLine }) - baseHipLines.push({ x1: connectHipLine.x1, y1: connectHipLine.y1, x2: connectHipLine.x2, y2: connectHipLine.y2, line: connectHipLine }) + baseHipLines.push({ + x1: firstHipLine.x1, + y1: firstHipLine.y1, + x2: firstHipLine.x2, + y2: firstHipLine.y2, + line: firstHipLine, + }) + baseHipLines.push({ + x1: firstRoofLine.x1, + y1: firstRoofLine.y1, + x2: firstRoofLine.x2, + y2: firstRoofLine.y2, + line: firstRoofLine, + }) + baseHipLines.push({ + x1: secondHipLine.x1, + y1: secondHipLine.y1, + x2: secondHipLine.x2, + y2: secondHipLine.y2, + line: secondHipLine, + }) + baseHipLines.push({ + x1: secondRoofLine.x1, + y1: secondRoofLine.y1, + x2: secondRoofLine.x2, + y2: secondRoofLine.y2, + line: secondRoofLine, + }) + baseHipLines.push({ + x1: connectHipLine.x1, + y1: connectHipLine.y1, + x2: connectHipLine.x2, + y2: connectHipLine.y2, + line: connectHipLine, + }) } else { const firstHipPoint = [currentRoof.x1, currentRoof.y1, currentMidX.toNumber(), currentMidY.toNumber()] const secondHipPoint = [currentRoof.x2, currentRoof.y2, currentMidX.toNumber(), currentMidY.toNumber()] const firstHipLine = drawHipLine(firstHipPoint, canvas, roof, textMode, null, prevDegree, prevDegree) const secondHipLine = drawHipLine(secondHipPoint, canvas, roof, textMode, null, nextDegree, nextDegree) - baseHipLines.push({ x1: firstHipLine.x1, y1: firstHipLine.y1, x2: firstHipLine.x2, y2: firstHipLine.y2, line: firstHipLine }) - baseHipLines.push({ x1: secondHipLine.x1, y1: secondHipLine.y1, x2: secondHipLine.x2, y2: secondHipLine.y2, line: secondHipLine }) + baseHipLines.push({ + x1: firstHipLine.x1, + y1: firstHipLine.y1, + x2: firstHipLine.x2, + y2: firstHipLine.y2, + line: firstHipLine, + }) + baseHipLines.push({ + x1: secondHipLine.x1, + y1: secondHipLine.y1, + x2: secondHipLine.x2, + y2: secondHipLine.y2, + line: secondHipLine, + }) } /** 마루가 맞은편 외벽선에 닿는 경우 해당 부분까지로 한정한다. */ @@ -2902,7 +3028,11 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { if ( (!isPointOnLineNew(prevRoof, { x: ridgeLine.x1, y: ridgeLine.y1 }) && !isPointOnLineNew(nextRoof, { x: ridgeLine.x1, y: ridgeLine.y1 })) || - (!isPointOnLineNew(prevRoof, { x: ridgeLine.x2, y: ridgeLine.y2 }) && !isPointOnLineNew(nextRoof, { x: ridgeLine.x2, y: ridgeLine.y2 })) + (!isPointOnLineNew(prevRoof, { + x: ridgeLine.x2, + y: ridgeLine.y2, + }) && + !isPointOnLineNew(nextRoof, { x: ridgeLine.x2, y: ridgeLine.y2 })) ) { roof.lines .filter((line) => line !== currentRoof && line !== prevRoof && line !== nextRoof) @@ -2971,7 +3101,13 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { polygonPoints.push({ x: minX, y: prevLineRidge.y1 }, { x: maxX, y: prevLineRidge.y1 }) } } else if (prevDistance < nextDistance) { - polygonPoints.push({ x: nextLineRidge.x1, y: nextLineRidge.y1 }, { x: nextLineRidge.x2, y: nextLineRidge.y2 }) + polygonPoints.push( + { x: nextLineRidge.x1, y: nextLineRidge.y1 }, + { + x: nextLineRidge.x2, + y: nextLineRidge.y2, + }, + ) /** 이전라인과 교차한 마루의 포인트*/ let prevRidgePoint1 @@ -2997,7 +3133,13 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { let checkRidgePoint if (nextLine.attributes.type === LINE_TYPE.WALLLINE.JERKINHEAD) { const ridgePoint1 = polygonPoints.filter((point) => point.x === nextLineRidge.x1 && point.y === nextLineRidge.y1) - checkRidgePoint = ridgePoint1.length > 0 ? { x: nextLineRidge.x2, y: nextLineRidge.y2 } : { x: nextLineRidge.x1, y: nextLineRidge.y1 } + checkRidgePoint = + ridgePoint1.length > 0 + ? { + x: nextLineRidge.x2, + y: nextLineRidge.y2, + } + : { x: nextLineRidge.x1, y: nextLineRidge.y1 } } else { checkRidgePoint = currentVectorX === 0 @@ -3010,10 +3152,21 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { } const prevRidgePoint2 = - currentVectorX === 0 ? { x: prevRidgePoint1.x, y: checkRidgePoint.y } : { x: checkRidgePoint.x, y: prevRidgePoint1.y } + currentVectorX === 0 + ? { x: prevRidgePoint1.x, y: checkRidgePoint.y } + : { + x: checkRidgePoint.x, + y: prevRidgePoint1.y, + } polygonPoints.push(prevRidgePoint2) } else { - polygonPoints.push({ x: prevLineRidge.x1, y: prevLineRidge.y1 }, { x: prevLineRidge.x2, y: prevLineRidge.y2 }) + polygonPoints.push( + { x: prevLineRidge.x1, y: prevLineRidge.y1 }, + { + x: prevLineRidge.x2, + y: prevLineRidge.y2, + }, + ) /** 다음라인과 교차한 마루의 포인트*/ let nextRidgePoint1 @@ -3038,7 +3191,13 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { let checkRidgePoint if (prevLine.attributes.type === LINE_TYPE.WALLLINE.JERKINHEAD) { const ridgePoint1 = polygonPoints.filter((point) => point.x === prevLineRidge.x1 && point.y === prevLineRidge.y1) - checkRidgePoint = ridgePoint1.length > 0 ? { x: prevLineRidge.x2, y: prevLineRidge.y2 } : { x: prevLineRidge.x1, y: prevLineRidge.y1 } + checkRidgePoint = + ridgePoint1.length > 0 + ? { + x: prevLineRidge.x2, + y: prevLineRidge.y2, + } + : { x: prevLineRidge.x1, y: prevLineRidge.y1 } } else { checkRidgePoint = currentVectorX === 0 @@ -3051,7 +3210,12 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { } const nextRidgePoint2 = - currentVectorX === 0 ? { x: nextRidgePoint1.x, y: checkRidgePoint.y } : { x: checkRidgePoint.x, y: nextRidgePoint1.y } + currentVectorX === 0 + ? { x: nextRidgePoint1.x, y: checkRidgePoint.y } + : { + x: checkRidgePoint.x, + y: nextRidgePoint1.y, + } polygonPoints.push(nextRidgePoint2) } } else { @@ -3179,9 +3343,18 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { } } else { if (ridgeLine) { - const ridgeEdge = { vertex1: { x: ridgeLine.x1, y: ridgeLine.y1 }, vertex2: { x: ridgeLine.x2, y: ridgeLine.y2 } } - const prevRoofEdge = { vertex1: { x: prevRoof.x1, y: prevRoof.y1 }, vertex2: { x: prevRoof.x2, y: prevRoof.y2 } } - const nextRoofEdge = { vertex1: { x: nextRoof.x1, y: nextRoof.y1 }, vertex2: { x: nextRoof.x2, y: nextRoof.y2 } } + const ridgeEdge = { + vertex1: { x: ridgeLine.x1, y: ridgeLine.y1 }, + vertex2: { x: ridgeLine.x2, y: ridgeLine.y2 }, + } + const prevRoofEdge = { + vertex1: { x: prevRoof.x1, y: prevRoof.y1 }, + vertex2: { x: prevRoof.x2, y: prevRoof.y2 }, + } + const nextRoofEdge = { + vertex1: { x: nextRoof.x1, y: nextRoof.y1 }, + vertex2: { x: nextRoof.x2, y: nextRoof.y2 }, + } const isPrevRoof = edgesIntersection(prevRoofEdge, ridgeEdge) const isNextRoof = edgesIntersection(nextRoofEdge, ridgeEdge) if (isPrevRoof && isPointOnLine(ridgeLine, isPrevRoof)) { @@ -3568,7 +3741,10 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { { x: currentRidge.x1, y: currentRidge.y1, checkPoint: true }, { x: currentRidge.x2, y: currentRidge.y2, checkPoint: true }, ] - const ridgeEdge = { vertex1: { x: currentRidge.x1, y: currentRidge.y1 }, vertex2: { x: currentRidge.x2, y: currentRidge.y2 } } + const ridgeEdge = { + vertex1: { x: currentRidge.x1, y: currentRidge.y1 }, + vertex2: { x: currentRidge.x2, y: currentRidge.y2 }, + } /** 포인트가 지붕선과 붙은 경우 */ roof.lines.forEach((line) => { const lineEdge = { vertex1: { x: line.x1, y: line.y1 }, vertex2: { x: line.x2, y: line.y2 } } @@ -3616,7 +3792,10 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { vertex2: { x: checkRidgePoint.x, y: currentRoof.y1 }, } } - const currentRoofEdge = { vertex1: { x: currentRoof.x1, y: currentRoof.y1 }, vertex2: { x: currentRoof.x2, y: currentRoof.y2 } } + const currentRoofEdge = { + vertex1: { x: currentRoof.x1, y: currentRoof.y1 }, + vertex2: { x: currentRoof.x2, y: currentRoof.y2 }, + } const isRoofPoint = edgesIntersection(checkEdge, currentRoofEdge) if (isRoofPoint) { @@ -4054,8 +4233,20 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { const prevGableLine = drawHipLine(prevGablePoint, canvas, roof, textMode, null, prevDegree, currentDegree) const nextGableLine = drawHipLine(nextGablePoint, canvas, roof, textMode, null, currentDegree, nextDegree) - baseHipLines.push({ x1: prevGableLine.x1, y1: prevGableLine.y1, x2: prevGableLine.x2, y2: prevGableLine.y2, line: prevGableLine }) - baseHipLines.push({ x1: nextGableLine.x1, y1: nextGableLine.y1, x2: nextGableLine.x2, y2: nextGableLine.y2, line: nextGableLine }) + baseHipLines.push({ + x1: prevGableLine.x1, + y1: prevGableLine.y1, + x2: prevGableLine.x2, + y2: prevGableLine.y2, + line: prevGableLine, + }) + baseHipLines.push({ + x1: nextGableLine.x1, + y1: nextGableLine.y1, + x2: nextGableLine.x2, + y2: nextGableLine.y2, + line: nextGableLine, + }) let oppositeLine baseLines @@ -4074,7 +4265,10 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { vertex2: { x: midX, y: oppCurrLine.y1 }, } } - const lineEdge = { vertex1: { x: oppCurrLine.x1, y: oppCurrLine.y1 }, vertex2: { x: oppCurrLine.x2, y: oppCurrLine.y2 } } + const lineEdge = { + vertex1: { x: oppCurrLine.x1, y: oppCurrLine.y1 }, + vertex2: { x: oppCurrLine.x2, y: oppCurrLine.y2 }, + } const intersection = edgesIntersection(checkEdge, lineEdge) if (intersection && isPointOnLine(oppCurrLine, intersection)) { const size = @@ -4394,7 +4588,10 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { vertex2: { x: currentMidX, y: oppCurrLine.y1 }, } } - const lineEdge = { vertex1: { x: oppCurrLine.x1, y: oppCurrLine.y1 }, vertex2: { x: oppCurrLine.x2, y: oppCurrLine.y2 } } + const lineEdge = { + vertex1: { x: oppCurrLine.x1, y: oppCurrLine.y1 }, + vertex2: { x: oppCurrLine.x2, y: oppCurrLine.y2 }, + } const intersection = edgesIntersection(checkEdge, lineEdge) if (intersection && isPointOnLine(oppCurrLine, intersection)) { const size = @@ -4469,7 +4666,10 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { } if (oppRoofLine) { - const ridgeEdge = { vertex1: { x: currentMidX, y: currentMidY }, vertex2: { x: intersection.x, y: intersection.y } } + const ridgeEdge = { + vertex1: { x: currentMidX, y: currentMidY }, + vertex2: { x: intersection.x, y: intersection.y }, + } if (oppCurrLine.attributes.type === LINE_TYPE.WALLLINE.EAVES) { const oppRoofSize = Big(oppRoofLine.attributes.planeSize).div(20) @@ -4594,7 +4794,10 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { drawBaseLines .filter((base) => base !== currentBaseLine && base !== prevBaseLine && base !== beforePrevLine) .forEach((base) => { - const lineEdge = { vertex1: { x: base.line.x1, y: base.line.y1 }, vertex2: { x: base.line.x2, y: base.line.y2 } } + const lineEdge = { + vertex1: { x: base.line.x1, y: base.line.y1 }, + vertex2: { x: base.line.x2, y: base.line.y2 }, + } const intersection = edgesIntersection(hipEdge, lineEdge) if (intersection && isPointOnLine(base.line, intersection)) { const size = Big(intersection.x) @@ -4658,7 +4861,10 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { drawBaseLines .filter((base) => base !== currentBaseLine && base !== nextBaseLine && base !== afterNextLine) .forEach((base) => { - const lineEdge = { vertex1: { x: base.line.x1, y: base.line.y1 }, vertex2: { x: base.line.x2, y: base.line.y2 } } + const lineEdge = { + vertex1: { x: base.line.x1, y: base.line.y1 }, + vertex2: { x: base.line.x2, y: base.line.y2 }, + } const intersection = edgesIntersection(hipEdge, lineEdge) if (intersection && isPointOnLine(base.line, intersection)) { const size = Big(intersection.x) @@ -4708,7 +4914,10 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { /** 포인트가 지붕밖에 있는 경우 조정*/ if (!roof.inPolygon({ x: ridgePoint.x1, y: ridgePoint.y1 })) { - const checkEdge = { vertex1: { x: ridgePoint.x2, y: ridgePoint.y2 }, vertex2: { x: ridgePoint.x1, y: ridgePoint.y1 } } + const checkEdge = { + vertex1: { x: ridgePoint.x2, y: ridgePoint.y2 }, + vertex2: { x: ridgePoint.x1, y: ridgePoint.y1 }, + } const isPoints = [] roof.lines.forEach((line) => { const lineEdge = { vertex1: { x: line.x1, y: line.y1 }, vertex2: { x: line.x2, y: line.y2 } } @@ -4737,7 +4946,10 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { } if (!roof.inPolygon({ x: ridgePoint.x2, y: ridgePoint.y2 })) { - const checkEdge = { vertex1: { x: ridgePoint.x1, y: ridgePoint.y1 }, vertex2: { x: ridgePoint.x2, y: ridgePoint.y2 } } + const checkEdge = { + vertex1: { x: ridgePoint.x1, y: ridgePoint.y1 }, + vertex2: { x: ridgePoint.x2, y: ridgePoint.y2 }, + } const isPoints = [] roof.lines.forEach((line) => { const lineEdge = { vertex1: { x: line.x1, y: line.y1 }, vertex2: { x: line.x2, y: line.y2 } } @@ -4822,8 +5034,20 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { const prevHipLine = drawHipLine(prevHipPoint, canvas, roof, textMode, null, prevDegree, prevDegree) const nextHipLine = drawHipLine(nextHipPoint, canvas, roof, textMode, null, nextDegree, nextDegree) - baseHipLines.push({ x1: prevHipLine.x1, y1: prevHipLine.y1, x2: prevHipLine.x2, y2: prevHipLine.y2, line: prevHipLine }) - baseHipLines.push({ x1: nextHipLine.x1, y1: nextHipLine.y1, x2: nextHipLine.x2, y2: nextHipLine.y2, line: nextHipLine }) + baseHipLines.push({ + x1: prevHipLine.x1, + y1: prevHipLine.y1, + x2: prevHipLine.x2, + y2: prevHipLine.y2, + line: prevHipLine, + }) + baseHipLines.push({ + x1: nextHipLine.x1, + y1: nextHipLine.y1, + x2: nextHipLine.x2, + y2: nextHipLine.y2, + line: nextHipLine, + }) } }) @@ -5138,7 +5362,10 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { } if (!roof.inPolygon({ x: prevEndPoint.x.toNumber(), y: prevEndPoint.y.toNumber() })) { - const checkEdge = { vertex1: { x: prevEndPoint.x.toNumber(), y: prevEndPoint.y.toNumber() }, vertex2: { x: x1, y: y1 } } + const checkEdge = { + vertex1: { x: prevEndPoint.x.toNumber(), y: prevEndPoint.y.toNumber() }, + vertex2: { x: x1, y: y1 }, + } const intersectionPoints = [] roof.lines.forEach((line) => { const lineEdge = { vertex1: { x: line.x1, y: line.y1 }, vertex2: { x: line.x2, y: line.y2 } } @@ -5161,19 +5388,51 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { } const overlapLine = baseHipLines.find( (line) => - isPointOnLineNew({ x1: x1, y1: y1, x2: prevEndPoint.x.toNumber(), y2: prevEndPoint.y.toNumber() }, { x: line.x1, y: line.y1 }) || - isPointOnLineNew({ x1: x1, y1: y1, x2: prevEndPoint.x.toNumber(), y2: prevEndPoint.y.toNumber() }, { x: line.x2, y: line.y2 }), + isPointOnLineNew( + { + x1: x1, + y1: y1, + x2: prevEndPoint.x.toNumber(), + y2: prevEndPoint.y.toNumber(), + }, + { x: line.x1, y: line.y1 }, + ) || + isPointOnLineNew( + { + x1: x1, + y1: y1, + x2: prevEndPoint.x.toNumber(), + y2: prevEndPoint.y.toNumber(), + }, + { x: line.x2, y: line.y2 }, + ), ) if (overlapLine) { let size1, size2 if ( - isPointOnLineNew({ x1: x1, y1: y1, x2: prevEndPoint.x.toNumber(), y2: prevEndPoint.y.toNumber() }, { x: overlapLine.x1, y: overlapLine.y1 }) + isPointOnLineNew( + { + x1: x1, + y1: y1, + x2: prevEndPoint.x.toNumber(), + y2: prevEndPoint.y.toNumber(), + }, + { x: overlapLine.x1, y: overlapLine.y1 }, + ) ) { size1 = Math.sqrt(Math.pow(x1 - overlapLine.x1, 2) + Math.pow(y1 - overlapLine.y1, 2)) } if ( - isPointOnLineNew({ x1: x1, y1: y1, x2: prevEndPoint.x.toNumber(), y2: prevEndPoint.y.toNumber() }, { x: overlapLine.x2, y: overlapLine.y2 }) + isPointOnLineNew( + { + x1: x1, + y1: y1, + x2: prevEndPoint.x.toNumber(), + y2: prevEndPoint.y.toNumber(), + }, + { x: overlapLine.x2, y: overlapLine.y2 }, + ) ) { size2 = Math.sqrt(Math.pow(x1 - overlapLine.x2, 2) + Math.pow(y1 - overlapLine.y2, 2)) } @@ -5283,7 +5542,10 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { } if (!roof.inPolygon({ x: nextEndPoint.x.toNumber(), y: nextEndPoint.y.toNumber() })) { - const checkEdge = { vertex1: { x: nextEndPoint.x.toNumber(), y: nextEndPoint.y.toNumber() }, vertex2: { x: x2, y: y2 } } + const checkEdge = { + vertex1: { x: nextEndPoint.x.toNumber(), y: nextEndPoint.y.toNumber() }, + vertex2: { x: x2, y: y2 }, + } const intersectionPoints = [] roof.lines.forEach((line) => { const lineEdge = { vertex1: { x: line.x1, y: line.y1 }, vertex2: { x: line.x2, y: line.y2 } } @@ -5308,18 +5570,50 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { // const overlapLine = baseHipLines.find((line) => isPointOnLine(line, { x: nextEndPoint.x.toNumber(), y: nextEndPoint.y.toNumber() })) const overlapLine = baseHipLines.find( (line) => - isPointOnLineNew({ x1: x2, y1: y2, x2: nextEndPoint.x.toNumber(), y2: nextEndPoint.y.toNumber() }, { x: line.x1, y: line.y1 }) || - isPointOnLineNew({ x1: x2, y1: y2, x2: nextEndPoint.x.toNumber(), y2: nextEndPoint.y.toNumber() }, { x: line.x2, y: line.y2 }), + isPointOnLineNew( + { + x1: x2, + y1: y2, + x2: nextEndPoint.x.toNumber(), + y2: nextEndPoint.y.toNumber(), + }, + { x: line.x1, y: line.y1 }, + ) || + isPointOnLineNew( + { + x1: x2, + y1: y2, + x2: nextEndPoint.x.toNumber(), + y2: nextEndPoint.y.toNumber(), + }, + { x: line.x2, y: line.y2 }, + ), ) if (overlapLine) { let size1, size2 if ( - isPointOnLineNew({ x1: x2, y1: y2, x2: nextEndPoint.x.toNumber(), y2: nextEndPoint.y.toNumber() }, { x: overlapLine.x1, y: overlapLine.y1 }) + isPointOnLineNew( + { + x1: x2, + y1: y2, + x2: nextEndPoint.x.toNumber(), + y2: nextEndPoint.y.toNumber(), + }, + { x: overlapLine.x1, y: overlapLine.y1 }, + ) ) { size1 = Math.sqrt(Math.pow(x2 - overlapLine.x1, 2) + Math.pow(y2 - overlapLine.y1, 2)) } if ( - isPointOnLineNew({ x1: x2, y1: y2, x2: nextEndPoint.x.toNumber(), y2: nextEndPoint.y.toNumber() }, { x: overlapLine.x2, y: overlapLine.y2 }) + isPointOnLineNew( + { + x1: x2, + y1: y2, + x2: nextEndPoint.x.toNumber(), + y2: nextEndPoint.y.toNumber(), + }, + { x: overlapLine.x2, y: overlapLine.y2 }, + ) ) { size2 = Math.sqrt(Math.pow(x2 - overlapLine.x2, 2) + Math.pow(y2 - overlapLine.y2, 2)) } @@ -5500,7 +5794,10 @@ export const drawRidgeRoof = (roofId, canvas, textMode) => { } else if (beforePrevLine.line.attributes.type === LINE_TYPE.WALLLINE.HIPANDGABLE) { width = beforePrevLine.line.attributes.width } - const checkEdge = { vertex1: { x: startPoint.x, y: startPoint.y }, vertex2: { x: oppositeMidX.toNumber(), y: oppositeMidY.toNumber() } } + const checkEdge = { + vertex1: { x: startPoint.x, y: startPoint.y }, + vertex2: { x: oppositeMidX.toNumber(), y: oppositeMidY.toNumber() }, + } const vectorX = Math.sign(startPoint.x - oppositeMidX.toNumber()) const vectorY = Math.sign(startPoint.y - oppositeMidY.toNumber()) const oppositeRoofPoints = [] @@ -8211,6 +8508,17 @@ export const calcLineActualSize = (points, degree = 0) => { return Big(planeSize).div(theta).round().toNumber() } +/** + * 실제 사이즈를 이용하여 기울기가 적용된 선의 길이를 구한다. + * @param planeSize + * @param degree + * @returns number + */ +export const calcLineActualSizeByPlaneSize = (planeSize, degree = 0) => { + const theta = Math.cos((degree * Math.PI) / 180) + return planeSize / theta +} + export const createLinesFromPolygon = (points) => { const lines = [] for (let i = 0; i < points.length; i++) {