Merge branch 'feature/test' of https://git.jetbrains.space/nalpari/q-cast-iii/qcast-front into feature/test

This commit is contained in:
hyojun.choi 2024-07-23 18:05:06 +09:00
commit 0402b8ef05
2 changed files with 225 additions and 9 deletions

View File

@ -38,6 +38,7 @@ export default function Roof2() {
zoomOut,
zoom,
togglePolygonLine,
handleOuterlinesTest,
handleOuterlinesTest2,
applyTemplateB,
makeRoofPatternPolygon,

View File

@ -874,10 +874,17 @@ export function useMode() {
/**
* 지붕 외곽선 생성
*/
const handleOuterlinesTest = (polygon, offset = 71) => {
var offsetPoints = []
const handleOuterlinesTest = (offsetInputX, offsetInputY = 0) => {
const polygon = drawWallPolygon()
debugger
let offsetPoints = []
const originalMax = 71
const transformedMax = 100
offsetInputY = offsetInputY !== 0 ? offsetInputY : offsetInputX
const offsetX = (offsetInputX / transformedMax) * originalMax * 2
const offsetY = (offsetInputY / transformedMax) * originalMax * 2
const sortedIndex = getStartIndex(polygon.lines)
let tmpArraySorted = rearrangeArray(polygon.lines, sortedIndex)
@ -930,17 +937,14 @@ export function useMode() {
// 오프셋 적용
var offsetPoint = {
x1: current.x + unitNormal.x * offset,
y1: current.y + unitNormal.y * offset,
x1: current.x + unitNormal.x * offsetX,
y1: current.y + unitNormal.y * offsetY,
}
offsetPoints.push(offsetPoint)
}
const roof = makePolygon(offsetPoints)
setRoof(roof)
return roof
makePolygon(offsetPoints)
}
/**
@ -1059,6 +1063,8 @@ export function useMode() {
} else if (polygon.lines.length === 6) {
//6각형
handleOuterLineTemplateA6Points(polygon)
} else if (polygon.lines.length === 8) {
handleOuterLineTemplateA8Points(polygon)
}
}
@ -1875,6 +1881,214 @@ export function useMode() {
canvas.renderAll()
}
const handleOuterLineTemplateA8Points = (polygon, offsetInputX = 50, offsetInputY = 20) => {
let offsetPoints = []
const originalMax = 71
const transformedMax = 100
let lines = [] //내각라인
let outLines = [] //아웃라인
let halfLength = 0 //선길이
const dashedCenterLineOpt = {
stroke: 'black',
strokeWidth: 4,
property: 'centerLine',
strokeDashArray: [5, 5],
fontSize: 14,
}
const centerLineOpt = {
stroke: 'blue',
strokeWidth: 5,
property: 'bigHoriCenter',
fontSize: 14,
}
// 폴리곤의 각 변을 선으로 생성
for (let i = 0; i < polygon.points.length; i++) {
const start = polygon.points[i]
const end = polygon.points[(i + 1) % polygon.points.length] // 다음 점, 마지막 점의 경우 첫 점으로
const color = i % 2 === 0 ? '#A0D468' : 'skyblue'
const line = new QLine([start.x, start.y, end.x, end.y], {
stroke: color,
strokeWidth: 2,
property: 'normal',
fontSize: 14,
})
// 선을 배열에 추가
lines.push(line)
canvas.add(line)
}
offsetInputY = offsetInputY !== 0 ? offsetInputY : offsetInputX
const sortedIndex = getStartIndex(polygon.lines)
let tmpArraySorted = rearrangeArray(polygon.lines, sortedIndex)
if (tmpArraySorted[0].direction === 'right') {
//시계방향
tmpArraySorted = tmpArraySorted.reverse() //그럼 배열을 거꾸로 만들어서 무조건 반시계방향으로 배열 보정
}
setSortedArray(tmpArraySorted) //recoil에 넣음
const points = tmpArraySorted.map((line) => ({
x: line.x1,
y: line.y1,
}))
// 외적을 계산하는 함수
function crossProduct(p1, p2, p3) {
const dx1 = p2.x - p1.x
const dy1 = p2.y - p1.y
const dx2 = p3.x - p2.x
const dy2 = p3.y - p2.y
return dx1 * dy2 - dy1 * dx2
}
let concaveIndices = [] //볼록한 부분 인덱스 배열
let concavePointIndices = [] //오목한 부분 인덱스 배열
// 오목한 부분 찾기
function findConcavePointIndices(points) {
let concaveIndices = []
for (let i = 0; i < points.length; i++) {
const p1 = points[i]
const p2 = points[(i + 1) % points.length]
const p3 = points[(i + 2) % points.length]
const cross = crossProduct(p1, p2, p3)
if (cross < 0) {
concaveIndices.push((i + 1) % points.length)
} else {
concavePointIndices.push((i + 1) % points.length)
}
}
return concaveIndices
}
// 오목한 부분 인덱스 찾기
concaveIndices = findConcavePointIndices(points) //오목한 부분을 제외한 인덱스
const concavePoints = concaveIndices.map((index) => points[index])
for (var i = 0; i < points.length; i++) {
var prev = points[(i - 1 + points.length) % points.length]
var current = points[i]
var next = points[(i + 1) % points.length]
// 두 벡터 계산 (prev -> current, current -> next)
var vector1 = { x: current.x - prev.x, y: current.y - prev.y }
var vector2 = { x: next.x - current.x, y: next.y - current.y }
// 벡터의 길이 계산
var length1 = Math.sqrt(vector1.x * vector1.x + vector1.y * vector1.y)
var length2 = Math.sqrt(vector2.x * vector2.x + vector2.y * vector2.y)
// 벡터를 단위 벡터로 정규화
var unitVector1 = { x: vector1.x / length1, y: vector1.y / length1 }
var unitVector2 = { x: vector2.x / length2, y: vector2.y / length2 }
// 법선 벡터 계산 (왼쪽 방향)
var normal1 = { x: -unitVector1.y, y: unitVector1.x }
var normal2 = { x: -unitVector2.y, y: unitVector2.x }
// 법선 벡터 평균 계산
var averageNormal = {
x: (normal1.x + normal2.x) / 2,
y: (normal1.y + normal2.y) / 2,
}
// 평균 법선 벡터를 단위 벡터로 정규화
var lengthNormal = Math.sqrt(averageNormal.x * averageNormal.x + averageNormal.y * averageNormal.y)
var unitNormal = {
x: averageNormal.x / lengthNormal,
y: averageNormal.y / lengthNormal,
}
let offsetX
let offsetY
if (concavePointIndices[0] === i || concavePointIndices[1] === i) {
// 인덱스가 배열이랑 같으면
if ((concavePointIndices[0] === 4 && concavePointIndices[1] === 5) || (concavePointIndices[0] === 2 && concavePointIndices[1] === 3)) {
offsetX = 1
offsetY = (offsetInputY / transformedMax) * originalMax * 2
} else {
offsetX = (offsetInputX / transformedMax) * originalMax * 2
offsetY = 1
}
} else {
offsetX = (offsetInputX / transformedMax) * originalMax * 2
offsetY = (offsetInputY / transformedMax) * originalMax * 2
}
// 오프셋 적용
var offsetPoint = {
x1: current.x + unitNormal.x * offsetX,
y1: current.y + unitNormal.y * offsetY,
}
offsetPoints.push(offsetPoint)
}
const outlinePolygon = makePolygon(offsetPoints)
// 아웃라인 폴리곤의 각 변을 선으로 생성
for (let i = 0; i < outlinePolygon.points.length; i++) {
const start = outlinePolygon.points[i]
const end = outlinePolygon.points[(i + 1) % outlinePolygon.points.length] // 다음 점, 마지막 점의 경우 첫 점으로
const line = new QLine([start.x, start.y, end.x, end.y], {
stroke: 'blue',
strokeWidth: 2,
property: 'normal',
fontSize: 14,
})
// 선을 배열에 추가
outLines.push(line)
canvas.add(line)
}
canvas?.remove(outlinePolygon) //임시 폴리곤을 삭제
canvas?.remove(outLines[concavePointIndices[0]]) //가운데 제외되는 선을 지운다
//라인들을 좌측에서 -> 우측으로 그리는거처럼 데이터 보정
outLines.forEach((outline, index) => {
let minX, minY, maxX, maxY
if (outline.x2 < outline.x1 || outline.y2 < outline.y1) {
outLines[index].x1 = outline.x2
outLines[index].y1 = outline.y2
outLines[index].x2 = outline.x1
outLines[index].y2 = outline.y1
outLines[index].line.x1 = minX
outLines[index].line.y1 = minY
outLines[index].line.x2 = maxX
outLines[index].line.y2 = maxY
}
})
// for (let i = 0; i < outLines.length; i++) {
// if (!i % 2 === 0) {
// if (i === concavePointIndices[0] - 1 || i === concavePointIndices[1] + 1) {
// //배열 3번이나 5번일때
// } else {
// }
// }
// }
let parallelLines = concavePointIndices[0] + 4 //들어간선에 무조건 평행하는 선 찾기
if (parallelLines > outLines.length) {
parallelLines = outLines[concavePointIndices[0] + 4 - outLines.length - 1]
}
canvas.renderAll()
}
/**
* 템플릿 B 적용
*/
@ -2371,6 +2585,7 @@ export function useMode() {
zoomOut,
zoom,
togglePolygonLine,
handleOuterlinesTest,
handleOuterlinesTest2,
makeRoofPatternPolygon,
}