Merge branch 'feature/test' of https://git.jetbrains.space/nalpari/q-cast-iii/qcast-front into feature/hj
# Conflicts: # src/components/fabric/QLine.js # src/hooks/useCanvas.js # src/util/qpolygon-utils.js
This commit is contained in:
commit
aa3337a383
@ -5,10 +5,10 @@ import { Button } from '@nextui-org/react'
|
|||||||
import QRect from '@/components/fabric/QRect'
|
import QRect from '@/components/fabric/QRect'
|
||||||
|
|
||||||
import RangeSlider from './ui/RangeSlider'
|
import RangeSlider from './ui/RangeSlider'
|
||||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
import { useRecoilState } from 'recoil'
|
||||||
import { canvasAtom, canvasListState, canvasSizeState, fontSizeState, sortedPolygonArray } from '@/store/canvasAtom'
|
import { canvasSizeState, fontSizeState, sortedPolygonArray } from '@/store/canvasAtom'
|
||||||
import { QLine } from '@/components/fabric/QLine'
|
import { QLine } from '@/components/fabric/QLine'
|
||||||
import { getTests, getCanvasState, insertCanvasState } from '@/lib/canvas'
|
import { getCanvasState, insertCanvasState } from '@/lib/canvas'
|
||||||
import { calculateIntersection2 } from '@/util/canvas-util'
|
import { calculateIntersection2 } from '@/util/canvas-util'
|
||||||
import { CustomLine } from '@/components/fabric/QLine'
|
import { CustomLine } from '@/components/fabric/QLine'
|
||||||
import { QPolygon } from '@/components/fabric/QPolygon'
|
import { QPolygon } from '@/components/fabric/QPolygon'
|
||||||
@ -206,6 +206,28 @@ export default function Roof2() {
|
|||||||
{ x: 897, y: 215 },
|
{ x: 897, y: 215 },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const eightPoint3 = [
|
||||||
|
{ x: 190, y: 147 },
|
||||||
|
{ x: 190, y: 747 },
|
||||||
|
{ x: 490, y: 747 },
|
||||||
|
{ x: 490, y: 497 },
|
||||||
|
{ x: 640, y: 497 },
|
||||||
|
{ x: 640, y: 747 },
|
||||||
|
{ x: 1090, y: 747 },
|
||||||
|
{ x: 1090, y: 147 },
|
||||||
|
]
|
||||||
|
|
||||||
|
const eightPoint4 = [
|
||||||
|
{ x: 228, y: 92 },
|
||||||
|
{ x: 228, y: 592 },
|
||||||
|
{ x: 478, y: 592 },
|
||||||
|
{ x: 478, y: 342 },
|
||||||
|
{ x: 728, y: 342 },
|
||||||
|
{ x: 728, y: 592 },
|
||||||
|
{ x: 1078, y: 592 },
|
||||||
|
{ x: 1078, y: 92 },
|
||||||
|
]
|
||||||
|
|
||||||
if (canvas) {
|
if (canvas) {
|
||||||
const polygon = new QPolygon(eightPoint, {
|
const polygon = new QPolygon(eightPoint, {
|
||||||
fill: 'transparent',
|
fill: 'transparent',
|
||||||
|
|||||||
@ -15,7 +15,7 @@ export class QLine2 extends fabric.Group {
|
|||||||
y2
|
y2
|
||||||
direction
|
direction
|
||||||
idx
|
idx
|
||||||
type = 'QLine'
|
type = 'QLine2'
|
||||||
parent
|
parent
|
||||||
isAlreadyInterSection = false
|
isAlreadyInterSection = false
|
||||||
|
|
||||||
|
|||||||
@ -18,8 +18,8 @@ import {
|
|||||||
import { QLine } from '@/components/fabric/QLine'
|
import { QLine } from '@/components/fabric/QLine'
|
||||||
import { drawHelpLineInHexagon } from '@/util/qpolygon-utils'
|
import { drawHelpLineInHexagon } from '@/util/qpolygon-utils'
|
||||||
|
|
||||||
export default class QPolygon extends fabric.Group {
|
export default class QPolygon3 extends fabric.Group {
|
||||||
type = 'QPolygon'
|
type = 'QPolygon3'
|
||||||
polygon
|
polygon
|
||||||
points
|
points
|
||||||
texts = []
|
texts = []
|
||||||
|
|||||||
@ -127,12 +127,6 @@ export function useCanvas(id) {
|
|||||||
fabric.Object._fromObject('QLine', options, _callback, 'points')
|
fabric.Object._fromObject('QLine', options, _callback, 'points')
|
||||||
}
|
}
|
||||||
|
|
||||||
// CustomLine.prototype.canvas = canvas
|
|
||||||
|
|
||||||
// fabric.QLine = fabric.util.createClass(fabric.Group, {})
|
|
||||||
|
|
||||||
// Register the custom class with fabric
|
|
||||||
|
|
||||||
fabric.QPolygon.fromObject = function (object, callback) {
|
fabric.QPolygon.fromObject = function (object, callback) {
|
||||||
fabric.Object._fromObject('QPolygon', object, callback, 'points')
|
fabric.Object._fromObject('QPolygon', object, callback, 'points')
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,6 +25,7 @@ export function useMode() {
|
|||||||
const points = useRef([])
|
const points = useRef([])
|
||||||
const historyPoints = useRef([])
|
const historyPoints = useRef([])
|
||||||
const historyLines = useRef([])
|
const historyLines = useRef([])
|
||||||
|
const startPoint = useRef()
|
||||||
const [canvas, setCanvas] = useState(null)
|
const [canvas, setCanvas] = useState(null)
|
||||||
const [zoom, setZoom] = useState(100)
|
const [zoom, setZoom] = useState(100)
|
||||||
const [fontSize] = useRecoilState(fontSizeState)
|
const [fontSize] = useRecoilState(fontSizeState)
|
||||||
@ -35,6 +36,8 @@ export function useMode() {
|
|||||||
|
|
||||||
const [endPoint, setEndPoint] = useState(null)
|
const [endPoint, setEndPoint] = useState(null)
|
||||||
|
|
||||||
|
const pointCount = useRef(0)
|
||||||
|
|
||||||
const [roofPolygonPattern, setRoofPolygonPattern] = useRecoilState(roofPolygonPatternArrayState)
|
const [roofPolygonPattern, setRoofPolygonPattern] = useRecoilState(roofPolygonPatternArrayState)
|
||||||
|
|
||||||
const [canvasSize] = useRecoilState(canvasSizeState)
|
const [canvasSize] = useRecoilState(canvasSizeState)
|
||||||
@ -102,6 +105,62 @@ export function useMode() {
|
|||||||
canvas?.renderAll()
|
canvas?.renderAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (pointCount.current <= 2) {
|
||||||
|
removeGuideLines()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
drawGuideLines()
|
||||||
|
}, [pointCount.current])
|
||||||
|
|
||||||
|
const removeGuideLines = () => {
|
||||||
|
const guideLines = canvas?._objects.filter((obj) => obj.name === 'guideLine')
|
||||||
|
guideLines?.forEach((item) => canvas?.remove(item))
|
||||||
|
}
|
||||||
|
|
||||||
|
const drawGuideLines = () => {
|
||||||
|
// 이름이 guideLine인 가이드라인을 제거합니다.
|
||||||
|
removeGuideLines()
|
||||||
|
|
||||||
|
const arrivalX = startPoint.current?.left
|
||||||
|
const arrivalY = startPoint.current?.top
|
||||||
|
|
||||||
|
const lastX = endPoint?.left
|
||||||
|
const lastY = endPoint?.top
|
||||||
|
|
||||||
|
if (lastX === arrivalX || lastY === arrivalY) {
|
||||||
|
// 둘중 하나라도 같으면 guideLine은 한개만 생성
|
||||||
|
const guideLine = new QLine([lastX, lastY, arrivalX, arrivalY], {
|
||||||
|
fontSize: fontSize,
|
||||||
|
stroke: 'black',
|
||||||
|
strokeWidth: 1,
|
||||||
|
strokeDashArray: [1, 1, 1],
|
||||||
|
})
|
||||||
|
guideLine.name = 'guideLine'
|
||||||
|
canvas?.add(guideLine)
|
||||||
|
} else {
|
||||||
|
const guideLine1 = new QLine([lastX, lastY, lastX, arrivalY], {
|
||||||
|
fontSize: fontSize,
|
||||||
|
stroke: 'black',
|
||||||
|
strokeWidth: 1,
|
||||||
|
strokeDashArray: [1, 1, 1],
|
||||||
|
})
|
||||||
|
|
||||||
|
const guideLine2 = new QLine([guideLine1.x2, guideLine1.y2, arrivalX, arrivalY], {
|
||||||
|
fontSize: fontSize,
|
||||||
|
stroke: 'black',
|
||||||
|
strokeWidth: 1,
|
||||||
|
strokeDashArray: [1, 1, 1],
|
||||||
|
})
|
||||||
|
|
||||||
|
guideLine1.name = 'guideLine'
|
||||||
|
guideLine2.name = 'guideLine'
|
||||||
|
|
||||||
|
canvas?.add(guideLine1)
|
||||||
|
canvas?.add(guideLine2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 마우스 포인터의 가이드라인을 제거합니다.
|
* 마우스 포인터의 가이드라인을 제거합니다.
|
||||||
*/
|
*/
|
||||||
@ -125,12 +184,10 @@ export function useMode() {
|
|||||||
const pointer = canvas?.getPointer(e.e)
|
const pointer = canvas?.getPointer(e.e)
|
||||||
|
|
||||||
// 마우스 포인터 위치랑 endPoint를 연결하는 line 생성
|
// 마우스 포인터 위치랑 endPoint를 연결하는 line 생성
|
||||||
const line = new QLine([endPoint.left, endPoint.top, pointer.x, pointer.y], {
|
const line = new fabric.Line([endPoint.left, endPoint.top, pointer.x, pointer.y], {
|
||||||
stroke: 'black',
|
stroke: 'black',
|
||||||
strokeWidth: 2,
|
strokeWidth: 1,
|
||||||
selectable: false,
|
selectable: false,
|
||||||
viewLengthText: true,
|
|
||||||
fontSize: fontSize,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
line.set({ name: 'connectLine' })
|
line.set({ name: 'connectLine' })
|
||||||
@ -235,8 +292,6 @@ export function useMode() {
|
|||||||
selectable: false,
|
selectable: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
setEndPoint(endPointCircle)
|
|
||||||
|
|
||||||
canvas?.add(endPointCircle)
|
canvas?.add(endPointCircle)
|
||||||
|
|
||||||
historyPoints.current.push(endPointCircle)
|
historyPoints.current.push(endPointCircle)
|
||||||
@ -244,6 +299,10 @@ export function useMode() {
|
|||||||
points.current.forEach((point) => {
|
points.current.forEach((point) => {
|
||||||
canvas?.remove(point)
|
canvas?.remove(point)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
setEndPoint(endPointCircle)
|
||||||
|
pointCount.current = pointCount.current + 1
|
||||||
|
|
||||||
points.current = [endPointCircle]
|
points.current = [endPointCircle]
|
||||||
|
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
@ -317,6 +376,8 @@ export function useMode() {
|
|||||||
|
|
||||||
const changeMode = (canvas, mode) => {
|
const changeMode = (canvas, mode) => {
|
||||||
setEndPoint(null)
|
setEndPoint(null)
|
||||||
|
pointCount.current = 0
|
||||||
|
|
||||||
setMode(mode)
|
setMode(mode)
|
||||||
// mode변경 시 이전 이벤트 제거
|
// mode변경 시 이전 이벤트 제거
|
||||||
setCanvas(canvas)
|
setCanvas(canvas)
|
||||||
@ -329,15 +390,19 @@ export function useMode() {
|
|||||||
canvas?.on('mouse:down', function (options) {
|
canvas?.on('mouse:down', function (options) {
|
||||||
const pointer = canvas?.getPointer(options.e)
|
const pointer = canvas?.getPointer(options.e)
|
||||||
const circle = new fabric.Circle({
|
const circle = new fabric.Circle({
|
||||||
radius: 1,
|
radius: 5,
|
||||||
fill: 'transparent', // 원 안을 비웁니다.
|
fill: 'transparent', // 원 안을 비웁니다.
|
||||||
stroke: 'black', // 원 테두리 색상을 검은색으로 설정합니다.
|
stroke: 'red', // 원 테두리 색상을 검은색으로 설정합니다.
|
||||||
left: pointer.x,
|
left: pointer.x - 5,
|
||||||
top: pointer.y,
|
top: pointer.y - 5,
|
||||||
originX: 'center',
|
originX: 'center',
|
||||||
originY: 'center',
|
originY: 'center',
|
||||||
selectable: false,
|
selectable: false,
|
||||||
})
|
})
|
||||||
|
if (!startPoint.current) {
|
||||||
|
startPoint.current = circle
|
||||||
|
pointCount.current = pointCount.current + 1
|
||||||
|
}
|
||||||
|
|
||||||
setEndPoint(circle)
|
setEndPoint(circle)
|
||||||
|
|
||||||
@ -347,6 +412,7 @@ export function useMode() {
|
|||||||
|
|
||||||
if (points.current.length === 2) {
|
if (points.current.length === 2) {
|
||||||
const length = Number(prompt('길이를 입력하세요:'))
|
const length = Number(prompt('길이를 입력하세요:'))
|
||||||
|
|
||||||
// length 값이 숫자가 아닌 경우
|
// length 값이 숫자가 아닌 경우
|
||||||
if (isNaN(length) || length === 0) {
|
if (isNaN(length) || length === 0) {
|
||||||
//마지막 추가 된 points 제거합니다.
|
//마지막 추가 된 points 제거합니다.
|
||||||
@ -382,40 +448,10 @@ export function useMode() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const line = new QLine(
|
const verticalLength = scaledVector.y
|
||||||
[points.current[0].left, points.current[0].top, points.current[0].left + scaledVector.x, points.current[0].top + scaledVector.y],
|
const horizontalLength = scaledVector.x
|
||||||
{
|
|
||||||
stroke: 'black',
|
|
||||||
strokeWidth: 2,
|
|
||||||
selectable: false,
|
|
||||||
viewLengthText: true,
|
|
||||||
direction: getDirection(points.current[0], points.current[1]),
|
|
||||||
fontSize: fontSize,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
pushHistoryLine(line)
|
drawCircleAndLine(verticalLength, horizontalLength)
|
||||||
|
|
||||||
// 라인의 끝에 점을 추가합니다.
|
|
||||||
const endPointCircle = new fabric.Circle({
|
|
||||||
radius: 1,
|
|
||||||
fill: 'transparent', // 원 안을 비웁니다.
|
|
||||||
stroke: 'black', // 원 테두리 색상을 검은색으로 설정합니다.
|
|
||||||
left: points.current[0].left + scaledVector.x,
|
|
||||||
top: points.current[0].top + scaledVector.y,
|
|
||||||
originX: 'center',
|
|
||||||
originY: 'center',
|
|
||||||
selectable: false,
|
|
||||||
})
|
|
||||||
setEndPoint(endPointCircle)
|
|
||||||
canvas?.add(endPointCircle)
|
|
||||||
|
|
||||||
historyPoints.current.push(endPointCircle)
|
|
||||||
|
|
||||||
points.current.forEach((point) => {
|
|
||||||
canvas?.remove(point)
|
|
||||||
})
|
|
||||||
points.current = [endPointCircle]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -667,6 +703,8 @@ export function useMode() {
|
|||||||
*/
|
*/
|
||||||
const handleClear = () => {
|
const handleClear = () => {
|
||||||
canvas?.clear()
|
canvas?.clear()
|
||||||
|
startPoint.current = null
|
||||||
|
setEndPoint(null)
|
||||||
points.current = []
|
points.current = []
|
||||||
historyPoints.current = []
|
historyPoints.current = []
|
||||||
historyLines.current = []
|
historyLines.current = []
|
||||||
@ -1979,16 +2017,15 @@ export function useMode() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
roofPatternPolygonArray.push(bigRoofPolygon)
|
roofPatternPolygonArray.push(bigRoofPolygon) //지붕폴리곤
|
||||||
roofPatternPolygonArray.push(middleRoofPolygon)
|
roofPatternPolygonArray.push(middleRoofPolygon) //중간라인 폴리곤
|
||||||
roofPatternPolygonArray.push(smallRoofPolygon)
|
roofPatternPolygonArray.push(smallRoofPolygon) //작은지붕폴리곤
|
||||||
|
setRoofPolygonPattern({ roofPatternPolygonArray, lines }) //모든 행을 저장
|
||||||
setRoofPolygonPattern({ roofPatternPolygonArray, lines })
|
|
||||||
|
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleOuterLineTemplateA8Points = (polygon, offsetInputX = 50, offsetInputY = 20) => {
|
const handleOuterLineTemplateA8Points = (polygon, offsetInputX = 20, offsetInputY = 50) => {
|
||||||
let offsetPoints = []
|
let offsetPoints = []
|
||||||
|
|
||||||
const originalMax = 71
|
const originalMax = 71
|
||||||
@ -2002,15 +2039,15 @@ export function useMode() {
|
|||||||
|
|
||||||
const dashedCenterLineOpt = {
|
const dashedCenterLineOpt = {
|
||||||
stroke: 'black',
|
stroke: 'black',
|
||||||
strokeWidth: 4,
|
strokeWidth: 1,
|
||||||
property: 'centerLine',
|
property: 'centerLine',
|
||||||
strokeDashArray: [5, 5],
|
strokeDashArray: [8, 4],
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
}
|
}
|
||||||
|
|
||||||
const centerLineOpt = {
|
const centerLineOpt = {
|
||||||
stroke: 'blue',
|
stroke: 'blue',
|
||||||
strokeWidth: 5,
|
strokeWidth: 2,
|
||||||
property: 'bigHoriCenter',
|
property: 'bigHoriCenter',
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
}
|
}
|
||||||
@ -2020,10 +2057,8 @@ export function useMode() {
|
|||||||
const start = polygon.points[i]
|
const start = polygon.points[i]
|
||||||
const end = polygon.points[(i + 1) % polygon.points.length] // 다음 점, 마지막 점의 경우 첫 점으로
|
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], {
|
const line = new QLine([start.x, start.y, end.x, end.y], {
|
||||||
stroke: color,
|
stroke: '#A0D468',
|
||||||
strokeWidth: 2,
|
strokeWidth: 2,
|
||||||
property: 'normal',
|
property: 'normal',
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
@ -2038,12 +2073,6 @@ export function useMode() {
|
|||||||
|
|
||||||
const sortedIndex = getStartIndex(polygon.lines)
|
const sortedIndex = getStartIndex(polygon.lines)
|
||||||
let tmpArraySorted = rearrangeArray(polygon.lines, sortedIndex)
|
let tmpArraySorted = rearrangeArray(polygon.lines, sortedIndex)
|
||||||
|
|
||||||
if (tmpArraySorted[0].direction === 'right') {
|
|
||||||
//시계방향
|
|
||||||
tmpArraySorted = tmpArraySorted.reverse() //그럼 배열을 거꾸로 만들어서 무조건 반시계방향으로 배열 보정
|
|
||||||
}
|
|
||||||
|
|
||||||
setSortedArray(tmpArraySorted) //recoil에 넣음
|
setSortedArray(tmpArraySorted) //recoil에 넣음
|
||||||
|
|
||||||
const points = tmpArraySorted.map((line) => ({
|
const points = tmpArraySorted.map((line) => ({
|
||||||
@ -2054,9 +2083,10 @@ export function useMode() {
|
|||||||
//좌표 재정렬
|
//좌표 재정렬
|
||||||
function reSortQlineArray(array) {
|
function reSortQlineArray(array) {
|
||||||
let tmpArray = []
|
let tmpArray = []
|
||||||
|
let minX, minY, maxX, maxY
|
||||||
|
let tmp
|
||||||
array.forEach((arr, index) => {
|
array.forEach((arr, index) => {
|
||||||
let minX, minY, maxX, maxY
|
tmp = arr
|
||||||
let tmp = arr
|
|
||||||
if (arr.x2 < arr.x1 || arr.y2 < arr.y1) {
|
if (arr.x2 < arr.x1 || arr.y2 < arr.y1) {
|
||||||
minX = arr.x2
|
minX = arr.x2
|
||||||
minY = arr.y2
|
minY = arr.y2
|
||||||
@ -2113,56 +2143,46 @@ export function useMode() {
|
|||||||
index: concavePointIndices[0],
|
index: concavePointIndices[0],
|
||||||
line: lines[concavePointIndices[0]],
|
line: lines[concavePointIndices[0]],
|
||||||
}
|
}
|
||||||
for (var i = 0; i < points.length; i++) {
|
|
||||||
var prev = points[(i - 1 + points.length) % points.length]
|
for (let i = 0; i < points.length; i++) {
|
||||||
var current = points[i]
|
let prev = points[(i - 1 + points.length) % points.length]
|
||||||
var next = points[(i + 1) % points.length]
|
let current = points[i]
|
||||||
|
let next = points[(i + 1) % points.length]
|
||||||
|
|
||||||
// 두 벡터 계산 (prev -> current, current -> next)
|
// 두 벡터 계산 (prev -> current, current -> next)
|
||||||
var vector1 = { x: current.x - prev.x, y: current.y - prev.y }
|
let vector1 = { x: current.x - prev.x, y: current.y - prev.y }
|
||||||
var vector2 = { x: next.x - current.x, y: next.y - current.y }
|
let vector2 = { x: next.x - current.x, y: next.y - current.y }
|
||||||
|
|
||||||
// 벡터의 길이 계산
|
// 벡터의 길이 계산
|
||||||
var length1 = Math.sqrt(vector1.x * vector1.x + vector1.y * vector1.y)
|
let length1 = Math.sqrt(vector1.x * vector1.x + vector1.y * vector1.y)
|
||||||
var length2 = Math.sqrt(vector2.x * vector2.x + vector2.y * vector2.y)
|
let length2 = Math.sqrt(vector2.x * vector2.x + vector2.y * vector2.y)
|
||||||
|
|
||||||
// 벡터를 단위 벡터로 정규화
|
// 벡터를 단위 벡터로 정규화
|
||||||
var unitVector1 = { x: vector1.x / length1, y: vector1.y / length1 }
|
let unitVector1 = { x: vector1.x / length1, y: vector1.y / length1 }
|
||||||
var unitVector2 = { x: vector2.x / length2, y: vector2.y / length2 }
|
let unitVector2 = { x: vector2.x / length2, y: vector2.y / length2 }
|
||||||
|
|
||||||
// 법선 벡터 계산 (왼쪽 방향)
|
// 법선 벡터 계산 (왼쪽 방향)
|
||||||
var normal1 = { x: -unitVector1.y, y: unitVector1.x }
|
let normal1 = { x: -unitVector1.y, y: unitVector1.x }
|
||||||
var normal2 = { x: -unitVector2.y, y: unitVector2.x }
|
let normal2 = { x: -unitVector2.y, y: unitVector2.x }
|
||||||
|
|
||||||
// 법선 벡터 평균 계산
|
// 법선 벡터 평균 계산
|
||||||
var averageNormal = {
|
let averageNormal = {
|
||||||
x: (normal1.x + normal2.x) / 2,
|
x: (normal1.x + normal2.x) / 2,
|
||||||
y: (normal1.y + normal2.y) / 2,
|
y: (normal1.y + normal2.y) / 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 평균 법선 벡터를 단위 벡터로 정규화
|
// 평균 법선 벡터를 단위 벡터로 정규화
|
||||||
var lengthNormal = Math.sqrt(averageNormal.x * averageNormal.x + averageNormal.y * averageNormal.y)
|
let lengthNormal = Math.sqrt(averageNormal.x * averageNormal.x + averageNormal.y * averageNormal.y)
|
||||||
var unitNormal = {
|
let unitNormal = {
|
||||||
x: averageNormal.x / lengthNormal,
|
x: averageNormal.x / lengthNormal,
|
||||||
y: averageNormal.y / lengthNormal,
|
y: averageNormal.y / lengthNormal,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (concavePointIndices[0] === i || concavePointIndices[1] === i) {
|
offsetX = (offsetInputX / transformedMax) * originalMax * 2
|
||||||
//인덱스가 배열이랑 같으면
|
offsetY = (offsetInputY / transformedMax) * originalMax * 2
|
||||||
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 = {
|
let offsetPoint = {
|
||||||
x1: current.x + unitNormal.x * offsetX,
|
x1: current.x + unitNormal.x * offsetX,
|
||||||
y1: current.y + unitNormal.y * offsetY,
|
y1: current.y + unitNormal.y * offsetY,
|
||||||
}
|
}
|
||||||
@ -2171,6 +2191,7 @@ export function useMode() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const outlinePolygon = makePolygon(offsetPoints)
|
const outlinePolygon = makePolygon(offsetPoints)
|
||||||
|
outlinePolygon.setViewLengthText(false)
|
||||||
|
|
||||||
// 아웃라인 폴리곤의 각 변을 선으로 생성
|
// 아웃라인 폴리곤의 각 변을 선으로 생성
|
||||||
for (let i = 0; i < outlinePolygon.points.length; i++) {
|
for (let i = 0; i < outlinePolygon.points.length; i++) {
|
||||||
@ -2182,6 +2203,7 @@ export function useMode() {
|
|||||||
strokeWidth: 2,
|
strokeWidth: 2,
|
||||||
property: 'normal',
|
property: 'normal',
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
|
idx: i,
|
||||||
})
|
})
|
||||||
|
|
||||||
// 선을 배열에 추가
|
// 선을 배열에 추가
|
||||||
@ -2191,13 +2213,8 @@ export function useMode() {
|
|||||||
|
|
||||||
canvas?.remove(outlinePolygon) //임시 폴리곤을 삭제
|
canvas?.remove(outlinePolygon) //임시 폴리곤을 삭제
|
||||||
|
|
||||||
//라인들을 좌측에서 -> 우측으로 그리는거처럼 데이터 보정
|
|
||||||
outLines = reSortQlineArray(outLines)
|
|
||||||
|
|
||||||
let parallelLinesIdx = concavePointIndices[0] + 4 //들어간선에 무조건 평행하는 선 찾기
|
let parallelLinesIdx = concavePointIndices[0] + 4 //들어간선에 무조건 평행하는 선 찾기
|
||||||
let parallelLines = outLines[parallelLinesIdx]
|
|
||||||
if (parallelLinesIdx >= outLines.length) {
|
if (parallelLinesIdx >= outLines.length) {
|
||||||
parallelLines = outLines[parallelLinesIdx - outLines.length]
|
|
||||||
parallelLinesIdx = parallelLinesIdx - outLines.length
|
parallelLinesIdx = parallelLinesIdx - outLines.length
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2206,10 +2223,220 @@ export function useMode() {
|
|||||||
let horiCenterLine = []
|
let horiCenterLine = []
|
||||||
let shorVertCenterLine = []
|
let shorVertCenterLine = []
|
||||||
|
|
||||||
|
let edgeIndexArray = []
|
||||||
|
|
||||||
if (concavePointIndices[0] % 2 === 0) {
|
if (concavePointIndices[0] % 2 === 0) {
|
||||||
// 오목한 부분이 세로선일때 ㄷ, 역ㄷ
|
//concave가 짝수면 좌우로 그려진 ㄷ자
|
||||||
|
//케라바 색을 바꾼다
|
||||||
|
lines.forEach((line, index) => {
|
||||||
|
if (index % 2 === 0) {
|
||||||
|
line.line.set('stroke', 'skyblue')
|
||||||
|
if (concavePointIndices[0] !== index) {
|
||||||
|
edgeIndexArray.push(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
outLines = reSortQlineArray(outLines)
|
||||||
|
edgeIndexArray.forEach((idx, index) => {
|
||||||
|
//가로라인이 케라바 라인임
|
||||||
|
if (concavePointIndices[0] !== idx) {
|
||||||
|
//오목이가 아니면 반으로 갈라서 계산
|
||||||
|
|
||||||
|
//카라바 선의 2분할 치수를 그림
|
||||||
|
let halfLength = outLines[idx].length / 2
|
||||||
|
let centerLine1 = new QLine([outLines[idx].x1, outLines[idx].y1, outLines[idx].x1, outLines[idx].y1 + halfLength], centerLineOpt)
|
||||||
|
canvas.add(centerLine1)
|
||||||
|
|
||||||
|
let centerLine2 = new QLine([outLines[idx].x1, centerLine1.y2, outLines[idx].x2, centerLine1.y2 + halfLength], centerLineOpt)
|
||||||
|
canvas.add(centerLine2)
|
||||||
|
canvas.remove(outLines[idx]) //기존 라인 삭제
|
||||||
|
|
||||||
|
halfHoriCenterLinePoint.push({ index: idx, x1: centerLine1.x1, y1: centerLine1.y1, x2: centerLine1.x2, y2: centerLine1.y2 }) //각 카라바 라인의 1번이 마지막점을 잡아서 센터선으로 설정
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// //각 센터 라인을 그림
|
||||||
|
halfHoriCenterLinePoint.forEach((centerPoint) => {
|
||||||
|
let tmpX2 = parallelLinesIdx !== centerPoint.index ? concaveLine.line.x2 : outLines[concavePointIndices[0]].x1 //평행선에서 내려오는 선은 아웃라인에 닿아야한다
|
||||||
|
|
||||||
|
let line = new QLine([centerPoint.x2, centerPoint.y2, tmpX2, centerPoint.y2], centerLineOpt)
|
||||||
|
canvas.add(line)
|
||||||
|
|
||||||
|
line['arrayIndex'] = centerPoint.index //커스텀으로 기존 index를 넣어줌
|
||||||
|
vertCenterLine.push(line)
|
||||||
|
})
|
||||||
|
|
||||||
|
vertCenterLine = reSortQlineArray(vertCenterLine)
|
||||||
|
lines = reSortQlineArray(lines)
|
||||||
|
|
||||||
|
//해당라인에서 만나는점을 계산
|
||||||
|
vertCenterLine.forEach((vertLine) => {
|
||||||
|
if (parallelLinesIdx !== vertLine.arrayIndex) {
|
||||||
|
//평행선을 제외한 애들만 네모를 연결
|
||||||
|
let nearLine
|
||||||
|
let nearOutline
|
||||||
|
if (vertLine.arrayIndex > concaveLine.index) {
|
||||||
|
//센터에 인덱스가 오목점 보다 크면 다음 작으면 앞에꺼
|
||||||
|
nearLine = lines[concaveLine.index + 1]
|
||||||
|
nearOutline = outLines[concaveLine.index + 1]
|
||||||
|
} else {
|
||||||
|
nearLine = lines[concaveLine.index - 1]
|
||||||
|
nearOutline = outLines[concaveLine.index - 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
let nearLineY = nearLine.y1
|
||||||
|
if (parallelLinesIdx < concaveLine.index) {
|
||||||
|
//오목점 위치가 평행선보다 크면 위쪽으로 오목
|
||||||
|
nearLineY = nearLine.y2
|
||||||
|
}
|
||||||
|
|
||||||
|
//기존에 있는 라인에서 연장해서 새로 그림
|
||||||
|
let centerExtendHoriLine = new QLine([vertLine.x1, nearOutline.line.y1, vertLine.x2, nearOutline.line.y2], centerLineOpt)
|
||||||
|
canvas.add(centerExtendHoriLine)
|
||||||
|
canvas.remove(nearOutline)
|
||||||
|
outLines.splice(nearOutline.idx, 1, centerExtendHoriLine) //아웃라인에 데이터를 다시 넣는다
|
||||||
|
|
||||||
|
//가로형에선 기본으로 ㄷ자 형태로 한다
|
||||||
|
let centerExtendLine = new QLine([vertLine.line.x1, vertLine.line.y1, centerExtendHoriLine.x1, centerExtendHoriLine.y1], centerLineOpt)
|
||||||
|
|
||||||
|
//오목이가 배열에 반보다 작으면 역 ㄷ자 여서 변경
|
||||||
|
if (concavePointIndices[0] < outLines.length / 2) {
|
||||||
|
centerExtendLine = new QLine([vertLine.line.x2, vertLine.line.y2, centerExtendHoriLine.x2, centerExtendHoriLine.y2], centerLineOpt)
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas.add(centerExtendLine) //새로그리고
|
||||||
|
|
||||||
|
let betweenCenterLine = (vertLine.line.x1 + vertLine.line.x2) / 2
|
||||||
|
let centerDashLine = new QLine([betweenCenterLine, centerExtendLine.y1, betweenCenterLine, centerExtendLine.y2], dashedCenterLineOpt)
|
||||||
|
|
||||||
|
canvas.add(centerDashLine)
|
||||||
|
horiCenterLine.push(centerDashLine)
|
||||||
|
shorVertCenterLine.push(vertLine) //마지막에 가운데 선을 긋기 위해 담음
|
||||||
|
} else {
|
||||||
|
let longDashLine = halfHoriCenterLinePoint.find((obj) => obj.index === parallelLinesIdx) //평행선
|
||||||
|
|
||||||
|
let dashCenterExtendLineLength = longDashLine.y2 - longDashLine.y1 //y반개 길이
|
||||||
|
let betweenCenterLine = (vertLine.line.x1 + vertLine.line.x2) / 2 //y의 길이
|
||||||
|
let totalLength = ((longDashLine.y2 - longDashLine.y1) * 2) / dashCenterExtendLineLength //2개로 나눔
|
||||||
|
|
||||||
|
//반 쪼개서 그린다
|
||||||
|
for (let i = 0; i < totalLength; i++) {
|
||||||
|
//2번에 나눠서
|
||||||
|
let startY = i === 0 ? longDashLine.y1 : longDashLine.y1 + dashCenterExtendLineLength //시작 하는 y의 좌표
|
||||||
|
//x값은 고정이임 //TODO: 지붕 각도 계산법에 의해 재계산해야함
|
||||||
|
let centerDashLine = new QLine([betweenCenterLine, startY, betweenCenterLine, startY + dashCenterExtendLineLength], dashedCenterLineOpt)
|
||||||
|
canvas.add(centerDashLine)
|
||||||
|
horiCenterLine.push(centerDashLine)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
//마지막에 오목한 외곽선을 연장한다
|
||||||
|
const tmpLastOutLine = outLines[concavePointIndices[0]]
|
||||||
|
const lastOutLine = new QLine([tmpLastOutLine.x1, shorVertCenterLine[0].y1, tmpLastOutLine.x1, shorVertCenterLine[1].y1], centerLineOpt)
|
||||||
|
canvas.add(lastOutLine)
|
||||||
|
canvas.remove(tmpLastOutLine)
|
||||||
|
|
||||||
|
//폴리곤 패턴을 그리기 위해 작성
|
||||||
|
let tmpVertCenterLine = outLines.filter((x, index) => index % 2 !== 0) //세로만 찾음
|
||||||
|
tmpVertCenterLine = tmpVertCenterLine.concat(vertCenterLine)
|
||||||
|
tmpVertCenterLine.sort((a, b) => a.y1 - b.y1)
|
||||||
|
tmpVertCenterLine.push(lastOutLine)
|
||||||
|
|
||||||
|
let roofPatternPolygonArray = []
|
||||||
|
let tmpArray = []
|
||||||
|
let tmpBigArray = []
|
||||||
|
|
||||||
|
console.log('tmpVertCenterLine', tmpVertCenterLine)
|
||||||
|
|
||||||
|
const lastCenterLine = tmpVertCenterLine[tmpVertCenterLine.length - 1] //마지막 센터라인을 정의
|
||||||
|
|
||||||
|
for (let i = 0; i < tmpVertCenterLine.length - 1; i++) {
|
||||||
|
//-1인건 마지막은 오목한 선이라 돌 필요 없음
|
||||||
|
//라인 하나에 두점씩 나온다
|
||||||
|
let firstPointObj = {}
|
||||||
|
let secondPointObj = {}
|
||||||
|
|
||||||
|
let x1 = tmpVertCenterLine[i].x1
|
||||||
|
let y1 = tmpVertCenterLine[i].y1
|
||||||
|
let x2 = tmpVertCenterLine[i].x2
|
||||||
|
let y2 = tmpVertCenterLine[i].y2
|
||||||
|
|
||||||
|
if (i === 2 || i === 4) {
|
||||||
|
//작은 네모들
|
||||||
|
tmpArray = []
|
||||||
|
const prevLine = tmpVertCenterLine[i - 1] //뒤에서 앞라인을 찾는다
|
||||||
|
const nextLine = tmpVertCenterLine[i + 1]
|
||||||
|
|
||||||
|
//내 앞뒤 라인
|
||||||
|
const tmpX1 = i === 2 ? prevLine.x1 : nextLine.x1
|
||||||
|
const tmpY1 = i === 2 ? prevLine.y1 : nextLine.y1
|
||||||
|
const tmpX2 = i === 2 ? prevLine.x2 : nextLine.x2
|
||||||
|
const tmpY2 = i === 2 ? prevLine.y2 : nextLine.y2
|
||||||
|
|
||||||
|
firstPointObj = { x: tmpX1, y: tmpY1 }
|
||||||
|
secondPointObj = { x: tmpX2, y: tmpY2 }
|
||||||
|
tmpArray.push(firstPointObj)
|
||||||
|
tmpArray.push(secondPointObj)
|
||||||
|
|
||||||
|
//현재 내 선
|
||||||
|
firstPointObj = { x: x1, y: y1 }
|
||||||
|
secondPointObj = { x: x2, y: y2 }
|
||||||
|
tmpArray.push(firstPointObj)
|
||||||
|
tmpArray.push(secondPointObj)
|
||||||
|
roofPatternPolygonArray.push(tmpArray)
|
||||||
|
} else {
|
||||||
|
//큰 육각
|
||||||
|
if (i === 1 || i === 5) {
|
||||||
|
// 큰 폴리곤은 가운데 선으로 되야됨
|
||||||
|
if (outLines.length / 2 > concavePointIndices[0]) {
|
||||||
|
x2 = i === 1 ? lastCenterLine.x1 : lastCenterLine.x2
|
||||||
|
y2 = i === 1 ? lastCenterLine.y1 : lastCenterLine.y2
|
||||||
|
} else {
|
||||||
|
//오목이가 배열 전체보다 크면 오른쪽 오목이
|
||||||
|
x1 = i === 1 ? lastCenterLine.x1 : lastCenterLine.x2
|
||||||
|
y1 = i === 1 ? lastCenterLine.y2 : lastCenterLine.y1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i === 5) {
|
||||||
|
//5번일때는 앞에 3번에 선이 필요하다
|
||||||
|
let prevX1 = tmpVertCenterLine[i - 2].x1
|
||||||
|
let prevY1 = tmpVertCenterLine[i - 2].y1
|
||||||
|
let prevX2 = tmpVertCenterLine[i - 2].x2
|
||||||
|
let prevY2 = tmpVertCenterLine[i - 2].y2
|
||||||
|
firstPointObj = { x: prevX1, y: prevY1 }
|
||||||
|
secondPointObj = { x: prevX2, y: prevY2 }
|
||||||
|
tmpBigArray.push(firstPointObj)
|
||||||
|
tmpBigArray.push(secondPointObj)
|
||||||
|
}
|
||||||
|
|
||||||
|
firstPointObj = { x: x1, y: y1 }
|
||||||
|
secondPointObj = { x: x2, y: y2 }
|
||||||
|
tmpBigArray.push(firstPointObj)
|
||||||
|
tmpBigArray.push(secondPointObj)
|
||||||
|
|
||||||
|
if (i === 3 || i === 6) {
|
||||||
|
roofPatternPolygonArray.push(tmpBigArray)
|
||||||
|
tmpBigArray = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('roofPatternPolygonArray', roofPatternPolygonArray)
|
||||||
|
|
||||||
|
setRoofPolygonPattern({ roofPatternPolygonArray, lines })
|
||||||
} else {
|
} else {
|
||||||
// 오목한 부분이 세로선일때 ㄷ, 역ㄷ
|
// 오목한 부분이 세로선일때 아래ㄷ, 위ㄷ
|
||||||
|
//라인들을 좌측에서 -> 우측으로 그리는거처럼 데이터 보정
|
||||||
|
|
||||||
|
lines.forEach((line, index) => {
|
||||||
|
if (!(index % 2 === 0)) {
|
||||||
|
line.line.set('stroke', 'skyblue')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
outLines = reSortQlineArray(outLines)
|
||||||
outLines.forEach((outline, index) => {
|
outLines.forEach((outline, index) => {
|
||||||
if (!(index % 2 === 0)) {
|
if (!(index % 2 === 0)) {
|
||||||
//세로라인이 케라바 라인임
|
//세로라인이 케라바 라인임
|
||||||
@ -2219,20 +2446,10 @@ export function useMode() {
|
|||||||
|
|
||||||
//카라바 선의 2분할 치수를 그림
|
//카라바 선의 2분할 치수를 그림
|
||||||
let halfLength = outline.length / 2
|
let halfLength = outline.length / 2
|
||||||
let centerLine1 = new QLine([outline.x1, outline.y1, outline.x1 + halfLength, outline.y1], {
|
let centerLine1 = new QLine([outline.x1, outline.y1, outline.x1 + halfLength, outline.y1], centerLineOpt)
|
||||||
stroke: 'red',
|
|
||||||
strokeWidth: 2,
|
|
||||||
property: 'normal',
|
|
||||||
fontSize: 14,
|
|
||||||
})
|
|
||||||
canvas.add(centerLine1)
|
canvas.add(centerLine1)
|
||||||
|
|
||||||
let centerLine2 = new QLine([centerLine1.x2, outline.y1, centerLine1.x2 + halfLength, outline.y1], {
|
let centerLine2 = new QLine([centerLine1.x2, outline.y1, centerLine1.x2 + halfLength, outline.y1], centerLineOpt)
|
||||||
stroke: 'red',
|
|
||||||
strokeWidth: 2,
|
|
||||||
property: 'normal',
|
|
||||||
fontSize: 14,
|
|
||||||
})
|
|
||||||
canvas.add(centerLine2)
|
canvas.add(centerLine2)
|
||||||
canvas.remove(outline) //기존 라인 삭제
|
canvas.remove(outline) //기존 라인 삭제
|
||||||
|
|
||||||
@ -2243,7 +2460,9 @@ export function useMode() {
|
|||||||
|
|
||||||
//각 센터 라인을 그림
|
//각 센터 라인을 그림
|
||||||
halfHoriCenterLinePoint.forEach((centerPoint) => {
|
halfHoriCenterLinePoint.forEach((centerPoint) => {
|
||||||
let line = new QLine([centerPoint.x2, centerPoint.y1, centerPoint.x2, concaveLine.line.y1], centerLineOpt)
|
let tmpY2 = parallelLinesIdx !== centerPoint.index ? concaveLine.line.y1 : outLines[concavePointIndices[0]].y2 //평행선에서 내려오는 선은 아웃라인에 닿아야한다
|
||||||
|
|
||||||
|
let line = new QLine([centerPoint.x2, centerPoint.y1, centerPoint.x2, tmpY2], centerLineOpt)
|
||||||
canvas.add(line)
|
canvas.add(line)
|
||||||
|
|
||||||
line['arrayIndex'] = centerPoint.index //커스텀으로 기존 index를 넣어줌
|
line['arrayIndex'] = centerPoint.index //커스텀으로 기존 index를 넣어줌
|
||||||
@ -2251,18 +2470,21 @@ export function useMode() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
vertCenterLine = reSortQlineArray(vertCenterLine)
|
vertCenterLine = reSortQlineArray(vertCenterLine)
|
||||||
|
lines = reSortQlineArray(lines)
|
||||||
|
|
||||||
//해당라인에서 만나는점을 계산
|
//해당라인에서 만나는점을 계산
|
||||||
vertCenterLine.forEach((vertLine) => {
|
vertCenterLine.forEach((vertLine) => {
|
||||||
if (parallelLinesIdx !== vertLine.arrayIndex) {
|
if (parallelLinesIdx !== vertLine.arrayIndex) {
|
||||||
//평행선을 제외한 애들만 네모를 연결
|
//평행선을 제외한 애들만 네모를 연결
|
||||||
let nearLine
|
let nearLine
|
||||||
|
let nearOutline
|
||||||
if (vertLine.arrayIndex > concaveLine.index) {
|
if (vertLine.arrayIndex > concaveLine.index) {
|
||||||
//센터에 인덱스가 오목점 보다 크면 다음 작으면 앞에꺼
|
//센터에 인덱스가 오목점 보다 크면 다음 작으면 앞에꺼
|
||||||
nearLine = outLines[concaveLine.index + 1]
|
nearLine = lines[concaveLine.index + 1]
|
||||||
|
nearOutline = outLines[concaveLine.index + 1]
|
||||||
} else {
|
} else {
|
||||||
nearLine = outLines[concaveLine.index - 1]
|
nearLine = lines[concaveLine.index - 1]
|
||||||
|
nearOutline = outLines[concaveLine.index - 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
let nearLineY = nearLine.y1
|
let nearLineY = nearLine.y1
|
||||||
@ -2271,11 +2493,17 @@ export function useMode() {
|
|||||||
nearLineY = nearLine.y2
|
nearLineY = nearLine.y2
|
||||||
}
|
}
|
||||||
|
|
||||||
let centerExtendLine = new QLine([vertLine.line.x1, nearLineY, nearLine.x1, nearLineY], centerLineOpt)
|
let centerExtendLine = new QLine([vertLine.line.x1, nearLineY, nearOutline.x1, nearLineY], centerLineOpt)
|
||||||
canvas.add(centerExtendLine)
|
canvas.add(centerExtendLine) //새로그리고
|
||||||
|
|
||||||
|
//기존에 있는 라인에서 연장해서 새로 그림
|
||||||
|
let centerExtendHoriLine = new QLine([nearOutline.line.x1, vertLine.y1, nearOutline.line.x2, vertLine.line.y2], centerLineOpt)
|
||||||
|
canvas.add(centerExtendHoriLine)
|
||||||
|
canvas.remove(nearOutline)
|
||||||
|
outLines.splice(nearOutline.idx, 1, centerExtendHoriLine) //아웃라인에 데이터를 다시 넣는다
|
||||||
|
|
||||||
let betweenCenterLine = (vertLine.line.y1 + vertLine.line.y2) / 2
|
let betweenCenterLine = (vertLine.line.y1 + vertLine.line.y2) / 2
|
||||||
let centerDashLine = new QLine([vertLine.line.x1, betweenCenterLine, nearLine.x1, betweenCenterLine], dashedCenterLineOpt)
|
let centerDashLine = new QLine([vertLine.line.x1, betweenCenterLine, nearOutline.x1, betweenCenterLine], dashedCenterLineOpt)
|
||||||
|
|
||||||
canvas.add(centerDashLine)
|
canvas.add(centerDashLine)
|
||||||
horiCenterLine.push(centerDashLine)
|
horiCenterLine.push(centerDashLine)
|
||||||
@ -2283,30 +2511,108 @@ export function useMode() {
|
|||||||
} else {
|
} else {
|
||||||
let longDashLine = halfHoriCenterLinePoint.find((obj) => obj.index === parallelLinesIdx)
|
let longDashLine = halfHoriCenterLinePoint.find((obj) => obj.index === parallelLinesIdx)
|
||||||
|
|
||||||
let dashCenterExtendLineLength = (longDashLine.x2 - longDashLine.x1) * 2
|
let dashCenterExtendLineLength = longDashLine.x2 - longDashLine.x1
|
||||||
let betweenCenterLine = (vertLine.line.y1 + vertLine.line.y2) / 2
|
let betweenCenterLine = (vertLine.line.y1 + vertLine.line.y2) / 2
|
||||||
|
let totalLength = ((longDashLine.x2 - longDashLine.x1) * 2) / dashCenterExtendLineLength
|
||||||
|
|
||||||
let centerDashLine = new QLine(
|
//반 쪼개서 그린다
|
||||||
[longDashLine.x1, betweenCenterLine, longDashLine.x1 + dashCenterExtendLineLength, betweenCenterLine],
|
for (let i = 0; i < totalLength; i++) {
|
||||||
dashedCenterLineOpt,
|
let startX = i === 0 ? longDashLine.x1 : longDashLine.x1 + dashCenterExtendLineLength
|
||||||
)
|
let centerDashLine = new QLine([startX, betweenCenterLine, startX + dashCenterExtendLineLength, betweenCenterLine], dashedCenterLineOpt)
|
||||||
canvas.add(centerDashLine)
|
canvas.add(centerDashLine)
|
||||||
horiCenterLine.push(centerDashLine)
|
horiCenterLine.push(centerDashLine)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
if (parallelLinesIdx < concaveLine.index) {
|
//마지막에 오목한 외곽선을 연장한다
|
||||||
offsetY = offsetY * -1 // 위로올린다
|
const tmpLastOutLine = outLines[concavePointIndices[0]]
|
||||||
|
const lastOutLine = new QLine([shorVertCenterLine[0].x1, tmpLastOutLine.y1, shorVertCenterLine[1].x1, tmpLastOutLine.y2], centerLineOpt)
|
||||||
|
canvas.add(lastOutLine)
|
||||||
|
canvas.remove(tmpLastOutLine)
|
||||||
|
|
||||||
|
let tmpVertCenterLine = outLines.filter((x, index) => index % 2 === 0) //세로만 찾음
|
||||||
|
tmpVertCenterLine = tmpVertCenterLine.concat(vertCenterLine)
|
||||||
|
tmpVertCenterLine.sort((a, b) => a.x1 - b.x1)
|
||||||
|
tmpVertCenterLine.push(lastOutLine)
|
||||||
|
|
||||||
|
let roofPatternPolygonArray = []
|
||||||
|
let tmpArray = []
|
||||||
|
let tmpBigArray = []
|
||||||
|
|
||||||
|
const lastCenterLine = tmpVertCenterLine[tmpVertCenterLine.length - 1] //마지막 센터라인을 정의
|
||||||
|
|
||||||
|
for (let i = 0; i < tmpVertCenterLine.length - 1; i++) {
|
||||||
|
//-1인건 마지막은 오목한 선이라 돌 필요 없음
|
||||||
|
//라인 하나에 두점씩 나온다
|
||||||
|
let firstPointObj = {}
|
||||||
|
let secondPointObj = {}
|
||||||
|
|
||||||
|
let x1 = tmpVertCenterLine[i].x1
|
||||||
|
let y1 = tmpVertCenterLine[i].y1
|
||||||
|
let x2 = tmpVertCenterLine[i].x2
|
||||||
|
let y2 = tmpVertCenterLine[i].y2
|
||||||
|
|
||||||
|
if (i === 2 || i === 4) {
|
||||||
|
tmpArray = []
|
||||||
|
const prevLine = tmpVertCenterLine[i - 1] //뒤에서 앞라인을 찾는다
|
||||||
|
const nextLine = tmpVertCenterLine[i + 1]
|
||||||
|
|
||||||
|
//내 앞뒤 라인
|
||||||
|
const tmpX1 = i === 2 ? prevLine.x1 : nextLine.x1
|
||||||
|
const tmpY1 = i === 2 ? prevLine.y1 : nextLine.y1
|
||||||
|
const tmpX2 = i === 2 ? prevLine.x2 : nextLine.x2
|
||||||
|
const tmpY2 = i === 2 ? prevLine.y2 : nextLine.y2
|
||||||
|
|
||||||
|
firstPointObj = { x: tmpX1, y: tmpY1 }
|
||||||
|
secondPointObj = { x: tmpX2, y: tmpY2 }
|
||||||
|
tmpArray.push(firstPointObj)
|
||||||
|
tmpArray.push(secondPointObj)
|
||||||
|
|
||||||
|
//현재 내 선
|
||||||
|
firstPointObj = { x: x1, y: y1 }
|
||||||
|
secondPointObj = { x: x2, y: y2 }
|
||||||
|
tmpArray.push(firstPointObj)
|
||||||
|
tmpArray.push(secondPointObj)
|
||||||
|
roofPatternPolygonArray.push(tmpArray)
|
||||||
|
} else {
|
||||||
|
if (i === 1 || i === 5) {
|
||||||
|
// 큰 폴리곤은 가운데 선으로 되야됨
|
||||||
|
if (outLines.length / 2 < concavePointIndices[0]) {
|
||||||
|
//오목이가 배열 전체보다 크면 위쪽 방향
|
||||||
|
x2 = i === 1 ? lastCenterLine.x2 : lastCenterLine.x1
|
||||||
|
y2 = i === 1 ? lastCenterLine.y2 : lastCenterLine.y1
|
||||||
|
} else {
|
||||||
|
x1 = i === 1 ? lastCenterLine.x1 : lastCenterLine.x2
|
||||||
|
y1 = i === 1 ? lastCenterLine.y1 : lastCenterLine.y2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i === 5) {
|
||||||
|
//5번일때는 앞에 3번에 선이 필요하다
|
||||||
|
let prevX1 = tmpVertCenterLine[i - 2].x1
|
||||||
|
let prevY1 = tmpVertCenterLine[i - 2].y1
|
||||||
|
let prevX2 = tmpVertCenterLine[i - 2].x2
|
||||||
|
let prevY2 = tmpVertCenterLine[i - 2].y2
|
||||||
|
firstPointObj = { x: prevX1, y: prevY1 }
|
||||||
|
secondPointObj = { x: prevX2, y: prevY2 }
|
||||||
|
tmpBigArray.push(firstPointObj)
|
||||||
|
tmpBigArray.push(secondPointObj)
|
||||||
|
}
|
||||||
|
|
||||||
|
firstPointObj = { x: x1, y: y1 }
|
||||||
|
secondPointObj = { x: x2, y: y2 }
|
||||||
|
tmpBigArray.push(firstPointObj)
|
||||||
|
tmpBigArray.push(secondPointObj)
|
||||||
|
|
||||||
|
if (i === 3 || i === 6) {
|
||||||
|
roofPatternPolygonArray.push(tmpBigArray)
|
||||||
|
tmpBigArray = []
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
setRoofPolygonPattern({ roofPatternPolygonArray, lines })
|
||||||
const lastInLine = new QLine(
|
|
||||||
[shorVertCenterLine[0].x1, lines[concavePointIndices[0]].y1 + offsetY, shorVertCenterLine[1].x1, lines[concavePointIndices[0]].y2 + offsetY],
|
|
||||||
centerLineOpt,
|
|
||||||
)
|
|
||||||
canvas.add(lastInLine)
|
|
||||||
canvas.remove(outLines[concavePointIndices[0]])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2835,8 +3141,6 @@ export function useMode() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const makeRoofPatternPolygon = (roofStyle) => {
|
const makeRoofPatternPolygon = (roofStyle) => {
|
||||||
console.log('roofPolygonPattern', roofPolygonPattern)
|
|
||||||
|
|
||||||
if (Object.keys(roofPolygonPattern).length === 0 && roofPolygonPattern.constructor === Object) {
|
if (Object.keys(roofPolygonPattern).length === 0 && roofPolygonPattern.constructor === Object) {
|
||||||
alert('객체가 비어있습니다.')
|
alert('객체가 비어있습니다.')
|
||||||
return
|
return
|
||||||
@ -2882,7 +3186,7 @@ export function useMode() {
|
|||||||
|
|
||||||
const commonOption = {
|
const commonOption = {
|
||||||
fill: pattern,
|
fill: pattern,
|
||||||
selectable: false,
|
selectable: true,
|
||||||
fontSize: 15, // fontSize는 필요에 따라 조정
|
fontSize: 15, // fontSize는 필요에 따라 조정
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,19 +1,7 @@
|
|||||||
import { fabric } from 'fabric'
|
import { fabric } from 'fabric'
|
||||||
import QPolygon from '@/components/fabric/QPolygon3'
|
import QPolygon from '@/components/fabric/QPolygon3'
|
||||||
import { QLine } from '@/components/fabric/QLine'
|
import { QLine } from '@/components/fabric/QLine'
|
||||||
import {
|
import { calculateIntersection2, distanceBetweenPoints, findClosestPoint } from '@/util/canvas-util'
|
||||||
calculateDistance,
|
|
||||||
calculateIntersection,
|
|
||||||
calculateIntersection2,
|
|
||||||
distanceBetweenPoints,
|
|
||||||
findClosestLineToPoint,
|
|
||||||
findClosestPoint,
|
|
||||||
findClosestPointWithDifferentXY,
|
|
||||||
findIntersection1,
|
|
||||||
getRoofHypotenuse,
|
|
||||||
removeDuplicatePoints,
|
|
||||||
} from '@/util/canvas-util'
|
|
||||||
import { help } from 'mathjs'
|
|
||||||
|
|
||||||
export const defineQPloygon = () => {
|
export const defineQPloygon = () => {
|
||||||
fabric.QPolygon = fabric.util.createClass(fabric.Group, {})
|
fabric.QPolygon = fabric.util.createClass(fabric.Group, {})
|
||||||
@ -58,7 +46,9 @@ export const drawHelpLineInHexagon = (polygon, chon) => {
|
|||||||
const angle1 = Math.atan2(wallLine.y1 - line.y1, wallLine.x1 - line.x1)
|
const angle1 = Math.atan2(wallLine.y1 - line.y1, wallLine.x1 - line.x1)
|
||||||
const angle2 = Math.atan2(wallLine.y2 - line.y2, wallLine.x2 - line.x2)
|
const angle2 = Math.atan2(wallLine.y2 - line.y2, wallLine.x2 - line.x2)
|
||||||
|
|
||||||
const helpLineLength = line.length * 2
|
// line을 이등변 삼각형의 밑변으로 보고 높이를 구한다.
|
||||||
|
|
||||||
|
const helpLineLength = Math.sqrt(2 * Math.pow(line.length / 2, 2))
|
||||||
|
|
||||||
const firstX2 = Math.floor(line.x1 + helpLineLength * Math.cos(angle1))
|
const firstX2 = Math.floor(line.x1 + helpLineLength * Math.cos(angle1))
|
||||||
const firstY2 = Math.floor(line.y1 + helpLineLength * Math.sin(angle1))
|
const firstY2 = Math.floor(line.y1 + helpLineLength * Math.sin(angle1))
|
||||||
@ -144,6 +134,7 @@ export const drawHelpLineInHexagon = (polygon, chon) => {
|
|||||||
helpLines = helpLines.filter((line) => line.relatedPoints?.length > 0)
|
helpLines = helpLines.filter((line) => line.relatedPoints?.length > 0)
|
||||||
|
|
||||||
ridgeStartPoints.forEach((point) => {
|
ridgeStartPoints.forEach((point) => {
|
||||||
|
point.alreadyIntersected = false
|
||||||
// x 혹은 y가 같으면서 가장 가까운 점을 찾는다.
|
// x 혹은 y가 같으면서 가장 가까운 점을 찾는다.
|
||||||
let arrivalPoint
|
let arrivalPoint
|
||||||
let hipLine
|
let hipLine
|
||||||
@ -185,24 +176,69 @@ export const drawHelpLineInHexagon = (polygon, chon) => {
|
|||||||
|
|
||||||
polygon.canvas.renderAll()
|
polygon.canvas.renderAll()
|
||||||
ridgeEndPoints.push(arrivalPoint)
|
ridgeEndPoints.push(arrivalPoint)
|
||||||
|
|
||||||
|
point.alreadyIntersected = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 안쓰는 점 제거
|
* 안쓰는 점 제거
|
||||||
*/
|
*/
|
||||||
centerInterSectionPoints.forEach((point) => {
|
|
||||||
ridgeEndPoints.forEach((endPoint) => {
|
const ridgeEndRemainingPoints = [...ridgeEndPoints]
|
||||||
if (!(Math.abs(point.x - endPoint.x) < 2 && Math.abs(point.y - endPoint.y) < 2)) {
|
|
||||||
centerInterSectionPoints.splice(centerInterSectionPoints.indexOf(point), 1)
|
const uniqueInterSectionPoints = Array.from(new Set(centerInterSectionPoints.map((point) => `${point.x},${point.y}`))).map((key) => {
|
||||||
|
const [x, y] = key.split(',').map(Number)
|
||||||
|
return { x, y }
|
||||||
|
})
|
||||||
|
|
||||||
|
while (ridgeEndRemainingPoints.length > 0) {
|
||||||
|
const point = ridgeEndRemainingPoints.shift()
|
||||||
|
let isExist = false
|
||||||
|
uniqueInterSectionPoints.forEach((uniquePoint) => {
|
||||||
|
const degree = calculateAngle(point, uniquePoint)
|
||||||
|
|
||||||
|
if (Math.abs(45 - Math.abs(degree)) <= 5 || Math.abs(135 - Math.abs(degree)) <= 5) {
|
||||||
|
const line = new QLine([point.x, point.y, uniquePoint.x, uniquePoint.y], {
|
||||||
|
stroke: 'purple',
|
||||||
|
fontSize: polygon.fontSize,
|
||||||
|
})
|
||||||
|
|
||||||
|
ridgeEndPoints.push(uniquePoint)
|
||||||
|
|
||||||
|
ridgeEndPoints.splice(ridgeEndPoints.indexOf(point), 1)
|
||||||
|
|
||||||
|
isExist = true
|
||||||
|
|
||||||
|
polygon.canvas.add(line)
|
||||||
|
polygon.canvas.renderAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isExist) {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
}
|
||||||
|
|
||||||
|
const ridgeEndRemainingPoints2 = [...ridgeEndPoints]
|
||||||
|
|
||||||
|
while (ridgeEndRemainingPoints2.length > 0) {
|
||||||
|
// 남아있는 점끼리 연결한다.
|
||||||
|
const point = ridgeEndRemainingPoints2.shift()
|
||||||
|
const closestPoint = findClosestPoint(point, ridgeEndRemainingPoints2)
|
||||||
|
if (!closestPoint) continue
|
||||||
|
const line = new QLine([point.x, point.y, closestPoint.x, closestPoint.y], {
|
||||||
|
stroke: 'purple',
|
||||||
|
fontSize: polygon.fontSize,
|
||||||
|
})
|
||||||
|
|
||||||
|
polygon.canvas.add(line)
|
||||||
|
polygon.canvas.renderAll()
|
||||||
|
}
|
||||||
|
|
||||||
// ridgeEndPoints와 가까운 centerInterSectionPoints를 찾아서 연결한다.
|
// ridgeEndPoints와 가까운 centerInterSectionPoints를 찾아서 연결한다.
|
||||||
const remainingPoints = centerInterSectionPoints
|
const remainingPoints = centerInterSectionPoints
|
||||||
const ridgeEndRemainingPoints = ridgeEndPoints
|
/*
|
||||||
|
|
||||||
helpLines.forEach((line) => {
|
helpLines.forEach((line) => {
|
||||||
remainingPoints.forEach((point) => {
|
remainingPoints.forEach((point) => {
|
||||||
if (line.relatedPoints.includes(point)) {
|
if (line.relatedPoints.includes(point)) {
|
||||||
@ -217,18 +253,7 @@ export const drawHelpLineInHexagon = (polygon, chon) => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
while (ridgeEndRemainingPoints.length > 0) {
|
|
||||||
const point = ridgeEndRemainingPoints.shift()
|
|
||||||
const closestPoint = findClosestPoint(point, remainingPoints)
|
|
||||||
if (!closestPoint) continue
|
|
||||||
const line = new QLine([point.x, point.y, closestPoint.x, closestPoint.y], {
|
|
||||||
stroke: 'green',
|
|
||||||
fontSize: polygon.fontSize,
|
|
||||||
})
|
|
||||||
|
|
||||||
polygon.canvas.add(line)
|
|
||||||
polygon.canvas.renderAll()
|
|
||||||
}
|
|
||||||
|
|
||||||
// centerInterSectionPoints에 남아있는 점들을 가까운 점끼리 연결한다.
|
// centerInterSectionPoints에 남아있는 점들을 가까운 점끼리 연결한다.
|
||||||
while (remainingPoints.length > 0) {
|
while (remainingPoints.length > 0) {
|
||||||
@ -243,8 +268,25 @@ export const drawHelpLineInHexagon = (polygon, chon) => {
|
|||||||
polygon.canvas.add(line)
|
polygon.canvas.add(line)
|
||||||
polygon.canvas.renderAll()
|
polygon.canvas.renderAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const notIntersectedRidgeStartPoints = ridgeStartPoints.filter((point) => !point.alreadyIntersected)
|
||||||
|
// 만나지 않은 마루 시작점
|
||||||
|
while (notIntersectedRidgeStartPoints.length > 0) {
|
||||||
|
const point = notIntersectedRidgeStartPoints.shift()
|
||||||
|
const closestPoint = findClosestPoint(point, notIntersectedRidgeStartPoints)
|
||||||
|
if (!closestPoint) continue
|
||||||
|
const line = new QLine([point.x, point.y, closestPoint.x, closestPoint.y], {
|
||||||
|
stroke: 'purple',
|
||||||
|
fontSize: polygon.fontSize,
|
||||||
|
})
|
||||||
|
|
||||||
|
polygon.canvas.add(line)
|
||||||
|
polygon.canvas.renderAll()
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const drawHelpLineInHexagon2 = (polygon, chon) => {}
|
||||||
|
|
||||||
export const drawCenterLines = (polygon) => {
|
export const drawCenterLines = (polygon) => {
|
||||||
const centerLines = []
|
const centerLines = []
|
||||||
|
|
||||||
@ -336,3 +378,9 @@ const getOneSideLines = (polygon) => {
|
|||||||
return line
|
return line
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
const calculateAngle = (point1, point2) => {
|
||||||
|
const deltaX = point2.x - point1.x
|
||||||
|
const deltaY = point2.y - point1.y
|
||||||
|
const angleInRadians = Math.atan2(deltaY, deltaX)
|
||||||
|
return angleInRadians * (180 / Math.PI)
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user