처마면 모듈 자동설치 작업중
This commit is contained in:
parent
0ed7efb3af
commit
04a45c1bc9
@ -39,7 +39,7 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
|
|||||||
|
|
||||||
const placementRef = {
|
const placementRef = {
|
||||||
isChidori: useRef('false'),
|
isChidori: useRef('false'),
|
||||||
setupLocation: useRef(null),
|
setupLocation: useRef('center'),
|
||||||
isMaxSetup: useRef('false'),
|
isMaxSetup: useRef('false'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,8 @@ import { forwardRef, useState } from 'react'
|
|||||||
const Placement = forwardRef((props, refs) => {
|
const Placement = forwardRef((props, refs) => {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
const [isChidori, setIsChidori] = useState('false')
|
const [isChidori, setIsChidori] = useState('false')
|
||||||
|
const [setupLocation, setSetupLocation] = useState('center')
|
||||||
|
const [isMaxSetup, setIsMaxSetup] = useState('false')
|
||||||
|
|
||||||
const moduleData = {
|
const moduleData = {
|
||||||
header: [
|
header: [
|
||||||
@ -33,6 +35,23 @@ const Placement = forwardRef((props, refs) => {
|
|||||||
refs.isChidori.current = e.target.value
|
refs.isChidori.current = e.target.value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleSetupLocation = (e) => {
|
||||||
|
setSetupLocation(e.target.value)
|
||||||
|
refs.setupLocation.current = e.target.value
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleMaxSetup = (e) => {
|
||||||
|
console.log(e.target.checked)
|
||||||
|
|
||||||
|
if (e.target.checked) {
|
||||||
|
setIsMaxSetup('true')
|
||||||
|
refs.isMaxSetup.current = 'true'
|
||||||
|
} else {
|
||||||
|
setIsMaxSetup('false')
|
||||||
|
refs.isMaxSetup.current = 'false'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="module-table-flex-wrap mb10">
|
<div className="module-table-flex-wrap mb10">
|
||||||
@ -128,15 +147,36 @@ const Placement = forwardRef((props, refs) => {
|
|||||||
<div className="self-item-td">
|
<div className="self-item-td">
|
||||||
<div className="pop-form-radio">
|
<div className="pop-form-radio">
|
||||||
<div className="d-check-radio pop">
|
<div className="d-check-radio pop">
|
||||||
<input type="radio" name="radio02" id="ra03" />
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="radio03"
|
||||||
|
id="ra03"
|
||||||
|
checked={setupLocation === 'center'}
|
||||||
|
value={'center'}
|
||||||
|
onChange={handleSetupLocation}
|
||||||
|
/>
|
||||||
<label htmlFor="ra03">{getMessage('modal.module.basic.setting.module.placement.arrangement.standard.center')}</label>
|
<label htmlFor="ra03">{getMessage('modal.module.basic.setting.module.placement.arrangement.standard.center')}</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="d-check-radio pop">
|
<div className="d-check-radio pop">
|
||||||
<input type="radio" name="radio02" id="ra04" />
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="radio04"
|
||||||
|
id="ra04"
|
||||||
|
checked={setupLocation === 'eaves'}
|
||||||
|
value={'eaves'}
|
||||||
|
onChange={handleSetupLocation}
|
||||||
|
/>
|
||||||
<label htmlFor="ra04">{getMessage('modal.module.basic.setting.module.placement.arrangement.standard.eaves')}</label>
|
<label htmlFor="ra04">{getMessage('modal.module.basic.setting.module.placement.arrangement.standard.eaves')}</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="d-check-radio pop">
|
<div className="d-check-radio pop">
|
||||||
<input type="radio" name="radio02" id="ra05" />
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="radio05"
|
||||||
|
id="ra05"
|
||||||
|
checked={setupLocation === 'ridge'}
|
||||||
|
value={'ridge'}
|
||||||
|
onChange={handleSetupLocation}
|
||||||
|
/>
|
||||||
<label htmlFor="ra05">{getMessage('modal.module.basic.setting.module.placement.arrangement.standard.ridge')}</label>
|
<label htmlFor="ra05">{getMessage('modal.module.basic.setting.module.placement.arrangement.standard.ridge')}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -145,7 +185,7 @@ const Placement = forwardRef((props, refs) => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="self-table-flx">
|
<div className="self-table-flx">
|
||||||
<div className="d-check-box pop">
|
<div className="d-check-box pop">
|
||||||
<input type="checkbox" id="ch04" />
|
<input type="checkbox" id="ch04" checked={isMaxSetup === 'true'} value={'true'} onChange={handleMaxSetup} />
|
||||||
<label htmlFor="ch04">{getMessage('modal.module.basic.setting.module.placement.maximum')}</label>
|
<label htmlFor="ch04">{getMessage('modal.module.basic.setting.module.placement.maximum')}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -20,6 +20,7 @@ export function useModuleBasicSetting() {
|
|||||||
const [moduleIsSetup, setModuleIsSetup] = useRecoilState(moduleIsSetupState)
|
const [moduleIsSetup, setModuleIsSetup] = useRecoilState(moduleIsSetupState)
|
||||||
// const { addTargetMouseEventListener, addCanvasMouseEventListener, initEvent } = useEvent()
|
// const { addTargetMouseEventListener, addCanvasMouseEventListener, initEvent } = useEvent()
|
||||||
const { addTargetMouseEventListener, addCanvasMouseEventListener, initEvent } = useContext(EventContext)
|
const { addTargetMouseEventListener, addCanvasMouseEventListener, initEvent } = useContext(EventContext)
|
||||||
|
const [flowModuleLine, setFlowModuleLine] = useState({})
|
||||||
let selectedModuleInstSurfaceArray = []
|
let selectedModuleInstSurfaceArray = []
|
||||||
|
|
||||||
const makeModuleInstArea = () => {
|
const makeModuleInstArea = () => {
|
||||||
@ -55,10 +56,12 @@ export function useModuleBasicSetting() {
|
|||||||
setupSurface.setViewLengthText(false)
|
setupSurface.setViewLengthText(false)
|
||||||
|
|
||||||
canvas.add(setupSurface)
|
canvas.add(setupSurface)
|
||||||
bottomModuleLine(setupSurface)
|
|
||||||
topModuleLine(setupSurface)
|
if (setupSurface.flowDirection === 'south' || setupSurface.flowDirection === 'north') {
|
||||||
leftModuleLine(setupSurface)
|
setFlowModuleLine(bottomTopFlowLine(setupSurface))
|
||||||
// rightModuleLine(setupSurface)
|
} else {
|
||||||
|
setFlowModuleLine(leftRightFlowLine(setupSurface))
|
||||||
|
}
|
||||||
|
|
||||||
//지붕면 선택 금지
|
//지붕면 선택 금지
|
||||||
roof.set({
|
roof.set({
|
||||||
@ -74,7 +77,6 @@ export function useModuleBasicSetting() {
|
|||||||
|
|
||||||
//설치 범위 지정 클릭 이벤트
|
//설치 범위 지정 클릭 이벤트
|
||||||
const toggleSelection = (setupSurface) => {
|
const toggleSelection = (setupSurface) => {
|
||||||
console.log('setupSurface', setupSurface)
|
|
||||||
const isExist = selectedModuleInstSurfaceArray.some((obj) => obj.parentId === setupSurface.parentId)
|
const isExist = selectedModuleInstSurfaceArray.some((obj) => obj.parentId === setupSurface.parentId)
|
||||||
//최초 선택일때
|
//최초 선택일때
|
||||||
if (!isExist) {
|
if (!isExist) {
|
||||||
@ -391,6 +393,8 @@ export function useModuleBasicSetting() {
|
|||||||
//자동 모듈 설치(그리드 방식)
|
//자동 모듈 설치(그리드 방식)
|
||||||
const autoModuleSetup = (placementRef) => {
|
const autoModuleSetup = (placementRef) => {
|
||||||
const isChidori = placementRef.isChidori.current
|
const isChidori = placementRef.isChidori.current
|
||||||
|
const setupLocation = placementRef.setupLocation.current
|
||||||
|
const isMaxSetup = placementRef.isMaxSetup.current
|
||||||
|
|
||||||
initEvent()
|
initEvent()
|
||||||
const moduleSetupSurfaces = moduleSetupSurface //선택 설치면
|
const moduleSetupSurfaces = moduleSetupSurface //선택 설치면
|
||||||
@ -434,6 +438,8 @@ export function useModuleBasicSetting() {
|
|||||||
moduleSetupSurfaces.forEach((moduleSetupSurface, index) => {
|
moduleSetupSurfaces.forEach((moduleSetupSurface, index) => {
|
||||||
moduleSetupSurface.fire('mousedown')
|
moduleSetupSurface.fire('mousedown')
|
||||||
|
|
||||||
|
const surfaceMaxLines = findSetupSurfaceMaxLines(moduleSetupSurface)
|
||||||
|
|
||||||
let maxLengthLine = moduleSetupSurface.lines.reduce((acc, cur) => {
|
let maxLengthLine = moduleSetupSurface.lines.reduce((acc, cur) => {
|
||||||
return acc.length > cur.length ? acc : cur
|
return acc.length > cur.length ? acc : cur
|
||||||
})
|
})
|
||||||
@ -470,21 +476,11 @@ export function useModuleBasicSetting() {
|
|||||||
} else {
|
} else {
|
||||||
convertBatchObject = polygonToTurfPolygon(containsBatchObjects[i])
|
convertBatchObject = polygonToTurfPolygon(containsBatchObjects[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i === 0) {
|
|
||||||
difference = turf.difference(turf.featureCollection([turfModuleSetupSurface, convertBatchObject])) //한 면에 도머가 1개일때
|
|
||||||
} else {
|
|
||||||
if (difference) {
|
|
||||||
difference = turf.difference(turf.featureCollection([difference, convertBatchObject])) //한면에 도머가 여러개일때 계속 제외시킴
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const bbox = turf.bbox(difference)
|
let width = maxLengthLine.flowDirection === 'east' || maxLengthLine.flowDirection === 'west' ? 172.2 : 113.4
|
||||||
|
let height = maxLengthLine.flowDirection === 'east' || maxLengthLine.flowDirection === 'west' ? 113.4 : 172.2
|
||||||
let width = maxLengthLine.flowDirection === 'right' || maxLengthLine.flowDirection === 'left' ? 172.2 : 113.4
|
|
||||||
let height = maxLengthLine.flowDirection === 'right' || maxLengthLine.flowDirection === 'left' ? 113.4 : 172.2
|
|
||||||
|
|
||||||
//배치면때는 방향쪽으로 패널이 넓게 누워져야함
|
//배치면때는 방향쪽으로 패널이 넓게 누워져야함
|
||||||
if (moduleSetupSurface.flowDirection !== undefined) {
|
if (moduleSetupSurface.flowDirection !== undefined) {
|
||||||
@ -492,144 +488,97 @@ export function useModuleBasicSetting() {
|
|||||||
height = moduleSetupSurface.flowDirection === 'south' || moduleSetupSurface.flowDirection === 'north' ? 113.4 : 172.2
|
height = moduleSetupSurface.flowDirection === 'south' || moduleSetupSurface.flowDirection === 'north' ? 113.4 : 172.2
|
||||||
}
|
}
|
||||||
|
|
||||||
let cols = Math.floor((bbox[2] - bbox[0]) / width)
|
let square
|
||||||
let rows = Math.floor((bbox[3] - bbox[1]) / height)
|
let startPoint, endPoint
|
||||||
|
|
||||||
// cols = cols * 2
|
if (setupLocation === 'eaves') {
|
||||||
|
if (moduleSetupSurface.flowDirection === 'south') {
|
||||||
|
startPoint = flowModuleLine.find((obj) => obj.target === 'bottom')
|
||||||
|
endPoint = flowModuleLine.find((obj) => obj.target === 'top')
|
||||||
|
const totalHeight = endPoint.y1 - startPoint.y1
|
||||||
|
const diffHeight = Math.abs(totalHeight / height)
|
||||||
|
let leftMargin = 0
|
||||||
|
let bottomMargin = 0
|
||||||
|
|
||||||
for (let col = 0; col <= cols; col++) {
|
for (let i = 0; i < diffHeight; i++) {
|
||||||
for (let row = 0; row <= rows; row++) {
|
leftMargin = i === 0 ? 1 : 0
|
||||||
let x = 0,
|
bottomMargin = i === 0 ? 0 : 1
|
||||||
y = 0,
|
|
||||||
square = [],
|
|
||||||
margin = 0
|
|
||||||
if (moduleSetupSurface.flowDirection !== undefined) {
|
|
||||||
//배치면 처림 방향이 정해져있는 경우
|
|
||||||
if (moduleSetupSurface.flowDirection === 'south' || moduleSetupSurface.flowDirection === 'north') {
|
|
||||||
//남,북
|
|
||||||
margin = (bbox[2] - bbox[0] - cols * width) / 2 //박스 끝에서 박스 시작값을 빼고 width와 계산된 cols를 곱한값을 뺀뒤 나누기 2 하면 가운데 배치됨
|
|
||||||
if (moduleSetupSurface.flowDirection === 'south') {
|
|
||||||
//남쪽
|
|
||||||
x = col === 0 ? moduleSetupSurface.left + margin : bbox[0] + col * width + margin //상하 위치 기준이면 좌우 가운데 정렬한다
|
|
||||||
y = bbox[3] - row * height
|
|
||||||
} else {
|
|
||||||
//북쪽
|
|
||||||
x = col === 0 ? moduleSetupSurface.left + margin : bbox[0] + col * width + margin
|
|
||||||
y = bbox[1] + row * height
|
|
||||||
}
|
|
||||||
} else if (moduleSetupSurface.flowDirection === 'east' || moduleSetupSurface.flowDirection === 'west') {
|
|
||||||
//동쪽
|
|
||||||
margin = (bbox[3] - bbox[1] - rows * height) / 2
|
|
||||||
if (moduleSetupSurface.flowDirection === 'east') {
|
|
||||||
x = bbox[2] - col * width
|
|
||||||
y = rows === 0 ? moduleSetupSurface.top + margin : bbox[1] + row * height + margin //좌우 위치 기준이면 상하 가운데 정렬한다
|
|
||||||
} else {
|
|
||||||
x = bbox[0] + col * width
|
|
||||||
y = rows === 0 ? moduleSetupSurface.top + margin : bbox[1] + row * height + margin
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//방향이 없는 경우 ex) 템플릿
|
|
||||||
x = bbox[0] + col * width
|
|
||||||
y = bbox[1] + row * height
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isChidori === 'true') {
|
|
||||||
if (row % 2 !== 0) {
|
|
||||||
square = [
|
|
||||||
[x, y],
|
|
||||||
[x + width, y],
|
|
||||||
[x + width, y + height],
|
|
||||||
[x, y + height],
|
|
||||||
[x, y],
|
|
||||||
]
|
|
||||||
} else {
|
|
||||||
square = [
|
|
||||||
[x - width / 2, y],
|
|
||||||
[x - width / 2 + width, y],
|
|
||||||
[x - width / 2 + width, y + height],
|
|
||||||
[x - width / 2, y + height],
|
|
||||||
[x - width / 2, y],
|
|
||||||
]
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
square = [
|
square = [
|
||||||
[x, y],
|
[startPoint.x1 + leftMargin, startPoint.y1 - height - bottomMargin],
|
||||||
[x + width, y],
|
[startPoint.x1 + leftMargin, startPoint.y1 - bottomMargin],
|
||||||
[x + width, y + height],
|
[startPoint.x1 + leftMargin + width, startPoint.y1 - bottomMargin],
|
||||||
[x, y + height],
|
[startPoint.x1 + leftMargin + width, startPoint.y1 - height - bottomMargin],
|
||||||
[x, y],
|
[startPoint.x1 + leftMargin, startPoint.y1 - height - bottomMargin],
|
||||||
]
|
]
|
||||||
}
|
|
||||||
|
|
||||||
// square = [
|
const squarePolygon = turf.polygon([square])
|
||||||
// [x - width / 2, y],
|
|
||||||
// [x - width / 2 + width, y],
|
|
||||||
// [x - width / 2 + width, y + height],
|
|
||||||
// [x - width / 2, y + height],
|
|
||||||
// [x - width / 2, y],
|
|
||||||
// ]
|
|
||||||
|
|
||||||
const squarePolygon = turf.polygon([square])
|
//설치면 안에 있는지 확인
|
||||||
const disjointFromTrestle =
|
const disjointFromTrestle =
|
||||||
turf.booleanContains(turfModuleSetupSurface, squarePolygon) || turf.booleanWithin(squarePolygon, turfModuleSetupSurface)
|
turf.booleanContains(turfModuleSetupSurface, squarePolygon) || turf.booleanWithin(squarePolygon, turfModuleSetupSurface)
|
||||||
if (disjointFromTrestle) {
|
|
||||||
let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1)
|
if (disjointFromTrestle) {
|
||||||
const points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] }))
|
let turfCoordnates = squarePolygon.geometry.coordinates[0].slice(0, -1)
|
||||||
if (containsBatchObjects.length > 0) {
|
const points = turfCoordnates.map((coord) => ({ x: coord[0], y: coord[1] }))
|
||||||
let convertBatchObject
|
|
||||||
//도머가 있으면 적용되는 로직
|
if (containsBatchObjects.length > 0) {
|
||||||
const isDisjoint = containsBatchObjects.every((batchObject) => {
|
let convertBatchObject
|
||||||
if (batchObject.type === 'group') {
|
//도머가 있으면 적용되는 로직
|
||||||
convertBatchObject = batchObjectGroupToTurfPolygon(batchObject)
|
const isDisjoint = containsBatchObjects.every((batchObject) => {
|
||||||
} else {
|
if (batchObject.type === 'group') {
|
||||||
convertBatchObject = polygonToTurfPolygon(batchObject)
|
convertBatchObject = batchObjectGroupToTurfPolygon(batchObject)
|
||||||
|
} else {
|
||||||
|
convertBatchObject = polygonToTurfPolygon(batchObject)
|
||||||
|
}
|
||||||
|
return turf.booleanDisjoint(squarePolygon, convertBatchObject) //도머가 여러개일수있으므로 겹치는게 있다면...
|
||||||
|
})
|
||||||
|
if (isDisjoint) {
|
||||||
|
const tempModule = new QPolygon(points, {
|
||||||
|
fill: '#BFFD9F',
|
||||||
|
stroke: 'black',
|
||||||
|
strokeWidth: 0.1,
|
||||||
|
selectable: true, // 선택 가능하게 설정
|
||||||
|
lockMovementX: false, // X 축 이동 잠금
|
||||||
|
lockMovementY: false, // Y 축 이동 잠금
|
||||||
|
lockRotation: false, // 회전 잠금
|
||||||
|
lockScalingX: false, // X 축 크기 조정 잠금
|
||||||
|
lockScalingY: false, // Y 축 크기 조정 잠금
|
||||||
|
opacity: 0.8,
|
||||||
|
parentId: moduleSetupSurface.parentId,
|
||||||
|
name: 'module',
|
||||||
|
})
|
||||||
|
tempModule.setViewLengthText(false)
|
||||||
|
canvas?.add(tempModule)
|
||||||
|
moduleSetupArray.push(tempModule)
|
||||||
}
|
}
|
||||||
return turf.booleanDisjoint(squarePolygon, convertBatchObject) //도머가 여러개일수있으므로 겹치는게 있다면...
|
} else {
|
||||||
})
|
//도머가 없을땐 그냥 그림
|
||||||
if (isDisjoint) {
|
|
||||||
const tempModule = new QPolygon(points, {
|
const tempModule = new QPolygon(points, {
|
||||||
fill: '#BFFD9F',
|
fill: '#BFFD9F',
|
||||||
stroke: 'black',
|
stroke: 'black',
|
||||||
selectable: true, // 선택 가능하게 설정
|
selectable: true, // 선택 가능하게 설정
|
||||||
lockMovementX: false, // X 축 이동 잠금
|
lockMovementX: true, // X 축 이동 잠금
|
||||||
lockMovementY: false, // Y 축 이동 잠금
|
lockMovementY: true, // Y 축 이동 잠금
|
||||||
lockRotation: false, // 회전 잠금
|
lockRotation: true, // 회전 잠금
|
||||||
lockScalingX: false, // X 축 크기 조정 잠금
|
lockScalingX: true, // X 축 크기 조정 잠금
|
||||||
lockScalingY: false, // Y 축 크기 조정 잠금
|
lockScalingY: true, // Y 축 크기 조정 잠금
|
||||||
opacity: 0.8,
|
opacity: 0.8,
|
||||||
parentId: moduleSetupSurface.parentId,
|
parentId: moduleSetupSurface.parentId,
|
||||||
lineCol: col,
|
|
||||||
lineRow: row,
|
|
||||||
name: 'module',
|
name: 'module',
|
||||||
|
selectable: true,
|
||||||
})
|
})
|
||||||
tempModule.setViewLengthText(false)
|
canvas?.add(tempModule)
|
||||||
// canvas?.add(tempModule)
|
|
||||||
moduleSetupArray.push(tempModule)
|
moduleSetupArray.push(tempModule)
|
||||||
}
|
}
|
||||||
} else {
|
startPoint = { x1: points[0].x, y1: points[0].y, x2: points[3].x, y2: points[3].y }
|
||||||
//도머가 없을땐 그냥 그림
|
|
||||||
const tempModule = new QPolygon(points, {
|
|
||||||
fill: '#BFFD9F',
|
|
||||||
stroke: 'black',
|
|
||||||
selectable: true, // 선택 가능하게 설정
|
|
||||||
lockMovementX: true, // X 축 이동 잠금
|
|
||||||
lockMovementY: true, // Y 축 이동 잠금
|
|
||||||
lockRotation: true, // 회전 잠금
|
|
||||||
lockScalingX: true, // X 축 크기 조정 잠금
|
|
||||||
lockScalingY: true, // Y 축 크기 조정 잠금
|
|
||||||
opacity: 0.8,
|
|
||||||
parentId: moduleSetupSurface.parentId,
|
|
||||||
lineCol: col,
|
|
||||||
lineRow: row,
|
|
||||||
name: 'module',
|
|
||||||
})
|
|
||||||
// canvas?.add(tempModule)
|
|
||||||
moduleSetupArray.push(tempModule)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (setupLocation === 'ridge') {
|
||||||
|
} else {
|
||||||
}
|
}
|
||||||
|
|
||||||
moduleSetupSurface.set({ modules: moduleSetupArray })
|
moduleSetupSurface.set({ modules: moduleSetupArray })
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -772,48 +721,9 @@ export function useModuleBasicSetting() {
|
|||||||
return hull
|
return hull
|
||||||
}
|
}
|
||||||
|
|
||||||
const bottomModuleLine = (nowSurface) => {
|
const bottomTopFlowLine = (surface) => {
|
||||||
let selectedLine = null
|
const flowArray = []
|
||||||
|
const bottomFlow = surface.lines.reduce(
|
||||||
const sortedLines = sortLinesByTopLeft(nowSurface.lines)
|
|
||||||
|
|
||||||
const moduleWidthLength = 173.3 + 5 //임시 약간 여유를 줌
|
|
||||||
|
|
||||||
// if (nowSurface.flowDirection === 'east') {
|
|
||||||
// const leftFlow = nowSurface.lines.reduce(
|
|
||||||
// (acc, line, index) => {
|
|
||||||
// if (line.x1 < acc.x1 || (line.x1 === acc.x1 && line.y1 < acc.y1)) {
|
|
||||||
// return { x1: line.x1, y1: line.y1, index: index }
|
|
||||||
// }
|
|
||||||
// return acc
|
|
||||||
// },
|
|
||||||
// { x1: Infinity, y1: Infinity, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스
|
|
||||||
// )
|
|
||||||
// selectedLine = leftFlow
|
|
||||||
// } else if (nowSurface.flowDirection === 'west') {
|
|
||||||
// const rightFlow = nowSurface.lines.reduce(
|
|
||||||
// (acc, line, index) => {
|
|
||||||
// if (line.x1 > acc.x1 || (line.x1 === acc.x1 && line.y1 > acc.y1)) {
|
|
||||||
// return { x1: line.x1, y1: line.y1, index: index }
|
|
||||||
// }
|
|
||||||
// return acc
|
|
||||||
// },
|
|
||||||
// { x1: 0, y1: 0, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스
|
|
||||||
// )
|
|
||||||
// selectedLine = rightFlow
|
|
||||||
// } else if (nowSurface.flowDirection === 'north') {
|
|
||||||
// const topFlow = nowSurface.lines.reduce(
|
|
||||||
// (acc, line, index) => {
|
|
||||||
// if (line.y1 < acc.y1 || (line.y1 === acc.y1 && line.x1 < acc.x1)) {
|
|
||||||
// return { x1: line.x1, y1: line.y1, index: index }
|
|
||||||
// }
|
|
||||||
// return acc
|
|
||||||
// },
|
|
||||||
// { x1: Infinity, y1: Infinity, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스
|
|
||||||
// )
|
|
||||||
// selectedLine = topFlow
|
|
||||||
// } else {
|
|
||||||
const bottomFlow = nowSurface.lines.reduce(
|
|
||||||
(acc, line, index) => {
|
(acc, line, index) => {
|
||||||
if (line.y1 > acc.y1 || (line.y1 === acc.y1 && line.x1 > acc.x1)) {
|
if (line.y1 > acc.y1 || (line.y1 === acc.y1 && line.x1 > acc.x1)) {
|
||||||
return { x1: line.x1, y1: line.y1, index: index }
|
return { x1: line.x1, y1: line.y1, index: index }
|
||||||
@ -822,103 +732,9 @@ export function useModuleBasicSetting() {
|
|||||||
},
|
},
|
||||||
{ x1: 0, y1: 0, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스
|
{ x1: 0, y1: 0, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스
|
||||||
)
|
)
|
||||||
selectedLine = bottomFlow
|
flowArray.push(bottomFlow)
|
||||||
// }
|
|
||||||
|
|
||||||
let prevLines = nowSurface.lines[(selectedLine.index - 1 + nowSurface.lines.length) % nowSurface.lines.length]
|
const topFlow = surface.lines.reduce(
|
||||||
let nextLines = nowSurface.lines[selectedLine.index]
|
|
||||||
const overlapCoords = { x: nextLines.x1, y: nextLines.y1 } //겹치는 꼭지점
|
|
||||||
|
|
||||||
const m1 = (prevLines.y2 - prevLines.y1) / (prevLines.x2 - prevLines.x1)
|
|
||||||
const m2 = (nextLines.y2 - nextLines.y1) / (nextLines.x2 - nextLines.x1)
|
|
||||||
|
|
||||||
const c1 = prevLines.y1 - m1 * prevLines.x1
|
|
||||||
const c2 = nextLines.y1 - m2 * nextLines.x1
|
|
||||||
|
|
||||||
// Step 2: Calculate intersection point
|
|
||||||
|
|
||||||
let xIntersectPrev = 0
|
|
||||||
let yIntersectPrev = 0
|
|
||||||
let xIntersectNext = 0
|
|
||||||
let yIntersectNext = 0
|
|
||||||
|
|
||||||
let endPoint = prevLines.y1 > nextLines.y2 ? prevLines.y1 : nextLines.y2
|
|
||||||
let biggerEndPoint = prevLines.y1 > nextLines.y2 ? 'left' : 'right'
|
|
||||||
|
|
||||||
//bottom일 경우
|
|
||||||
xIntersectPrev = (endPoint - c1) / m1
|
|
||||||
yIntersectPrev = m1 * xIntersectPrev + c1
|
|
||||||
xIntersectNext = (endPoint - c2) / m2
|
|
||||||
yIntersectNext = m2 * xIntersectNext + c2
|
|
||||||
|
|
||||||
let lineCoords
|
|
||||||
let polygonCoords
|
|
||||||
let ratio = 1
|
|
||||||
if (biggerEndPoint === 'left') {
|
|
||||||
//왼쪽이 더 밑이면 우측 라인에 절편으로 계산
|
|
||||||
lineCoords = [prevLines.x1, yIntersectNext, xIntersectNext, yIntersectNext]
|
|
||||||
polygonCoords = [
|
|
||||||
{ x: prevLines.x1, y: yIntersectNext },
|
|
||||||
{ x: xIntersectNext, y: yIntersectNext },
|
|
||||||
{ x: overlapCoords.x, y: overlapCoords.y },
|
|
||||||
]
|
|
||||||
ratio = moduleWidthLength / Math.abs(prevLines.x1 - xIntersectNext)
|
|
||||||
} else {
|
|
||||||
lineCoords = [xIntersectPrev, yIntersectPrev, nextLines.x2, yIntersectPrev]
|
|
||||||
polygonCoords = [
|
|
||||||
{ x: xIntersectPrev, y: yIntersectPrev },
|
|
||||||
{ x: nextLines.x2, y: yIntersectPrev },
|
|
||||||
{ x: overlapCoords.x, y: overlapCoords.y },
|
|
||||||
]
|
|
||||||
ratio = moduleWidthLength / Math.abs(nextLines.x2 - xIntersectPrev)
|
|
||||||
}
|
|
||||||
|
|
||||||
const tempTriangle = new QPolygon(polygonCoords, {
|
|
||||||
fill: 'transparent',
|
|
||||||
stroke: 'green',
|
|
||||||
strokeWidth: 2,
|
|
||||||
originY: 'bottom',
|
|
||||||
strokeDashArray: [5, 5],
|
|
||||||
// fontSize: 15,
|
|
||||||
})
|
|
||||||
|
|
||||||
// canvas.add(tempTriangle)
|
|
||||||
|
|
||||||
let cloneCoords = []
|
|
||||||
tempTriangle.clone((clone) => {
|
|
||||||
clone.scale(ratio)
|
|
||||||
cloneCoords = clone.getCurrentPoints()
|
|
||||||
})
|
|
||||||
|
|
||||||
//아래쪽에선 잴 작은
|
|
||||||
const vertexPoints = cloneCoords.reduce((acc, point, index) => (acc['y'] > point['y'] ? acc : point))
|
|
||||||
|
|
||||||
const differenceDistance = overlapCoords.x - vertexPoints.x
|
|
||||||
|
|
||||||
const newTriangleCoords = cloneCoords.map((point) => {
|
|
||||||
return { x: point.x + differenceDistance, y: point.y }
|
|
||||||
})
|
|
||||||
|
|
||||||
const deleteBottomPoint = newTriangleCoords.reduce((acc, point) => (acc['y'] > point['y'] ? acc : point))
|
|
||||||
const deleteIndex = newTriangleCoords.indexOf(deleteBottomPoint)
|
|
||||||
if (deleteIndex !== -1) newTriangleCoords.splice(deleteIndex, 1)
|
|
||||||
|
|
||||||
const newLine = new QLine([newTriangleCoords[0].x, newTriangleCoords[0].y, newTriangleCoords[1].x, newTriangleCoords[1].y], {
|
|
||||||
fill: 'transparent',
|
|
||||||
stroke: 'red',
|
|
||||||
strokeWidth: 2,
|
|
||||||
selectable: true,
|
|
||||||
fontSize: 14,
|
|
||||||
})
|
|
||||||
canvas.add(newLine)
|
|
||||||
return newLine
|
|
||||||
}
|
|
||||||
|
|
||||||
const topModuleLine = (nowSurface) => {
|
|
||||||
let selectedLine = null
|
|
||||||
const moduleWidthLength = 173.3 + 5 //임시 약간 여유를 줌
|
|
||||||
|
|
||||||
const topFlow = nowSurface.lines.reduce(
|
|
||||||
(acc, line, index) => {
|
(acc, line, index) => {
|
||||||
if (line.y1 < acc.y1 || (line.y1 === acc.y1 && line.x1 < acc.x1)) {
|
if (line.y1 < acc.y1 || (line.y1 === acc.y1 && line.x1 < acc.x1)) {
|
||||||
return { x1: line.x1, y1: line.y1, index: index }
|
return { x1: line.x1, y1: line.y1, index: index }
|
||||||
@ -927,117 +743,80 @@ export function useModuleBasicSetting() {
|
|||||||
},
|
},
|
||||||
{ x1: Infinity, y1: Infinity, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스
|
{ x1: Infinity, y1: Infinity, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스
|
||||||
)
|
)
|
||||||
selectedLine = topFlow
|
flowArray.push(topFlow)
|
||||||
|
|
||||||
let prevLines = nowSurface.lines[(selectedLine.index - 1 + nowSurface.lines.length) % nowSurface.lines.length]
|
let idx = 0
|
||||||
let nextLines = nowSurface.lines[selectedLine.index]
|
let rtnObjArray = []
|
||||||
const overlapCoords = { x: nextLines.x1, y: nextLines.y1 } //겹치는 꼭지점
|
flowArray.forEach((center) => {
|
||||||
|
const linesArray = new Array()
|
||||||
|
|
||||||
const m1 = (prevLines.y2 - prevLines.y1) / (prevLines.x2 - prevLines.x1)
|
surface.lines.filter((line) => {
|
||||||
const m2 = (nextLines.y2 - nextLines.y1) / (nextLines.x2 - nextLines.x1)
|
if ((center.x1 === line.x1 && center.y1 === line.y1) || (center.x1 === line.x2 && center.y1 === line.y2)) {
|
||||||
|
linesArray.push(line)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const c1 = prevLines.y1 - m1 * prevLines.x1
|
let coords = []
|
||||||
const c2 = nextLines.y1 - m2 * nextLines.x1
|
if (center.index === 0) {
|
||||||
|
coords = [
|
||||||
|
{ x: linesArray[0].x2, y: linesArray[0].y2 },
|
||||||
|
{ x: center.x1, y: center.y1 },
|
||||||
|
{ x: linesArray[1].x1, y: linesArray[1].y1 },
|
||||||
|
]
|
||||||
|
} else {
|
||||||
|
coords = [
|
||||||
|
{ x: linesArray[0].x1, y: linesArray[0].y1 },
|
||||||
|
{ x: center.x1, y: center.y1 },
|
||||||
|
{ x: linesArray[1].x2, y: linesArray[1].y2 },
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
// Step 2: Calculate intersection point
|
const adjust1 = coords[0].x - coords[1].x
|
||||||
|
const height1 = coords[1].y - coords[0].y
|
||||||
|
const angle1 = Math.abs(Math.round(Math.atan(height1 / adjust1) * (180 / Math.PI) * 1000) / 1000)
|
||||||
|
|
||||||
let xIntersectPrev = 0
|
const adjust2 = coords[2].x - coords[1].x
|
||||||
let yIntersectPrev = 0
|
const height2 = coords[2].y - coords[1].y
|
||||||
let xIntersectNext = 0
|
const angle2 = Math.abs(Math.round(Math.atan(height2 / adjust2) * (180 / Math.PI) * 1000) / 1000)
|
||||||
let yIntersectNext = 0
|
const angle3 = 180 - (angle1 + angle2)
|
||||||
|
|
||||||
let endPoint = prevLines.y1 > nextLines.y2 ? nextLines.y2 : prevLines.y1
|
const charlie = 173.3 + 3 // 평행선길이 약간 여유를 줌
|
||||||
let biggerEndPoint = prevLines.y1 < nextLines.y2 ? 'left' : 'right'
|
const alpha = (charlie * Math.sin((angle1 * Math.PI) / 180)) / Math.sin((angle3 * Math.PI) / 180)
|
||||||
|
const beta = Math.sqrt(alpha ** 2 + charlie ** 2 - 2 * alpha * charlie * Math.cos((angle2 * Math.PI) / 180))
|
||||||
|
const h = beta * Math.sin((angle1 * Math.PI) / 180) // 높이
|
||||||
|
const sign = Math.sign(coords[0].y - coords[1].y) // 진행방향
|
||||||
|
const top = coords[1].y + sign * h // 변경되는 높이 좌표 값
|
||||||
|
// const line3 = new QLine([coords[1].x, coords[1].y, coords[1].x, top], {
|
||||||
|
// stroke: 'blue',
|
||||||
|
// strokeWidth: 1,
|
||||||
|
// selectable: true,
|
||||||
|
// })
|
||||||
|
// // canvas?.add(line3)
|
||||||
|
|
||||||
//bottom일 경우
|
const pointX1 = coords[0].x + ((coords[0].y - top) / (coords[0].y - coords[1].y)) * (coords[1].x - coords[0].x)
|
||||||
xIntersectPrev = (endPoint - c1) / m1
|
const pointY1 = top
|
||||||
yIntersectPrev = m1 * xIntersectPrev + c1
|
const pointX2 = coords[2].x + ((coords[2].y - top) / (coords[2].y - coords[1].y)) * (coords[1].x - coords[2].x)
|
||||||
xIntersectNext = (endPoint - c2) / m2
|
const pointY2 = top
|
||||||
yIntersectNext = m2 * xIntersectNext + c2
|
|
||||||
|
|
||||||
let lineCoords
|
const finalLine = new QLine([pointX1, pointY1, pointX2, pointY2], {
|
||||||
let polygonCoords
|
stroke: 'red',
|
||||||
let ratio = 1
|
strokeWidth: 1,
|
||||||
|
selectable: true,
|
||||||
|
})
|
||||||
|
canvas?.add(finalLine)
|
||||||
|
canvas?.renderAll()
|
||||||
|
|
||||||
if (biggerEndPoint === 'left') {
|
const rtnObj = { target: idx === 0 ? 'bottom' : 'top', x1: pointX1, y1: pointY1, x2: pointX2, y2: pointY2 }
|
||||||
//왼쪽이 더 밑이면 우측 라인에 절편으로 계산
|
rtnObjArray.push(rtnObj)
|
||||||
lineCoords = [prevLines.x1, yIntersectNext, xIntersectNext, yIntersectNext]
|
++idx
|
||||||
polygonCoords = [
|
|
||||||
{ x: prevLines.x1, y: yIntersectNext },
|
|
||||||
{ x: xIntersectNext, y: yIntersectNext },
|
|
||||||
{ x: overlapCoords.x, y: overlapCoords.y },
|
|
||||||
]
|
|
||||||
ratio = moduleWidthLength / Math.abs(prevLines.x1 - xIntersectNext)
|
|
||||||
} else {
|
|
||||||
lineCoords = [xIntersectPrev, yIntersectPrev, nextLines.x2, yIntersectPrev]
|
|
||||||
polygonCoords = [
|
|
||||||
{ x: xIntersectPrev, y: yIntersectPrev },
|
|
||||||
{ x: nextLines.x2, y: yIntersectPrev },
|
|
||||||
{ x: overlapCoords.x, y: overlapCoords.y },
|
|
||||||
]
|
|
||||||
ratio = moduleWidthLength / Math.abs(nextLines.x2 - xIntersectPrev)
|
|
||||||
}
|
|
||||||
|
|
||||||
const tempTriangle = new QPolygon(polygonCoords, {
|
|
||||||
fill: 'transparent',
|
|
||||||
stroke: 'green',
|
|
||||||
strokeWidth: 2,
|
|
||||||
originY: 'top',
|
|
||||||
strokeDashArray: [5, 5],
|
|
||||||
// fontSize: 15,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// canvas.add(tempTriangle)
|
return rtnObjArray
|
||||||
|
|
||||||
let cloneCoords = []
|
|
||||||
tempTriangle.clone((clone) => {
|
|
||||||
clone.scale(ratio)
|
|
||||||
cloneCoords = clone.getCurrentPoints()
|
|
||||||
})
|
|
||||||
|
|
||||||
//아래쪽에선 잴 작은
|
|
||||||
const vertexPoints = cloneCoords.reduce((acc, point, index) => (acc['y'] < point['y'] ? acc : point))
|
|
||||||
|
|
||||||
const differenceDistance = overlapCoords.x - vertexPoints.x
|
|
||||||
|
|
||||||
const newTriangleCoords = cloneCoords.map((point) => {
|
|
||||||
return { x: point.x + differenceDistance, y: point.y }
|
|
||||||
})
|
|
||||||
|
|
||||||
// const newTriangle1 = new QPolygon(newTriangleCoords, {
|
|
||||||
// fill: 'transparent',
|
|
||||||
// stroke: 'red',
|
|
||||||
// strokeWidth: 1,
|
|
||||||
// selectable: true,
|
|
||||||
// fontSize: 14,
|
|
||||||
// })
|
|
||||||
// canvas.add(newTriangle1)
|
|
||||||
|
|
||||||
const deleteBottomPoint = newTriangleCoords.reduce((acc, point) => (acc['y'] < point['y'] ? acc : point))
|
|
||||||
const deleteIndex = newTriangleCoords.indexOf(deleteBottomPoint)
|
|
||||||
if (deleteIndex !== -1) newTriangleCoords.splice(deleteIndex, 1)
|
|
||||||
|
|
||||||
const newLine = new QLine([newTriangleCoords[0].x, newTriangleCoords[0].y, newTriangleCoords[1].x, newTriangleCoords[1].y], {
|
|
||||||
fill: 'transparent',
|
|
||||||
stroke: 'red',
|
|
||||||
strokeWidth: 2,
|
|
||||||
selectable: true,
|
|
||||||
fontSize: 14,
|
|
||||||
})
|
|
||||||
canvas.add(newLine)
|
|
||||||
return newLine
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const leftModuleLine = (nowSurface) => {
|
const leftRightFlowLine = (surface) => {
|
||||||
let selectedLine = null
|
const flowArray = []
|
||||||
|
const leftFlow = surface.lines.reduce(
|
||||||
sortLinesByTopLeft(nowSurface)
|
|
||||||
|
|
||||||
console.log('nowSurface', nowSurface)
|
|
||||||
|
|
||||||
const moduleWidthLength = 173.3 + 5 //임시 약간 여유를 줌
|
|
||||||
|
|
||||||
const leftFlow = nowSurface.lines.reduce(
|
|
||||||
(acc, line, index) => {
|
(acc, line, index) => {
|
||||||
if (line.x1 < acc.x1 || (line.x1 === acc.x1 && line.y1 < acc.y1)) {
|
if (line.x1 < acc.x1 || (line.x1 === acc.x1 && line.y1 < acc.y1)) {
|
||||||
return { x1: line.x1, y1: line.y1, index: index }
|
return { x1: line.x1, y1: line.y1, index: index }
|
||||||
@ -1046,143 +825,135 @@ export function useModuleBasicSetting() {
|
|||||||
},
|
},
|
||||||
{ x1: Infinity, y1: Infinity, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스
|
{ x1: Infinity, y1: Infinity, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스
|
||||||
)
|
)
|
||||||
selectedLine = leftFlow
|
flowArray.push(leftFlow)
|
||||||
|
|
||||||
let prevLines = nowSurface.lines[(selectedLine.index - 1 + nowSurface.lines.length) % nowSurface.lines.length]
|
const rightFlow = surface.lines.reduce(
|
||||||
let nextLines = nowSurface.lines[selectedLine.index]
|
(acc, line, index) => {
|
||||||
const overlapCoords = { x: nextLines.x1, y: nextLines.y1 } //겹치는 꼭지점
|
if (line.x1 > acc.x1 || (line.x1 === acc.x1 && line.y1 > acc.y1)) {
|
||||||
|
return { x1: line.x1, y1: line.y1, index: index }
|
||||||
|
}
|
||||||
|
return acc
|
||||||
|
},
|
||||||
|
{ x1: 0, y1: 0, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스
|
||||||
|
)
|
||||||
|
flowArray.push(rightFlow)
|
||||||
|
|
||||||
const m1 = (prevLines.y2 - prevLines.y1) / (prevLines.x2 - prevLines.x1)
|
let idx = 0
|
||||||
const m2 = (nextLines.y2 - nextLines.y1) / (nextLines.x2 - nextLines.x1)
|
let rtnObjArray = []
|
||||||
|
flowArray.forEach((center) => {
|
||||||
|
const linesArray = surface.lines.filter((line) => {
|
||||||
|
if ((center.x1 === line.x1 && center.y1 === line.y1) || (center.x1 === line.x2 && center.y1 === line.y2)) {
|
||||||
|
return line
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const c1 = prevLines.y1 - m1 * prevLines.x1
|
let coords = []
|
||||||
const c2 = nextLines.y1 - m2 * nextLines.x1
|
if (center.index === 0) {
|
||||||
|
coords = [
|
||||||
|
{ x: linesArray[1].x1, y: linesArray[1].y1 },
|
||||||
|
{ x: center.x1, y: center.y1 },
|
||||||
|
{ x: linesArray[0].x2, y: linesArray[0].y2 },
|
||||||
|
]
|
||||||
|
} else {
|
||||||
|
coords = [
|
||||||
|
{ x: linesArray[0].x1, y: linesArray[0].y1 },
|
||||||
|
{ x: center.x1, y: center.y1 },
|
||||||
|
{ x: linesArray[1].x2, y: linesArray[1].y2 },
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
// Step 2: Calculate intersection point
|
const adjust1 = coords[0].x - coords[1].x
|
||||||
|
const height1 = coords[1].y - coords[0].y
|
||||||
|
const angle1 = Math.abs(Math.round(Math.atan(adjust1 / height1) * (180 / Math.PI) * 1000) / 1000)
|
||||||
|
|
||||||
let xIntersectPrev = 0
|
const adjust2 = coords[2].x - coords[1].x
|
||||||
let yIntersectPrev = 0
|
const height2 = coords[2].y - coords[1].y
|
||||||
let xIntersectNext = 0
|
const angle2 = Math.abs(Math.round(Math.atan(adjust2 / height2) * (180 / Math.PI) * 1000) / 1000)
|
||||||
let yIntersectNext = 0
|
const angle3 = 180 - (angle1 + angle2)
|
||||||
|
|
||||||
let biggerEndPoint = prevLines.x1 > nextLines.x2 ? 'top' : 'bottom'
|
const charlie = 173.3 + 3 // 평행선길이 약간 여유를줌
|
||||||
console.log('prevLines.x1', prevLines.x1)
|
const alpha = (charlie * Math.sin((angle1 * Math.PI) / 180)) / Math.sin((angle3 * Math.PI) / 180)
|
||||||
console.log('nextLines.x2', nextLines.x2)
|
const beta = Math.sqrt(alpha ** 2 + charlie ** 2 - 2 * alpha * charlie * Math.cos((angle2 * Math.PI) / 180))
|
||||||
console.log('biggerEndPoint', biggerEndPoint)
|
|
||||||
|
|
||||||
//bottom일 경우
|
const h = beta * Math.sin((angle1 * Math.PI) / 180) // 높이
|
||||||
xIntersectPrev = prevLines.x1
|
const sign = Math.sign(coords[0].x - coords[1].x) // 진행방향
|
||||||
yIntersectPrev = m1 * xIntersectPrev + c1
|
const top = coords[1].x + sign * h // 변경되는 높이 좌표 값
|
||||||
xIntersectNext = prevLines.x1
|
|
||||||
yIntersectNext = m2 * xIntersectNext + c2
|
|
||||||
|
|
||||||
let lineCoords
|
// const line3 = new QLine([coords[1].x, coords[1].y, top, coords[1].y], {
|
||||||
let polygonCoords
|
// stroke: 'blue',
|
||||||
let ratio = 1
|
// strokeWidth: 1,
|
||||||
|
// selectable: true,
|
||||||
|
// })
|
||||||
|
// canvas?.add(line3)
|
||||||
|
|
||||||
if (biggerEndPoint === 'top') {
|
const pointX1 = top
|
||||||
//윗쪽이이 더 밑이면 아래 라인에 절편으로 계산
|
const pointY1 = coords[0].y + ((coords[0].x - top) / (coords[0].x - coords[1].x)) * (coords[1].y - coords[0].y)
|
||||||
lineCoords = [prevLines.x1, yIntersectNext, xIntersectNext, yIntersectNext]
|
const pointX2 = top
|
||||||
polygonCoords = [
|
const pointY2 = coords[2].y + ((coords[2].x - top) / (coords[2].x - coords[1].x)) * (coords[1].y - coords[2].y)
|
||||||
{ x: prevLines.x1, y: yIntersectNext },
|
|
||||||
{ x: xIntersectNext, y: yIntersectNext },
|
|
||||||
{ x: overlapCoords.x, y: overlapCoords.y },
|
|
||||||
]
|
|
||||||
ratio = moduleWidthLength / Math.abs(prevLines.x1 - xIntersectNext)
|
|
||||||
} else {
|
|
||||||
lineCoords = [xIntersectPrev, prevLines.y1, xIntersectPrev, yIntersectPrev]
|
|
||||||
polygonCoords = [
|
|
||||||
{ x: xIntersectNext, y: prevLines.y1 },
|
|
||||||
{ x: xIntersectNext, y: yIntersectNext },
|
|
||||||
{ x: overlapCoords.x, y: overlapCoords.y },
|
|
||||||
]
|
|
||||||
ratio = moduleWidthLength / Math.abs(prevLines.y1 - yIntersectNext)
|
|
||||||
}
|
|
||||||
|
|
||||||
const tempTriangle = new QPolygon(polygonCoords, {
|
const finalLine = new QLine([pointX1, pointY1, pointX2, pointY2], {
|
||||||
fill: 'transparent',
|
stroke: 'red',
|
||||||
stroke: 'green',
|
strokeWidth: 1,
|
||||||
strokeWidth: 2,
|
selectable: true,
|
||||||
originX: 'left',
|
})
|
||||||
strokeDashArray: [5, 5],
|
canvas?.add(finalLine)
|
||||||
// fontSize: 15,
|
canvas?.renderAll()
|
||||||
selectable: true,
|
|
||||||
|
const rtnObj = { target: idx === 0 ? 'left' : 'right', x1: pointX1, y1: pointY1, x2: pointX2, y2: pointY2 }
|
||||||
|
rtnObjArray.push(rtnObj)
|
||||||
|
++idx
|
||||||
})
|
})
|
||||||
|
|
||||||
// canvas.add(tempTriangle)
|
|
||||||
|
|
||||||
let cloneCoords = []
|
|
||||||
tempTriangle.clone((clone) => {
|
|
||||||
clone.scale(ratio)
|
|
||||||
cloneCoords = clone.getCurrentPoints()
|
|
||||||
// canvas.add(clone)
|
|
||||||
})
|
|
||||||
|
|
||||||
canvas.remove(tempTriangle)
|
|
||||||
|
|
||||||
//left에선 가장 왼쪽
|
|
||||||
const vertexPoints = cloneCoords.reduce((acc, point, index) => (acc['x'] < point['x'] ? acc : point))
|
|
||||||
const differenceDistance = overlapCoords.y - vertexPoints.y
|
|
||||||
|
|
||||||
const newTriangleCoords = cloneCoords.map((point) => {
|
|
||||||
return { x: point.x, y: point.y + differenceDistance }
|
|
||||||
})
|
|
||||||
|
|
||||||
// const newTriangle1 = new QPolygon(newTriangleCoords, {
|
|
||||||
// fill: 'transparent',
|
|
||||||
// stroke: 'red',
|
|
||||||
// strokeWidth: 1,
|
|
||||||
// selectable: true,
|
|
||||||
// fontSize: 14,
|
|
||||||
// })
|
|
||||||
// canvas.add(newTriangle1)
|
|
||||||
|
|
||||||
const deleteLeftPoint = newTriangleCoords.reduce((acc, point) => (acc['x'] < point['x'] ? acc : point))
|
|
||||||
const deleteIndex = newTriangleCoords.indexOf(deleteLeftPoint)
|
|
||||||
if (deleteIndex !== -1) newTriangleCoords.splice(deleteIndex, 1)
|
|
||||||
|
|
||||||
const newLine = new QLine([newTriangleCoords[0].x, newTriangleCoords[0].y, newTriangleCoords[1].x, newTriangleCoords[1].y], {
|
|
||||||
fill: 'transparent',
|
|
||||||
stroke: 'red',
|
|
||||||
strokeWidth: 2,
|
|
||||||
viewLengthText: false,
|
|
||||||
// selectable: true,
|
|
||||||
fontSize: 14,
|
|
||||||
})
|
|
||||||
canvas.add(newLine)
|
|
||||||
return newLine
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function sortLinesByTopLeft(surface) {
|
const findSetupSurfaceMaxLines = (surface) => {
|
||||||
// 좌측 상단 기준으로 정렬
|
const leftFlow = surface.lines.reduce(
|
||||||
const sortedLines = surface.lines.sort((a, b) => {
|
(acc, line, index) => {
|
||||||
// x1, y1 값을 기준으로 정렬
|
if (line.x1 < acc.x1 || (line.x1 === acc.x1 && line.y1 < acc.y1)) {
|
||||||
if (a.x1 !== b.x1) {
|
return { x1: line.x1, y1: line.y1 }
|
||||||
return a.x1 - b.x1 // x1 기준 정렬
|
}
|
||||||
} else {
|
return acc
|
||||||
return a.y1 - b.y1 // x1이 같으면 y1 기준 정렬
|
},
|
||||||
}
|
{ x1: Infinity, y1: Infinity, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스
|
||||||
})
|
)
|
||||||
|
|
||||||
// 정렬된 결과를 기반으로 좌표 재정렬
|
const rightFlow = surface.lines.reduce(
|
||||||
sortedLines.forEach((line) => {
|
(acc, line, index) => {
|
||||||
// 좌측 상단이 (0,0) 기준이 되도록 좌표 이동
|
if (line.x1 > acc.x1 || (line.x1 === acc.x1 && line.y1 > acc.y1)) {
|
||||||
const minX = Math.min(line.x1, line.x2)
|
return { x1: line.x1, y1: line.y1 }
|
||||||
const minY = Math.min(line.y1, line.y2)
|
}
|
||||||
|
return acc
|
||||||
|
},
|
||||||
|
{ x1: 0, y1: 0, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스
|
||||||
|
)
|
||||||
|
|
||||||
line.set({
|
const topFlow = surface.lines.reduce(
|
||||||
x1: line.x1 - minX,
|
(acc, line, index) => {
|
||||||
y1: line.y1 - minY,
|
if (line.y1 < acc.y1 || (line.y1 === acc.y1 && line.x1 < acc.x1)) {
|
||||||
x2: line.x2 - minX,
|
return { x1: line.x1, y1: line.y1 }
|
||||||
y2: line.y2 - minY,
|
}
|
||||||
})
|
return acc
|
||||||
})
|
},
|
||||||
|
{ x1: Infinity, y1: Infinity, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스
|
||||||
|
)
|
||||||
|
|
||||||
surface.set({
|
const bottomFlow = surface.lines.reduce(
|
||||||
sortedLines: sortedLines,
|
(acc, line, index) => {
|
||||||
})
|
if (line.y1 > acc.y1 || (line.y1 === acc.y1 && line.x1 > acc.x1)) {
|
||||||
|
return { x1: line.x1, y1: line.y1 }
|
||||||
|
}
|
||||||
|
return acc
|
||||||
|
},
|
||||||
|
{ x1: 0, y1: 0, index: -1 }, // 초기값: 무한대와 유효하지 않은 인덱스
|
||||||
|
)
|
||||||
|
|
||||||
return sortedLines
|
const obj = {
|
||||||
|
left: leftFlow,
|
||||||
|
right: rightFlow,
|
||||||
|
top: topFlow,
|
||||||
|
bottom: bottomFlow,
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user