dev #746
@ -17,7 +17,6 @@ import {
|
|||||||
currentCanvasPlanState,
|
currentCanvasPlanState,
|
||||||
isManualModuleLayoutSetupState,
|
isManualModuleLayoutSetupState,
|
||||||
isManualModuleSetupState,
|
isManualModuleSetupState,
|
||||||
moduleSetupOptionState,
|
|
||||||
toggleManualSetupModeState,
|
toggleManualSetupModeState,
|
||||||
} from '@/store/canvasAtom'
|
} from '@/store/canvasAtom'
|
||||||
import { loginUserStore } from '@/store/commonAtom'
|
import { loginUserStore } from '@/store/commonAtom'
|
||||||
@ -48,7 +47,6 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
|
|||||||
const [checkedModules, setCheckedModules] = useRecoilState(checkedModuleState)
|
const [checkedModules, setCheckedModules] = useRecoilState(checkedModuleState)
|
||||||
const [roofs, setRoofs] = useState(addedRoofs)
|
const [roofs, setRoofs] = useState(addedRoofs)
|
||||||
const [manualSetupMode, setManualSetupMode] = useRecoilState(toggleManualSetupModeState)
|
const [manualSetupMode, setManualSetupMode] = useRecoilState(toggleManualSetupModeState)
|
||||||
const [moduleSetupOption, setModuleSetupOption] = useRecoilState(moduleSetupOptionState)
|
|
||||||
const [layoutSetup, setLayoutSetup] = useState([{}])
|
const [layoutSetup, setLayoutSetup] = useState([{}])
|
||||||
const {
|
const {
|
||||||
selectedModules,
|
selectedModules,
|
||||||
@ -213,12 +211,8 @@ export default function BasicSetting({ id, pos = { x: 50, y: 230 } }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleManualModuleSetup = () => {
|
const handleManualModuleSetup = () => {
|
||||||
const nextManual = !isManualModuleSetup
|
setManualSetupMode(`manualSetup_${!isManualModuleSetup}`)
|
||||||
setManualSetupMode(`manualSetup_${nextManual}`)
|
setIsManualModuleSetup(!isManualModuleSetup)
|
||||||
setIsManualModuleSetup(nextManual)
|
|
||||||
if (nextManual) {
|
|
||||||
setModuleSetupOption((prev) => ({ ...prev, isChidori: true }))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleManualModuleLayoutSetup = () => {
|
const handleManualModuleLayoutSetup = () => {
|
||||||
|
|||||||
@ -1756,6 +1756,11 @@ export function useMode() {
|
|||||||
offsetEdges.push(createOffsetEdge(edge, dx, dy))
|
offsetEdges.push(createOffsetEdge(edge, dx, dy))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 폴리곤의 감김 방향(signed area)을 구한다
|
||||||
|
const signedArea = bevelJoin
|
||||||
|
? polygon.edges.reduce((sum, edge) => sum + (edge.vertex1.x * edge.vertex2.y - edge.vertex2.x * edge.vertex1.y), 0)
|
||||||
|
: 0
|
||||||
|
|
||||||
const vertices = []
|
const vertices = []
|
||||||
|
|
||||||
offsetEdges.forEach((thisEdge, i) => {
|
offsetEdges.forEach((thisEdge, i) => {
|
||||||
@ -1765,9 +1770,22 @@ export function useMode() {
|
|||||||
if (!vertex.isIntersectionOutside || !bevelJoin) {
|
if (!vertex.isIntersectionOutside || !bevelJoin) {
|
||||||
vertices.push({ x: vertex.x, y: vertex.y })
|
vertices.push({ x: vertex.x, y: vertex.y })
|
||||||
} else {
|
} else {
|
||||||
// 둔각 + bevelJoin: offset edge 끝점 사용
|
// 꼭짓점의 볼록/오목 판별 (cross product와 signed area 비교)
|
||||||
vertices.push({ x: prevEdge.vertex2.x, y: prevEdge.vertex2.y })
|
const origPrev = polygon.edges[(i + polygon.edges.length - 1) % polygon.edges.length]
|
||||||
vertices.push({ x: thisEdge.vertex1.x, y: thisEdge.vertex1.y })
|
const origThis = polygon.edges[i]
|
||||||
|
const cross =
|
||||||
|
(origPrev.vertex2.x - origPrev.vertex1.x) * (origThis.vertex2.y - origThis.vertex1.y) -
|
||||||
|
(origPrev.vertex2.y - origPrev.vertex1.y) * (origThis.vertex2.x - origThis.vertex1.x)
|
||||||
|
const isConvex = cross * signedArea > 0
|
||||||
|
|
||||||
|
if (isConvex) {
|
||||||
|
// 볼록 꼭짓점: bevel 적용 (offset edge 끝점 사용)
|
||||||
|
vertices.push({ x: prevEdge.vertex2.x, y: prevEdge.vertex2.y })
|
||||||
|
vertices.push({ x: thisEdge.vertex1.x, y: thisEdge.vertex1.y })
|
||||||
|
} else {
|
||||||
|
// 오목 꼭짓점: 교차점 사용 (90도 유지)
|
||||||
|
vertices.push({ x: vertex.x, y: vertex.y })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -1795,6 +1813,11 @@ export function useMode() {
|
|||||||
offsetEdges.push(createOffsetEdge(edge, dx, dy))
|
offsetEdges.push(createOffsetEdge(edge, dx, dy))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 폴리곤의 감김 방향(signed area)을 구한다
|
||||||
|
const signedArea = bevelJoin
|
||||||
|
? polygon.edges.reduce((sum, edge) => sum + (edge.vertex1.x * edge.vertex2.y - edge.vertex2.x * edge.vertex1.y), 0)
|
||||||
|
: 0
|
||||||
|
|
||||||
const vertices = []
|
const vertices = []
|
||||||
|
|
||||||
offsetEdges.forEach((thisEdge, i) => {
|
offsetEdges.forEach((thisEdge, i) => {
|
||||||
@ -1804,9 +1827,22 @@ export function useMode() {
|
|||||||
if (!vertex.isIntersectionOutside || !bevelJoin) {
|
if (!vertex.isIntersectionOutside || !bevelJoin) {
|
||||||
vertices.push({ x: vertex.x, y: vertex.y })
|
vertices.push({ x: vertex.x, y: vertex.y })
|
||||||
} else {
|
} else {
|
||||||
// 둔각 + bevelJoin: offset edge 끝점 사용
|
// 꼭짓점의 볼록/오목 판별 (cross product와 signed area 비교)
|
||||||
vertices.push({ x: prevEdge.vertex2.x, y: prevEdge.vertex2.y })
|
const origPrev = polygon.edges[(i + polygon.edges.length - 1) % polygon.edges.length]
|
||||||
vertices.push({ x: thisEdge.vertex1.x, y: thisEdge.vertex1.y })
|
const origThis = polygon.edges[i]
|
||||||
|
const cross =
|
||||||
|
(origPrev.vertex2.x - origPrev.vertex1.x) * (origThis.vertex2.y - origThis.vertex1.y) -
|
||||||
|
(origPrev.vertex2.y - origPrev.vertex1.y) * (origThis.vertex2.x - origThis.vertex1.x)
|
||||||
|
const isConvex = cross * signedArea > 0
|
||||||
|
|
||||||
|
if (isConvex) {
|
||||||
|
// 볼록 꼭짓점: bevel 적용 (offset edge 끝점 사용)
|
||||||
|
vertices.push({ x: prevEdge.vertex2.x, y: prevEdge.vertex2.y })
|
||||||
|
vertices.push({ x: thisEdge.vertex1.x, y: thisEdge.vertex1.y })
|
||||||
|
} else {
|
||||||
|
// 오목 꼭짓점: 교차점 사용 (90도 유지)
|
||||||
|
vertices.push({ x: vertex.x, y: vertex.y })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user