Merge pull request 'dev' (#502) from dev into prd-deploy
Reviewed-on: #502
This commit is contained in:
commit
9c9ca8f026
@ -11,6 +11,7 @@ import { moduleSelectionDataState } from '@/store/selectedModuleOptions'
|
||||
import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController'
|
||||
import { isObjectNotEmpty } from '@/util/common-utils'
|
||||
import { normalizeDecimal} from '@/util/input-utils'
|
||||
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||
|
||||
export default function Module({ setTabNum }) {
|
||||
const { getMessage } = useMessage()
|
||||
@ -185,11 +186,23 @@ export default function Module({ setTabNum }) {
|
||||
<div className="eaves-keraba-td">
|
||||
<div className="outline-form">
|
||||
<div className="grid-select mr10">
|
||||
<input
|
||||
type="text"
|
||||
{/*<input*/}
|
||||
{/* type="text"*/}
|
||||
{/* className="input-origin block"*/}
|
||||
{/* value={inputInstallHeight}*/}
|
||||
{/* onChange={(e) => setInputInstallHeight(normalizeDecimal(e.target.value))}*/}
|
||||
{/*/>*/}
|
||||
<CalculatorInput
|
||||
id=""
|
||||
name=""
|
||||
label=""
|
||||
className="input-origin block"
|
||||
value={inputInstallHeight}
|
||||
onChange={(e) => setInputInstallHeight(normalizeDecimal(e.target.value))}
|
||||
onChange={(value) => setInputInstallHeight(value)}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<span className="thin">m</span>
|
||||
|
||||
@ -10,6 +10,7 @@ import { useModuleBasicSetting } from '@/hooks/module/useModuleBasicSetting'
|
||||
import { useCommonCode } from '@/hooks/common/useCommonCode'
|
||||
import Swal from 'sweetalert2'
|
||||
import { normalizeDecimal} from '@/util/input-utils'
|
||||
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||
|
||||
export const Orientation = forwardRef((props, ref) => {
|
||||
const { getMessage } = useMessage()
|
||||
@ -436,13 +437,26 @@ export const Orientation = forwardRef((props, ref) => {
|
||||
<label htmlFor="ch99">{getMessage('modal.module.basic.setting.orientation.setting.angle.passivity')}</label>
|
||||
</div>
|
||||
<div className="input-grid mr10" style={{ width: '60px' }}>
|
||||
<input
|
||||
type="text"
|
||||
{/*<input*/}
|
||||
{/* type="text"*/}
|
||||
{/* className="input-origin block"*/}
|
||||
{/* value={inputCompasDeg}*/}
|
||||
{/* readOnly={!hasAnglePassivity}*/}
|
||||
{/* placeholder={0}*/}
|
||||
{/* onChange={(e) => checkDegree(e.target.value)}*/}
|
||||
{/*/>*/}
|
||||
<CalculatorInput
|
||||
id=""
|
||||
name=""
|
||||
label=""
|
||||
className="input-origin block"
|
||||
value={inputCompasDeg}
|
||||
readOnly={!hasAnglePassivity}
|
||||
placeholder={0}
|
||||
onChange={(e) => checkDegree(e.target.value)}
|
||||
onChange={(value) => setInputCompasDeg(value)}
|
||||
options={{
|
||||
allowNegative: true,
|
||||
allowDecimal: false
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<span className="thin">°</span>
|
||||
@ -533,7 +547,19 @@ export const Orientation = forwardRef((props, ref) => {
|
||||
<div className="outline-form mt15">
|
||||
<span>{getMessage('modal.module.basic.setting.module.placement.area')}</span>
|
||||
<div className="input-grid mr10" style={{ width: '60px' }}>
|
||||
<input type="text" className="input-origin block" value={inputMargin} onChange={(e) => setInputMargin(normalizeDecimal(e.target.value))} />
|
||||
{/*<input type="text" className="input-origin block" value={inputMargin} onChange={(e) => setInputMargin(normalizeDecimal(e.target.value))} />*/}
|
||||
<CalculatorInput
|
||||
id=""
|
||||
name=""
|
||||
label=""
|
||||
className="input-origin block"
|
||||
value={inputMargin}
|
||||
onChange={(value) => setInputMargin(value)}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<span className="thin">m</span>
|
||||
</div>
|
||||
@ -561,11 +587,23 @@ export const Orientation = forwardRef((props, ref) => {
|
||||
<div className="outline-form">
|
||||
<span>{getMessage('modal.module.basic.setting.module.fitting.height')}</span>
|
||||
<div className="input-grid mr10">
|
||||
<input
|
||||
type="text"
|
||||
{/*<input*/}
|
||||
{/* type="text"*/}
|
||||
{/* className="input-origin block"*/}
|
||||
{/* value={inputInstallHeight}*/}
|
||||
{/* onChange={(e) => handleChangeInstallHeight(normalizeDecimal(e.target.value))}*/}
|
||||
{/*/>*/}
|
||||
<CalculatorInput
|
||||
id=""
|
||||
name=""
|
||||
label=""
|
||||
className="input-origin block"
|
||||
value={inputInstallHeight}
|
||||
onChange={(e) => handleChangeInstallHeight(normalizeDecimal(e.target.value))}
|
||||
onChange={(value) => handleChangeInstallHeight(value)}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<span className="thin">m</span>
|
||||
@ -589,11 +627,23 @@ export const Orientation = forwardRef((props, ref) => {
|
||||
<div className="outline-form">
|
||||
<span>{getMessage('modal.module.basic.setting.module.standard.snowfall.amount')}</span>
|
||||
<div className="input-grid mr10">
|
||||
<input
|
||||
type="text"
|
||||
{/*<input*/}
|
||||
{/* type="text"*/}
|
||||
{/* className="input-origin block"*/}
|
||||
{/* value={inputVerticalSnowCover}*/}
|
||||
{/* onChange={(e) => handleChangeVerticalSnowCover(normalizeDecimal(e.target.value))}*/}
|
||||
{/*/>*/}
|
||||
<CalculatorInput
|
||||
id=""
|
||||
name=""
|
||||
label=""
|
||||
className="input-origin block"
|
||||
value={inputVerticalSnowCover}
|
||||
onChange={(e) => handleChangeVerticalSnowCover(normalizeDecimal(e.target.value))}
|
||||
value={inputInstallHeight}
|
||||
onChange={(value) => handleChangeVerticalSnowCover(value)}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<span className="thin">cm</span>
|
||||
|
||||
@ -10,6 +10,7 @@ import { forwardRef, useContext, useEffect, useImperativeHandle, useRef, useStat
|
||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||
import Swal from 'sweetalert2'
|
||||
import { normalizeDigits } from '@/util/input-utils'
|
||||
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||
|
||||
const Trestle = forwardRef((props, ref) => {
|
||||
const { tabNum, setTabNum, trestleTrigger, roofs, setRoofs, moduleSelectionData, setModuleSelectionData, setRoofsStore } = props
|
||||
@ -885,12 +886,24 @@ const Trestle = forwardRef((props, ref) => {
|
||||
<div className="outline-form mr15">
|
||||
<span>{getMessage('modal.module.basic.setting.module.placement.area.eaves')}</span>
|
||||
<div className="input-grid mr10">
|
||||
<input
|
||||
type="number"
|
||||
{/*<input*/}
|
||||
{/* type="number"*/}
|
||||
{/* className="input-origin block"*/}
|
||||
{/* value={eavesMargin ?? 0}*/}
|
||||
{/* // onChange={(e) => dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, eavesMargin: e.target.value } })}*/}
|
||||
{/* onChange={(e) => setEavesMargin(+e.target.value)}*/}
|
||||
{/*/>*/}
|
||||
<CalculatorInput
|
||||
id=""
|
||||
name=""
|
||||
label=""
|
||||
className="input-origin block"
|
||||
value={eavesMargin ?? 0}
|
||||
// onChange={(e) => dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, eavesMargin: e.target.value } })}
|
||||
onChange={(e) => setEavesMargin(+e.target.value)}
|
||||
onChange={(value) => setEavesMargin(value)}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
@ -898,12 +911,24 @@ const Trestle = forwardRef((props, ref) => {
|
||||
<div className="outline-form mr15">
|
||||
<span>{getMessage('modal.module.basic.setting.module.placement.area.ridge')}</span>
|
||||
<div className="input-grid mr10">
|
||||
<input
|
||||
type="number"
|
||||
{/*<input*/}
|
||||
{/* type="number"*/}
|
||||
{/* className="input-origin block"*/}
|
||||
{/* value={ridgeMargin ?? 0}*/}
|
||||
{/* // onChange={(e) => dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, ridgeMargin: e.target.value } })}*/}
|
||||
{/* onChange={(e) => setRidgeMargin(+e.target.value)}*/}
|
||||
{/*/>*/}
|
||||
<CalculatorInput
|
||||
id=""
|
||||
name=""
|
||||
label=""
|
||||
className="input-origin block"
|
||||
value={ridgeMargin ?? 0}
|
||||
// onChange={(e) => dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, ridgeMargin: e.target.value } })}
|
||||
onChange={(e) => setRidgeMargin(+e.target.value)}
|
||||
onChange={(value) => setRidgeMargin(value)}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
@ -911,12 +936,24 @@ const Trestle = forwardRef((props, ref) => {
|
||||
<div className="outline-form ">
|
||||
<span>{getMessage('modal.module.basic.setting.module.placement.area.keraba')}</span>
|
||||
<div className="input-grid mr10">
|
||||
<input
|
||||
type="number"
|
||||
{/*<input*/}
|
||||
{/* type="number"*/}
|
||||
{/* className="input-origin block"*/}
|
||||
{/* value={kerabaMargin ?? 0}*/}
|
||||
{/* // onChange={(e) => dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, kerabaMargin: e.target.value } })}*/}
|
||||
{/* onChange={(e) => setKerabaMargin(+e.target.value)}*/}
|
||||
{/*/>*/}
|
||||
<CalculatorInput
|
||||
id=""
|
||||
name=""
|
||||
label=""
|
||||
className="input-origin block"
|
||||
value={kerabaMargin ?? 0}
|
||||
// onChange={(e) => dispatch({ type: 'SET_TRESTLE_DETAIL', roof: { ...trestleState, kerabaMargin: e.target.value } })}
|
||||
onChange={(e) => setKerabaMargin(+e.target.value)}
|
||||
onChange={(value) => setKerabaMargin(value)}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<span className="thin">mm</span>
|
||||
|
||||
@ -851,12 +851,15 @@ export const usePolygon = () => {
|
||||
// innerLines와 polygonLines의 겹침을 확인하고 type 변경
|
||||
innerLines.forEach((innerLine) => {
|
||||
polygonLines.forEach((polygonLine) => {
|
||||
if (polygonLine.attributes.type === LINE_TYPE.WALLLINE.EAVES) {
|
||||
return
|
||||
}
|
||||
if (checkLineOverlap(innerLine, polygonLine)) {
|
||||
// innerLine의 type을 polygonLine의 type으로 변경
|
||||
if (innerLine.attributes && polygonLine.attributes.type) {
|
||||
// innerLine이 polygonLine보다 긴 경우 polygonLine.need를 false로 변경
|
||||
if (polygonLine.length < innerLine.length) {
|
||||
if (polygonLine.lineName !== 'eaveHelpLine') {
|
||||
if (polygonLine.lineName !== 'eaveHelpLine' || polygonLine.lineName !== 'eaveHelpLine') {
|
||||
polygonLine.need = false
|
||||
}
|
||||
}
|
||||
@ -1014,6 +1017,7 @@ export const usePolygon = () => {
|
||||
canvas.add(line)
|
||||
})
|
||||
canvas.renderAll()*/
|
||||
|
||||
polygonLines = polygonLines.filter((line) => line.need)
|
||||
|
||||
polygonLines.forEach((line) => {
|
||||
@ -1377,7 +1381,6 @@ export const usePolygon = () => {
|
||||
let newRoofs = getSplitRoofsPoints(allLines)
|
||||
|
||||
newRoofs = newRoofs.filter((roof) => roof.length !== 0)
|
||||
|
||||
newRoofs.forEach((roofPoint, index) => {
|
||||
let defense, pitch
|
||||
|
||||
@ -1411,6 +1414,124 @@ export const usePolygon = () => {
|
||||
}
|
||||
})
|
||||
|
||||
// representLines가 없다면 A,B타입중 하나임
|
||||
if (representLines.length === 0) {
|
||||
// 1. roofPoint로 폴리곤의 라인들을 생성
|
||||
const roofPolygonLines = []
|
||||
for (let i = 0; i < roofPoint.length; i++) {
|
||||
const nextIndex = (i + 1) % roofPoint.length
|
||||
const startPt = roofPoint[i]
|
||||
const endPt = roofPoint[nextIndex]
|
||||
roofPolygonLines.push({
|
||||
x1: startPt.x,
|
||||
y1: startPt.y,
|
||||
x2: endPt.x,
|
||||
y2: endPt.y,
|
||||
startPoint: startPt,
|
||||
endPoint: endPt,
|
||||
})
|
||||
}
|
||||
|
||||
// 3. 평행 여부 확인 함수
|
||||
const checkParallel = (line1, line2) => {
|
||||
const v1x = line1.x2 - line1.x1
|
||||
const v1y = line1.y2 - line1.y1
|
||||
const v2x = line2.x2 - line2.x1
|
||||
const v2y = line2.y2 - line2.y1
|
||||
|
||||
const length1 = Math.sqrt(v1x ** 2 + v1y ** 2)
|
||||
const length2 = Math.sqrt(v2x ** 2 + v2y ** 2)
|
||||
|
||||
if (length1 === 0 || length2 === 0) return false
|
||||
|
||||
const norm1x = v1x / length1
|
||||
const norm1y = v1y / length1
|
||||
const norm2x = v2x / length2
|
||||
const norm2y = v2y / length2
|
||||
|
||||
const EPSILON = 0.01
|
||||
const crossProduct = Math.abs(norm1x * norm2y - norm1y * norm2x)
|
||||
const dotProduct = norm1x * norm2x + norm1y * norm2y
|
||||
|
||||
return crossProduct < EPSILON || Math.abs(Math.abs(dotProduct) - 1) < EPSILON
|
||||
}
|
||||
|
||||
// 4. 점에서 라인까지의 거리 계산 함수
|
||||
const getDistanceFromPointToLine = (point, lineP1, lineP2) => {
|
||||
const A = point.x - lineP1.x
|
||||
const B = point.y - lineP1.y
|
||||
const C = lineP2.x - lineP1.x
|
||||
const D = lineP2.y - lineP1.y
|
||||
|
||||
const dot = A * C + B * D
|
||||
const lenSq = C * C + D * D
|
||||
let param = -1
|
||||
|
||||
if (lenSq !== 0) {
|
||||
param = dot / lenSq
|
||||
}
|
||||
|
||||
let xx, yy
|
||||
|
||||
if (param < 0) {
|
||||
xx = lineP1.x
|
||||
yy = lineP1.y
|
||||
} else if (param > 1) {
|
||||
xx = lineP2.x
|
||||
yy = lineP2.y
|
||||
} else {
|
||||
xx = lineP1.x + param * C
|
||||
yy = lineP1.y + param * D
|
||||
}
|
||||
|
||||
const dx = point.x - xx
|
||||
const dy = point.y - yy
|
||||
|
||||
return Math.sqrt(dx * dx + dy * dy)
|
||||
}
|
||||
|
||||
// 5. 두 평행한 라인 사이의 거리 계산 (한 라인의 중점에서 다른 라인까지의 거리)
|
||||
const getDistanceBetweenParallelLines = (line1, line2) => {
|
||||
const midPoint = {
|
||||
x: (line1.x1 + line1.x2) / 2,
|
||||
y: (line1.y1 + line1.y2) / 2,
|
||||
}
|
||||
return getDistanceFromPointToLine(midPoint, { x: line2.x1, y: line2.y1 }, { x: line2.x2, y: line2.y2 })
|
||||
}
|
||||
|
||||
// 6. roofPolygonLines의 모든 라인에서 평행하면서 가장 가까운 EAVES 라인 찾기
|
||||
let closestLine = null
|
||||
let minDistance = Infinity
|
||||
|
||||
roofPolygonLines.forEach((roofLine) => {
|
||||
;[...polygonLines, ...innerLines].forEach((line) => {
|
||||
// EAVES 타입만 필터링
|
||||
if (line.attributes?.type !== LINE_TYPE.WALLLINE.EAVES && line.attributes?.type !== LINE_TYPE.WALLLINE.EAVE_HELP_LINE) {
|
||||
return
|
||||
}
|
||||
|
||||
const lineObj = {
|
||||
x1: line.startPoint.x,
|
||||
y1: line.startPoint.y,
|
||||
x2: line.endPoint.x,
|
||||
y2: line.endPoint.y,
|
||||
}
|
||||
|
||||
if (checkParallel(roofLine, lineObj)) {
|
||||
const distance = getDistanceBetweenParallelLines(roofLine, lineObj)
|
||||
if (distance < minDistance && distance > 0) {
|
||||
minDistance = distance
|
||||
closestLine = line
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
if (closestLine) {
|
||||
representLines.push(closestLine)
|
||||
}
|
||||
}
|
||||
|
||||
// representLines중 가장 긴 line을 찾는다.
|
||||
representLines.forEach((line) => {
|
||||
if (!representLine) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user