Merge branch 'feature/test-jy' into dev

# Conflicts:
#	src/components/fabric/QPolygon.js
#	src/util/qpolygon-utils.js
This commit is contained in:
Jaeyoung Lee 2024-08-07 15:15:39 +09:00
commit 960056c17d
5 changed files with 1887 additions and 16 deletions

View File

@ -10,7 +10,6 @@ import { QLine } from '@/components/fabric/QLine'
import { getCanvasState, insertCanvasState } from '@/lib/canvas' import { getCanvasState, insertCanvasState } from '@/lib/canvas'
import { calculateIntersection } from '@/util/canvas-util' import { calculateIntersection } from '@/util/canvas-util'
import { QPolygon } from '@/components/fabric/QPolygon' import { QPolygon } from '@/components/fabric/QPolygon'
import offsetPolygon from '@/util/qpolygon-utils'
export default function Roof2() { export default function Roof2() {
const { canvas, handleRedo, handleUndo, setCanvasBackgroundWithDots, saveImage, addCanvas } = useCanvas('canvas') const { canvas, handleRedo, handleUndo, setCanvasBackgroundWithDots, saveImage, addCanvas } = useCanvas('canvas')
@ -51,6 +50,7 @@ export default function Roof2() {
applyTemplateB, applyTemplateB,
makeRoofPatternPolygon, makeRoofPatternPolygon,
createRoofRack, createRoofRack,
drawRoofPolygon,
} = useMode() } = useMode()
// const [canvasState, setCanvasState] = useRecoilState(canvasAtom) // const [canvasState, setCanvasState] = useRecoilState(canvasAtom)
@ -204,14 +204,25 @@ export default function Roof2() {
] ]
const eightPoint4 = [ const eightPoint4 = [
{ x: 228, y: 92 }, { x: 200, y: 200 },
{ x: 228, y: 592 }, { x: 200, y: 400 },
{ x: 478, y: 592 }, { x: 500, y: 400 },
{ x: 478, y: 342 }, { x: 500, y: 700 },
{ x: 728, y: 342 }, { x: 800, y: 700 },
{ x: 728, y: 592 }, { x: 800, y: 400 },
{ x: 1078, y: 592 }, { x: 1100, y: 400 },
{ x: 1078, y: 92 }, { x: 1100, y: 200 },
]
const eightPoint5 = [
{ x: 140, y: 101 },
{ x: 140, y: 601 },
{ x: 440, y: 601 },
{ x: 440, y: 801 },
{ x: 840, y: 801 },
{ x: 840, y: 601 },
{ x: 1140, y: 601 },
{ x: 1140, y: 101 },
] ]
const twelvePoint = [ const twelvePoint = [
@ -229,6 +240,21 @@ export default function Roof2() {
{ x: 995, y: 166 }, { x: 995, y: 166 },
] ]
const twelvePoint2 = [
{ x: 165, y: 81 },
{ x: 165, y: 1081 },
{ x: 465, y: 1081 },
{ x: 465, y: 781 },
{ x: 765, y: 781 },
{ x: 765, y: 1081 },
{ x: 1065, y: 1081 },
{ x: 1065, y: 581 },
{ x: 765, y: 581 },
{ x: 765, y: 281 },
{ x: 1065, y: 281 },
{ x: 1065, y: 81 },
]
const complicatedType = [ const complicatedType = [
{ x: 100, y: 100 }, { x: 100, y: 100 },
{ x: 100, y: 1100 }, { x: 100, y: 1100 },
@ -244,6 +270,29 @@ export default function Roof2() {
{ x: 1000, y: 100 }, { x: 1000, y: 100 },
] ]
const testType = [
{ x: 500, y: 400 },
{ x: 650, y: 550 },
{ x: 575, y: 625 },
{ x: 325, y: 625 },
{ x: 100, y: 400 },
]
const testType2 = [
{ x: 100, y: 400 },
{ x: 325, y: 625 },
{ x: 575, y: 625 },
{ x: 650, y: 550 },
{ x: 500, y: 400 },
]
const triangleType = [
{ x: 100, y: 100 },
{ x: 100, y: 600 },
{ x: 600, y: 600 },
{ x: 600, y: 100 },
]
const types = [type1, type2, type3, type4, type1A, type1B, eightPoint, eightPoint2, eightPoint3, eightPoint4, twelvePoint] const types = [type1, type2, type3, type4, type1A, type1B, eightPoint, eightPoint2, eightPoint3, eightPoint4, twelvePoint]
const newP = [ const newP = [
{ x: 450, y: 450 }, { x: 450, y: 450 },
@ -251,9 +300,10 @@ export default function Roof2() {
{ x: 675, y: 275 }, { x: 675, y: 275 },
{ x: 450, y: 850 }, { x: 450, y: 850 },
] ]
const polygon = new QPolygon(type2, {
const polygon = new QPolygon(twelvePoint, {
fill: 'transparent', fill: 'transparent',
stroke: 'black', stroke: 'green',
strokeWidth: 1, strokeWidth: 1,
selectable: false, selectable: false,
fontSize: fontSize, fontSize: fontSize,

View File

@ -2,7 +2,7 @@ import { fabric } from 'fabric'
import { v4 as uuidv4 } from 'uuid' import { v4 as uuidv4 } from 'uuid'
import { QLine } from '@/components/fabric/QLine' import { QLine } from '@/components/fabric/QLine'
import { distanceBetweenPoints, findTopTwoIndexesByDistance, getDirectionByPoint, sortedPointLessEightPoint, sortedPoints } from '@/util/canvas-util' import { distanceBetweenPoints, findTopTwoIndexesByDistance, getDirectionByPoint, sortedPointLessEightPoint, sortedPoints } from '@/util/canvas-util'
import { calculateAngle, dividePolygon, drawHelpLineInHexagon, splitPolygonWithLines } from '@/util/qpolygon-utils' import { calculateAngle, dividePolygon, drawHelpLineInHexagon, splitPolygonWithLines , drawHippedRoof} from '@/util/qpolygon-utils'
export const QPolygon = fabric.util.createClass(fabric.Polygon, { export const QPolygon = fabric.util.createClass(fabric.Polygon, {
type: 'QPolygon', type: 'QPolygon',
@ -15,6 +15,7 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
connectRidges: [], connectRidges: [],
cells: [], cells: [],
parentId: null, parentId: null,
innerLines: [],
initialize: function (points, options, canvas) { initialize: function (points, options, canvas) {
// 소수점 전부 제거 // 소수점 전부 제거
points.forEach((point) => { points.forEach((point) => {
@ -149,7 +150,8 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
// 보조선 그리기 // 보조선 그리기
drawHelpLine(chon = 4) { drawHelpLine(chon = 4) {
drawHelpLineInHexagon(this, chon) // drawHelpLineInHexagon(this, chon)
drawHippedRoof(this, chon)
}, },
addLengthText() { addLengthText() {

View File

@ -1109,6 +1109,391 @@ export function useMode() {
roof.divideLine() roof.divideLine()
} }
const drawRoofPolygon = (wall, offset = 50) => {
console.log(wall)
let points = wall.points,
expandedPoints = []
let minX = points[0].x,
minY = points[0].y,
maxX = points[0].x,
maxY = points[0].y
points.forEach((point) => {
if (point.x < minX) minX = point.x
if (point.y < minY) minY = point.y
if (point.x > maxX) maxX = point.x
if (point.y > maxY) maxY = point.y
})
console.log(points)
points.forEach((point, index) => {
const prevIndex = index === 0 ? points.length - 1 : index - 1
const nextIndex = index === points.length - 1 ? 0 : index + 1
point.direction = getDirectionByPoint(point, points[nextIndex])
point.length = Math.abs(point.x - points[nextIndex].x) === 0 ? Math.abs(point.y - points[nextIndex].y) : Math.abs(point.x - points[nextIndex].x)
// point.degree = Math.round(getDegreeBetweenTwoLines(points[prevIndex], point, points[nextIndex]))
})
console.log('points : ', points)
points.forEach((currentWall, index) => {
let prevWall = points[index === 0 ? points.length - 1 : index - 1]
let nextWall = points[index === points.length - 1 ? 0 : index + 1]
let isStartPointIn = minX < currentWall.x && currentWall.x < maxX && minY < currentWall.y && currentWall.y < maxY
// let isEndPointIn = minX < currentWall.x2 && currentWall.x2 < maxX && minY < currentWall.y2 && currentWall.y2 < maxY
if (prevWall.direction !== nextWall.direction) {
if (currentWall.direction === 'top') {
console.log('prevWall degree : ', 45)
if (prevWall.direction === 'right') {
let addLength = getLineOffsetPoint(prevWall, currentWall, nextWall, offset)
expandedPoints.push({
x: currentWall.x + addLength,
y: currentWall.y + addLength,
})
}
if (prevWall.direction === 'left') {
console.log('prevWall degree : ', 225)
expandedPoints.push({
x: currentWall.x - offset,
y: currentWall.y + offset,
})
}
}
if (currentWall.direction === 'bottom') {
if (prevWall.direction === 'right') {
console.log('prevWall degree : ', 45)
let addLength = getLineOffsetPoint(prevWall, currentWall, nextWall, offset)
console.log(currentWall.x, '-', offset, '+', addLength)
console.log('addLength : ', addLength)
expandedPoints.push({
x: currentWall.x + addLength,
y: currentWall.y - addLength,
})
}
if (prevWall.direction === 'left') {
console.log('prevWall degree : ', 315)
let addLength = getLineOffsetPoint(prevWall, currentWall, nextWall, offset)
console.log(currentWall.x, '-', offset, '+', addLength)
console.log('addLength : ', addLength)
expandedPoints.push({
x: currentWall.x - offset,
y: currentWall.y - offset,
})
}
}
if (currentWall.direction === 'right') {
if (prevWall.direction === 'top') {
if (isStartPointIn) {
console.log('prevWall degree : ', 135)
expandedPoints.push({
x: currentWall.x + offset,
y: currentWall.y + offset,
})
} else {
console.log('prevWall degree : ', 315)
expandedPoints.push({
x: currentWall.x - offset,
y: currentWall.y - offset,
})
}
}
if (prevWall.direction === 'bottom') {
if (isStartPointIn) {
console.log('prevWall degree : ', 45)
expandedPoints.push({
x: currentWall.x + offset,
y: currentWall.y - offset,
})
} else {
console.log('prevWall degree : ', 225)
let addLength = getLineOffsetPoint(prevWall, currentWall, nextWall, offset)
console.log('addLength : ', addLength)
expandedPoints.push({
x: currentWall.x - offset,
y: currentWall.y + offset,
})
}
}
}
if (currentWall.direction === 'left') {
if (prevWall.direction === 'top') {
if (isStartPointIn) {
console.log('prevWall degree : ', 225)
let addLength = getLineOffsetPoint(prevWall, currentWall, nextWall, offset)
console.log('addLength : ', addLength)
expandedPoints.push({
x: currentWall.x - offset,
y: currentWall.y + offset,
})
} else {
console.log('prevWall degree : ', 45)
let addLength = getLineOffsetPoint(prevWall, currentWall, nextWall, offset)
expandedPoints.push({
x: currentWall.x + offset,
y: currentWall.y - offset,
})
}
}
if (prevWall.direction === 'bottom') {
if (isStartPointIn) {
console.log('prevWall degree : ', 315)
expandedPoints.push({
x: currentWall.x - offset,
y: currentWall.y - offset,
})
} else {
console.log('prevWall degree : ', 135)
expandedPoints.push({
x: currentWall.x + offset,
y: currentWall.y + offset,
})
}
}
}
} else {
console.log('else :::: ')
if (currentWall.direction === 'top') {
if (prevWall.direction === 'right') {
if (isStartPointIn) {
console.log('prevWall degree : ', 315)
expandedPoints.push({
x: currentWall.x - offset,
y: currentWall.y - offset,
})
} else {
console.log('prevWall degree : ', 135)
expandedPoints.push({
x: currentWall.x + offset,
y: currentWall.y + offset,
})
}
}
if (prevWall.direction === 'left') {
if (isStartPointIn) {
console.log('prevWall degree : ', 45)
expandedPoints.push({
x: currentWall.x + offset,
y: currentWall.y - offset,
})
} else {
console.log('prevWall degree : ', 225)
expandedPoints.push({
x: currentWall.x - offset,
y: currentWall.y + offset,
})
}
}
}
if (currentWall.direction === 'bottom') {
if (prevWall.direction === 'right') {
if (isStartPointIn) {
console.log('prevWall degree : ', 225)
expandedPoints.push({
x: currentWall.x - offset,
y: currentWall.y + offset,
})
} else {
console.log('prevWall degree : ', 45)
expandedPoints.push({
x: currentWall.x + offset,
y: currentWall.y - offset,
})
}
}
}
if (currentWall.direction === 'right') {
if (prevWall.direction === 'top') {
if (isStartPointIn) {
console.log('prevWall degree : ', 135)
expandedPoints.push({
x: currentWall.x + offset,
y: currentWall.y + offset,
})
} else {
console.log('prevWall degree : ', 315)
expandedPoints.push({
x: currentWall.x - offset,
y: currentWall.y - offset,
})
}
}
if (prevWall.direction === 'bottom') {
if (isStartPointIn) {
console.log('prevWall degree : ', 225)
expandedPoints.push({
x: currentWall.x - offset,
y: currentWall.y + offset,
})
} else {
console.log('prevWall degree : ', 45)
expandedPoints.push({
x: currentWall.x + offset,
y: currentWall.y - offset,
})
}
}
}
if (currentWall.direction === 'left') {
if (prevWall.direction === 'top') {
if (isStartPointIn) {
console.log('prevWall degree : ', 225)
expandedPoints.push({
x: currentWall.x - offset,
y: currentWall.y + offset,
})
} else {
console.log('prevWall degree : ', 45)
expandedPoints.push({
x: currentWall.x + offset,
y: currentWall.y - offset,
})
}
}
if (prevWall.direction === 'bottom') {
if (isStartPointIn) {
console.log('prevWall degree : ', 135)
expandedPoints.push({
x: currentWall.x + offset,
y: currentWall.y + offset,
})
} else {
console.log('prevWall degree : ', 315)
expandedPoints.push({
x: currentWall.x - offset,
y: currentWall.y - offset,
})
}
}
}
}
})
console.log('expandedPoints : ', expandedPoints)
/*const roof = new fabric.Polygon(expandedPoints, {
fill: 'transparent',
stroke: 'red',
strokeWidth: 1,
selectable: true,
fontSize: fontSize,
name: 'QPolygon1',
})
roof.wall = wall
canvas?.add(roof)*/
// roof.drawHelpLine()
}
/**
* 구하려는 라인의 x1,y1좌표가 기준
* @param line1 이전 라인
* @param line2 현재 라인
* @param line3 다음 라인
* @param offset
* @returns {number}
*/
const getLineOffsetPoint = (line1, line2, line3, offset) => {
//밑변
let a = Math.abs(line1.x - line2.x)
//빗변
let c = Math.sqrt(Math.abs(line1.x - line2.x) ** 2 + Math.abs(line1.y - line2.y) ** 2)
console.log(a, c)
//밑변과 빗변사이의 각도
let alphaDegree = getDegreeBetweenTwoLines(line1, line2, line3)
alphaDegree = alphaDegree <= 90 ? alphaDegree : 180 - alphaDegree
alphaDegree = 90 - alphaDegree
console.log('alphaDegree : ', alphaDegree)
// console.log('Math.tan(alphaDegree * (Math.PI / 180)) : ', Math.tan(alphaDegree * (Math.PI / 180)))
console.log(Math.round(offset * Math.tan(alphaDegree * (Math.PI / 180))))
const angle = getDegreeBetweenTwoLines(line1, line2, line3)
const side1 = line1.length
const side2 = line2.length
const side3 = Math.sqrt(side1 ** 2 + side2 ** 2 - 2 * side1 * side2 * Math.cos(angle * (Math.PI / 180)))
const beta = Math.round(Math.asin((side2 * Math.sin(angle * (Math.PI / 180))) / side3) * (180 / Math.PI) * 10) / 10
const alpha = 180 - angle - beta
console.log('angle : ', angle, 'alpha : ', alpha, 'beta : ', beta)
const h = side2 * Math.sin(alpha * (Math.PI / 180))
const h_new = h + offset
console.log('빗변까지 길이 : ', h, 'offset 적용된 빗변까지 길이 : ', h_new)
const newAdjacent = h_new / Math.sin(angle * (Math.PI / 180))
console.log('offset 적용된 밑변 : ', newAdjacent)
// offset = Math.sqrt(diffAdjacent ** 2 + diffAdjacent ** 2) / 2
console.log('offset : ', offset)
return offset
}
/**
* 구하려는 라인의 x1,y1좌표가 기준
* @param line1 이전 라인
* @param line2 현재 라인
* @param line3 다음 라인
* @returns {number}
*/
const getDegreeBetweenTwoLines = (line1, line2, line3) => {
console.log('getDegreeBetweenTwoLines 확인 ==========')
console.log(line1, line2, line3)
let x1 = line1.x,
x2 = line2.x,
x3 = line3.x
let y1 = line1.y,
y2 = line2.y,
y3 = line3.y
// 각 점 사이의 벡터 계산
const vector1 = { x: x1 - x2, y: y1 - y2 }
const vector2 = { x: x3 - x2, y: y3 - y2 }
// 벡터의 길이 계산
const magnitude1 = Math.sqrt(vector1.x * vector1.x + vector1.y * vector1.y)
const magnitude2 = Math.sqrt(vector2.x * vector2.x + vector2.y * vector2.y)
// 내적 계산
const dotProduct = vector1.x * vector2.x + vector1.y * vector2.y
// 각도 계산 (라디안에서도 0에서 PI 라디안 사이의 각도로 변환)
let angle = Math.acos(dotProduct / (magnitude1 * magnitude2))
// 라디안에서 도 단위로 변환
angle = angle * (180 / Math.PI)
console.log('angel : ', angle)
return angle
}
const calculateParallelPoint = (x1, y1, x2, y2, distance) => {
// 원래 선의 dx, dy 계산
const dx = x2 - x1
const dy = y2 - y1
// 법선 벡터 정규화
const norm = Math.sqrt(dx * dx + dy * dy)
const unitVectorX = dy / norm
const unitVectorY = -dx / norm
// 원하는 거리만큼 평행 이동
const offsetX = distance * unitVectorX
const offsetY = distance * unitVectorY
// 새로운 평행선의 두 점 계산
const newX1 = x1 + offsetX
const newY1 = y1 + offsetY
const newX2 = x2 + offsetX
const newY2 = y2 + offsetY
return { newPoint1: { x: newX1, y: newY1 }, newPoint2: { x: newX2, y: newY2 } }
}
const togglePolygonLine = (obj) => { const togglePolygonLine = (obj) => {
const rtnLines = [] const rtnLines = []
if (obj.type === 'QPolygon') { if (obj.type === 'QPolygon') {
@ -3437,5 +3822,6 @@ export function useMode() {
makeRoofPatternPolygon, makeRoofPatternPolygon,
makeRoofTrestle, makeRoofTrestle,
createRoofRack, createRoofRack,
drawRoofPolygon,
} }
} }

View File

@ -38,7 +38,7 @@ export function actionHandler(eventData, transform, x, y) {
// define a function that can keep the polygon in the same position when we change its width/height/top/left // define a function that can keep the polygon in the same position when we change its width/height/top/left
export function anchorWrapper(anchorIndex, fn) { export function anchorWrapper(anchorIndex, fn) {
return function (eventData, transform, x, y) { return function(eventData, transform, x, y) {
let fabricObject = transform.target let fabricObject = transform.target
let originX = fabricObject?.points[anchorIndex].x - fabricObject.pathOffset.x let originX = fabricObject?.points[anchorIndex].x - fabricObject.pathOffset.x
let originY = fabricObject.points[anchorIndex].y - fabricObject.pathOffset.y let originY = fabricObject.points[anchorIndex].y - fabricObject.pathOffset.y
@ -241,6 +241,14 @@ export const getRoofHypotenuse = (base) => {
return Math.sqrt(base * base * 2) return Math.sqrt(base * base * 2)
} }
/**
* 빗변의 길이를 입력받아 밑변의 길이를 반환
* @param base 빗변
*/
export const getAdjacent = (base) => {
return Math.round(Math.sqrt(Math.pow(base, 2) / 2))
}
/** /**
* 촌을 입력받아 각도를 반환 * 촌을 입력받아 각도를 반환
* @param chon * @param chon

File diff suppressed because it is too large Load Diff