diff --git a/package.json b/package.json
index 9321f939..c2b9e6cf 100644
--- a/package.json
+++ b/package.json
@@ -13,6 +13,7 @@
"@nextui-org/react": "^2.4.2",
"ag-grid-react": "^32.0.2",
"axios": "^1.7.8",
+ "big.js": "^6.2.2",
"chart.js": "^4.4.6",
"dayjs": "^1.11.13",
"fabric": "^5.3.0",
diff --git a/src/components/fabric/QLine.js b/src/components/fabric/QLine.js
index 17892dfe..7fc1afc1 100644
--- a/src/components/fabric/QLine.js
+++ b/src/components/fabric/QLine.js
@@ -28,6 +28,7 @@ export const QLine = fabric.util.createClass(fabric.Line, {
this.idx = options.idx ?? 0
this.direction = options.direction ?? getDirectionByPoint({ x: this.x1, y: this.y1 }, { x: this.x2, y: this.y2 })
+ this.textMode = options.textMode ?? 'plane' // plane:복시도, actual:실측, none:표시안함
if (length !== 0) {
this.length = length
} else {
@@ -60,70 +61,84 @@ export const QLine = fabric.util.createClass(fabric.Line, {
},
setLength() {
- const scaleX = this.scaleX
- const scaleY = this.scaleY
- const x1 = this.left
- const y1 = this.top
- const x2 = this.left + this.width * scaleX
- const y2 = this.top + this.height * scaleY
- const dx = x2 - x1
- const dy = y2 - y1
- this.length = Number(Math.sqrt(dx * dx + dy * dy).toFixed(1))
+ if (this.attributes?.actualSize !== undefined && this.attributes?.planeSize !== undefined) {
+ if (this.textMode === 'plane') {
+ this.length = this.attributes.planeSize / 10
+ } else if (this.textMode === 'actual') {
+ this.length = this.attributes.actualSize / 10
+ }
+ } else {
+ const scaleX = this.scaleX
+ const scaleY = this.scaleY
+ const x1 = this.left
+ const y1 = this.top
+ const x2 = this.left + this.width * scaleX
+ const y2 = this.top + this.height * scaleY
+ const dx = x2 - x1
+ const dy = y2 - y1
+ this.length = Number(Math.sqrt(dx * dx + dy * dy).toFixed(1))
+ }
},
addLengthText() {
const thisText = this.canvas.getObjects().find((obj) => obj.name === 'lengthText' && obj.parentId === this.id)
- this.setLength()
- const scaleX = this.scaleX
- const scaleY = this.scaleY
- const x1 = this.left
- const y1 = this.top
- const x2 = this.left + this.width * scaleX
- const y2 = this.top + this.height * scaleY
+ if (this.textMode === 'none') {
+ if (thisText) {
+ this.canvas.remove(thisText)
+ }
+ } else {
+ this.setLength()
+ const scaleX = this.scaleX
+ const scaleY = this.scaleY
+ const x1 = this.left
+ const y1 = this.top
+ const x2 = this.left + this.width * scaleX
+ const y2 = this.top + this.height * scaleY
- if (thisText) {
- thisText.set({ text: this.getLength().toString(), left: (x1 + x2) / 2, top: (y1 + y2) / 2 })
- this.text = thisText
- return
+ if (thisText) {
+ thisText.set({ text: this.getLength().toString(), left: (x1 + x2) / 2, top: (y1 + y2) / 2 })
+ this.text = thisText
+ return
+ }
+ let left, top
+ if (this.direction === 'left' || this.direction === 'right') {
+ left = (x1 + x2) / 2
+ top = (y1 + y2) / 2 + 10
+ } else if (this.direction === 'top' || this.direction === 'bottom') {
+ left = (x1 + x2) / 2 + 10
+ top = (y1 + y2) / 2
+ }
+
+ const minX = this.left
+ const maxX = this.left + this.width
+ const minY = this.top
+ const maxY = this.top + this.length
+ const degree = (Math.atan2(y2 - y1, x2 - x1) * 180) / Math.PI
+
+ const text = new fabric.Textbox(this.getLength().toString(), {
+ left: left,
+ top: top,
+ fontSize: this.fontSize,
+ minX,
+ maxX,
+ minY,
+ maxY,
+ parentDirection: this.direction,
+ parentDegree: degree,
+ parentId: this.id,
+ editable: false,
+ selectable: true,
+ lockRotation: true,
+ lockScalingX: true,
+ lockScalingY: true,
+ parent: this,
+ name: 'lengthText',
+ })
+
+ this.text = text
+ this.canvas.add(text)
}
- let left, top
- if (this.direction === 'left' || this.direction === 'right') {
- left = (x1 + x2) / 2
- top = (y1 + y2) / 2 + 10
- } else if (this.direction === 'top' || this.direction === 'bottom') {
- left = (x1 + x2) / 2 + 10
- top = (y1 + y2) / 2
- }
-
- const minX = this.left
- const maxX = this.left + this.width
- const minY = this.top
- const maxY = this.top + this.length
- const degree = (Math.atan2(y2 - y1, x2 - x1) * 180) / Math.PI
-
- const text = new fabric.Textbox(this.getLength().toString(), {
- left: left,
- top: top,
- fontSize: this.fontSize,
- minX,
- maxX,
- minY,
- maxY,
- parentDirection: this.direction,
- parentDegree: degree,
- parentId: this.id,
- editable: false,
- selectable: true,
- lockRotation: true,
- lockScalingX: true,
- lockScalingY: true,
- parent: this,
- name: 'lengthText',
- })
-
- this.text = text
- this.canvas.add(text)
},
setFontSize(fontSize) {
this.fontSize = fontSize
diff --git a/src/components/fabric/QPolygon.js b/src/components/fabric/QPolygon.js
index 33099639..22ef408b 100644
--- a/src/components/fabric/QPolygon.js
+++ b/src/components/fabric/QPolygon.js
@@ -5,6 +5,7 @@ import { distanceBetweenPoints, findTopTwoIndexesByDistance, getDirectionByPoint
import { calculateAngle, drawGabledRoof, drawRidgeRoof, drawShedRoof, inPolygon, toGeoJSON } from '@/util/qpolygon-utils'
import * as turf from '@turf/turf'
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
+import Big from 'big.js'
export const QPolygon = fabric.util.createClass(fabric.Polygon, {
type: 'QPolygon',
@@ -188,7 +189,7 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
},
// 보조선 그리기
- drawHelpLine() {
+ drawHelpLine(settingModalFirstOptions) {
const types = []
this.lines.forEach((line) => types.push(line.attributes.type))
@@ -205,7 +206,7 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
(gableOdd.every((type) => type === LINE_TYPE.WALLLINE.EAVES) && gableEven.every((type) => gableType.includes(type))) ||
(gableEven.every((type) => type === LINE_TYPE.WALLLINE.EAVES) && gableOdd.every((type) => gableType.includes(type)))
) {
- drawGabledRoof(this.id, this.canvas)
+ drawGabledRoof(this.id, this.canvas, settingModalFirstOptions)
} else if (hasShed) {
const sheds = this.lines.filter((line) => line.attributes !== undefined && line.attributes.type === LINE_TYPE.WALLLINE.SHED)
const areLinesParallel = function (line1, line2) {
@@ -232,18 +233,18 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
const gables = this.lines.filter((line) => sheds.includes(line) === false && eaves.includes(line) === false)
const isGable = gables.every((line) => gableType.includes(line.attributes.type))
if (isGable) {
- drawShedRoof(this.id, this.canvas)
+ drawShedRoof(this.id, this.canvas, settingModalFirstOptions)
} else {
- drawRidgeRoof(this.id, this.canvas)
+ drawRidgeRoof(this.id, this.canvas, settingModalFirstOptions)
}
} else {
- drawRidgeRoof(this.id, this.canvas)
+ drawRidgeRoof(this.id, this.canvas, settingModalFirstOptions)
}
} else {
- drawRidgeRoof(this.id, this.canvas)
+ drawRidgeRoof(this.id, this.canvas, settingModalFirstOptions)
}
} else {
- drawRidgeRoof(this.id, this.canvas)
+ drawRidgeRoof(this.id, this.canvas, settingModalFirstOptions)
}
},
@@ -265,15 +266,16 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
const end = points[(i + 1) % points.length]
// planeSize: Math.round(Math.sqrt(Math.pow(newLine.x1 - newLine.x2, 2) + Math.pow(newLine.y1 - newLine.y2, 2))) * 10,
// actualSize: Math.round(Math.sqrt(Math.pow(newLine.x1 - newLine.x2, 2) + Math.pow(newLine.y1 - newLine.y2, 2))) * 10,
- const dx = end.x - start.x
- const dy = end.y - start.y
- const length = Math.round(Math.sqrt(Math.pow(end.x - start.x, 2) + Math.pow(end.y - start.y, 2))) * 10
+ const dx = Big(end.x).minus(Big(start.x))
+ const dy = Big(end.y).minus(Big(start.y))
+ // const length = Math.round(Math.sqrt(Math.pow(end.x - start.x, 2) + Math.pow(end.y - start.y, 2))) * 10
+ const length = dx.pow(2).plus(dy.pow(2)).sqrt().times(10).round().toNumber()
let midPoint
midPoint = new fabric.Point((start.x + end.x) / 2, (start.y + end.y) / 2)
- const degree = (Math.atan2(dy, dx) * 180) / Math.PI
+ const degree = Big(Math.atan2(dy.toNumber(), dx.toNumber())).times(180).div(Math.PI).toNumber()
// Create new text object if it doesn't exist
const text = new fabric.Text(length.toString(), {
diff --git a/src/hooks/roofcover/useEavesGableEdit.js b/src/hooks/roofcover/useEavesGableEdit.js
index 7e69941a..7e84994e 100644
--- a/src/hooks/roofcover/useEavesGableEdit.js
+++ b/src/hooks/roofcover/useEavesGableEdit.js
@@ -10,6 +10,7 @@ import { outerLineFixState } from '@/store/outerLineAtom'
import { useSwal } from '@/hooks/useSwal'
import { usePopup } from '@/hooks/usePopup'
import { getChonByDegree } from '@/util/canvas-util'
+import { settingModalFirstOptionsState } from '@/store/settingAtom'
// 처마.케라바 변경
export function useEavesGableEdit(id) {
@@ -46,6 +47,8 @@ export function useEavesGableEdit(id) {
{ id: 4, name: getMessage('shed'), type: TYPES.SHED },
]
+ const settingModalFirstOptions = useRecoilValue(settingModalFirstOptionsState)
+
useEffect(() => {
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
if (!outerLineFix || outerLines.length === 0) {
@@ -180,7 +183,7 @@ export function useEavesGableEdit(id) {
const roof = drawRoofPolygon(wallLine)
canvas?.renderAll()
- roof.drawHelpLine()
+ roof.drawHelpLine(settingModalFirstOptions)
})
wallLines.forEach((wallLine) => {
diff --git a/src/hooks/roofcover/useOuterLineWall.js b/src/hooks/roofcover/useOuterLineWall.js
index 74bfcbcc..7e94f074 100644
--- a/src/hooks/roofcover/useOuterLineWall.js
+++ b/src/hooks/roofcover/useOuterLineWall.js
@@ -31,6 +31,7 @@ import { fabric } from 'fabric'
import { outlineDisplaySelector } from '@/store/settingAtom'
import { usePopup } from '@/hooks/usePopup'
import PropertiesSetting from '@/components/floor-plan/modal/outerlinesetting/PropertiesSetting'
+import Big from 'big.js'
//외벽선 그리기
export function useOuterLineWall(id, propertiesId) {
@@ -141,6 +142,8 @@ export function useOuterLineWall(id, propertiesId) {
const mouseDown = (e) => {
let pointer = getIntersectMousePoint(e)
+ pointer = { x: Big(pointer.x).round(1).toNumber(), y: Big(pointer.y).round(1).toNumber() }
+ console.log('mouseDown', pointer, points)
if (points.length === 0) {
setPoints((prev) => [...prev, pointer])
@@ -148,24 +151,30 @@ export function useOuterLineWall(id, propertiesId) {
const lastPoint = points[points.length - 1]
let newPoint = { x: pointer.x, y: pointer.y }
const length = distanceBetweenPoints(lastPoint, newPoint)
+ console.log('length', length)
if (verticalHorizontalMode) {
const vector = {
- x: pointer.x - points[points.length - 1].x,
- y: pointer.y - points[points.length - 1].y,
+ x: Big(pointer.x).minus(Big(points[points.length - 1].x)),
+ y: Big(pointer.y).minus(Big(points[points.length - 1].y)),
}
- const slope = Math.abs(vector.y / vector.x) // 기울기 계산
+ // const slope = Math.abs(vector.y / vector.x) // 기울기 계산
+ console.log('vector', vector.x.toNumber(), vector.y.toNumber(), Math.abs(vector.y.toNumber() / vector.x.toNumber()) >= 1)
+ const slope = vector.x.eq(0) ? Big(1) : vector.y.div(vector.x).abs() // 기울기 계산
let scaledVector
- if (slope >= 1) {
+ // if (slope >= 1) {
+ if (slope.gte(1)) {
// 기울기가 1 이상이면 x축 방향으로 그림
scaledVector = {
x: 0,
- y: vector.y >= 0 ? Number(length) : -Number(length),
+ // y: vector.y >= 0 ? Number(length) : -Number(length),
+ y: vector.y.gte(0) ? Big(length).toNumber() : Big(length).neg().toNumber(),
}
} else {
// 기울기가 1 미만이면 y축 방향으로 그림
scaledVector = {
- x: vector.x >= 0 ? Number(length) : -Number(length),
+ // x: vector.x >= 0 ? Number(length) : -Number(length),
+ x: vector.x.gte(0) ? Big(length).toNumber() : Big(length).neg().toNumber(),
y: 0,
}
}
@@ -173,9 +182,11 @@ export function useOuterLineWall(id, propertiesId) {
const verticalLength = scaledVector.y
const horizontalLength = scaledVector.x
+ console.log('verticalLength', verticalLength, 'horizontalLength', horizontalLength)
+
newPoint = {
- x: lastPoint.x + horizontalLength,
- y: lastPoint.y + verticalLength,
+ x: Big(lastPoint.x).plus(horizontalLength).toNumber(),
+ y: Big(lastPoint.y).plus(verticalLength).toNumber(),
}
}
setPoints((prev) => [...prev, newPoint])
@@ -865,6 +876,8 @@ export function useOuterLineWall(id, propertiesId) {
const firstPoint = points[0]
+ console.log('points 좌표 : ', points)
+
points.forEach((point, idx) => {
if (idx === 0 || !isAllRightAngle) {
return
diff --git a/src/hooks/roofcover/usePropertiesSetting.js b/src/hooks/roofcover/usePropertiesSetting.js
index 57aadd6d..564ec3e8 100644
--- a/src/hooks/roofcover/usePropertiesSetting.js
+++ b/src/hooks/roofcover/usePropertiesSetting.js
@@ -10,6 +10,7 @@ import { usePopup } from '@/hooks/usePopup'
import PropertiesSetting from '@/components/floor-plan/modal/outerlinesetting/PropertiesSetting'
import RoofShapeSetting from '@/components/floor-plan/modal/roofShape/RoofShapeSetting'
import RoofAllocationSetting from '@/components/floor-plan/modal/roofAllocation/RoofAllocationSetting'
+import { settingModalFirstOptionsState } from '@/store/settingAtom'
// 외벽선 속성 설정
export function usePropertiesSetting(id) {
@@ -19,6 +20,7 @@ export function usePropertiesSetting(id) {
const { drawRoofPolygon } = useMode()
const setPoints = useResetRecoilState(outerLinePointsState)
+ const settingModalFirstOptions = useRecoilValue(settingModalFirstOptionsState)
const { addPolygonByLines } = usePolygon()
const { removeLine, hideLine } = useLine()
@@ -160,7 +162,7 @@ export function usePropertiesSetting(id) {
setPoints([])
canvas.renderAll()
- roof.drawHelpLine()
+ roof.drawHelpLine(settingModalFirstOptions)
addPopup(id, 1, )
return
}
diff --git a/src/hooks/roofcover/useRoofShapeSetting.js b/src/hooks/roofcover/useRoofShapeSetting.js
index 407c19a0..e9b7bafe 100644
--- a/src/hooks/roofcover/useRoofShapeSetting.js
+++ b/src/hooks/roofcover/useRoofShapeSetting.js
@@ -11,6 +11,7 @@ import { useSwal } from '@/hooks/useSwal'
import { usePopup } from '@/hooks/usePopup'
import { getChonByDegree } from '@/util/canvas-util'
import RoofAllocationSetting from '@/components/floor-plan/modal/roofAllocation/RoofAllocationSetting'
+import { settingModalFirstOptionsState } from '@/store/settingAtom'
// 지붕형상 설정
export function useRoofShapeSetting(id) {
@@ -49,6 +50,8 @@ export function useRoofShapeSetting(id) {
const history = useRef([])
const { closePopup, addPopup } = usePopup()
+ const settingModalFirstOptions = useRecoilValue(settingModalFirstOptionsState)
+
useEffect(() => {
pitchRef.current = currentAngleType === ANGLE_TYPE.SLOPE ? pitch : getChonByDegree(pitch)
}, [pitch])
@@ -441,7 +444,7 @@ export function useRoofShapeSetting(id) {
const roof = drawRoofPolygon(polygon)
canvas?.renderAll()
- roof.drawHelpLine()
+ roof.drawHelpLine(settingModalFirstOptions)
isFixRef.current = true
addPopup(id, 1, )
}
diff --git a/src/hooks/useMode.js b/src/hooks/useMode.js
index 009df2e7..539b8af4 100644
--- a/src/hooks/useMode.js
+++ b/src/hooks/useMode.js
@@ -37,6 +37,8 @@ import offsetPolygon from '@/util/qpolygon-utils'
import { isObjectNotEmpty } from '@/util/common-utils'
import * as turf from '@turf/turf'
import { INPUT_TYPE, LINE_TYPE, Mode, POLYGON_TYPE } from '@/common/common'
+import Big from 'big.js'
+import { settingModalFirstOptionsState } from '@/store/settingAtom'
export function useMode() {
const [mode, setMode] = useRecoilState(modeState)
@@ -78,6 +80,8 @@ export function useMode() {
const [objectPlacementMode, setObjectPlacementModeState] = useRecoilState(objectPlacementModeState)
+ const settingModalFirstOptions = useRecoilValue(settingModalFirstOptionsState)
+
useEffect(() => {
// if (!canvas) {
// canvas?.setZoom(0.8)
@@ -1554,7 +1558,7 @@ export function useMode() {
})
const roof = drawRoofPolygon(polygon) //지붕 그리기
- roof.drawHelpLine()
+ roof.drawHelpLine(settingModalFirstOptions)
// roof.divideLine()
}
@@ -1664,11 +1668,18 @@ export function useMode() {
}
}
+ /**
+ * polygon 을 기준으로 margin 된 polygon 을 작성한다.
+ * @param polygon
+ * @param lines
+ * @param arcSegments
+ * @returns {{vertices, edges: *[], minX: *, minY: *, maxX: *, maxY: *}}
+ */
function createMarginPolygon(polygon, lines, arcSegments = 0) {
const offsetEdges = []
polygon.edges.forEach((edge, i) => {
- const offset = lines[i % lines.length].attributes.offset === 0 ? 1 : lines[i % lines.length].attributes.offset
+ const offset = lines[i % lines.length].attributes.offset === 0 ? 0.1 : lines[i % lines.length].attributes.offset
const dx = edge.outwardNormal.x * offset
const dy = edge.outwardNormal.y * offset
offsetEdges.push(createOffsetEdge(edge, dx, dy))
@@ -1692,6 +1703,13 @@ export function useMode() {
return marginPolygon
}
+ /**
+ * polygon 을 기준으로 padding 된 polygon 을 작성한다.
+ * @param polygon
+ * @param lines
+ * @param arcSegments
+ * @returns {{vertices, edges: *[], minX: *, minY: *, maxX: *, maxY: *}}
+ */
function createPaddingPolygon(polygon, lines, arcSegments = 0) {
const offsetEdges = []
@@ -1720,7 +1738,13 @@ export function useMode() {
return paddingPolygon
}
+ /**
+ * 외벽선을 기준으로 지붕을 그린다.
+ * @param wall
+ * @returns {*}
+ */
const drawRoofPolygon = (wall) => {
+ //외벽선의 순서를 최좌측 선을 기준으로 반시계방향으로 정리한다. 지붕선과 순서를 맞추기 위함.
const startLine = wall.lines
.filter((line) => line.x1 === Math.min(...wall.lines.map((line) => line.x1)))
.reduce((prev, current) => {
@@ -1740,12 +1764,15 @@ export function useMode() {
wall.lines = afterLine.concat(beforeLine)
+ //외벽선을 기준으로 polygon을 생성한다. 지붕선의 기준이 됨.
const polygon = createRoofPolygon(wall.points)
const originPolygon = new QPolygon(wall.points, { fontSize: 0 })
originPolygon.setViewLengthText(false)
let offsetPolygon
let result = createMarginPolygon(polygon, wall.lines).vertices
+
+ //margin polygon 의 point가 기준 polygon의 밖에 있는지 판단한다.
const allPointsOutside = result.every((point) => !originPolygon.inPolygon(point))
if (allPointsOutside) {
@@ -1759,6 +1786,7 @@ export function useMode() {
return { x1: point.x, y1: point.y }
}),
)
+
if (wall.direction) {
roof.direction = wall.direction
}
@@ -1769,9 +1797,11 @@ export function useMode() {
roof.setWall(wall)
roof.lines.forEach((line, index) => {
- const lineLength = Math.sqrt(
- Math.pow(Math.round(Math.abs(line.x1 - line.x2) * 10), 2) + Math.pow(Math.round(Math.abs(line.y1 - line.y2) * 10), 2),
- )
+ const x1 = Big(line.x1)
+ const x2 = Big(line.x2)
+ const y1 = Big(line.y1)
+ const y2 = Big(line.y2)
+ const lineLength = x1.minus(x2).abs().pow(2).plus(y1.minus(y2).abs().pow(2)).sqrt().times(10).round().toNumber()
line.attributes = {
roofId: roof.id,
planeSize: lineLength,
@@ -1785,18 +1815,26 @@ export function useMode() {
}
})
- wall.attributes = {
- roofId: roof.id,
- }
+ wall.set({
+ originX: 'center',
+ originY: 'center',
+ attributes: {
+ roofId: roof.id,
+ },
+ })
+ //외벽선 삭제
canvas
.getObjects()
.filter((line) => line.attributes?.wallId === wall.id)
.forEach((line) => canvas.remove(line))
+
wall.lines.forEach((line, index) => {
- const lineLength = Math.sqrt(
- Math.pow(Math.round(Math.abs(line.x1 - line.x2) * 10), 2) + Math.pow(Math.round(Math.abs(line.y1 - line.y2) * 10), 2),
- )
+ const x1 = Big(line.x1)
+ const x2 = Big(line.x2)
+ const y1 = Big(line.y1)
+ const y2 = Big(line.y2)
+ const lineLength = x1.minus(x2).abs().pow(2).plus(y1.minus(y2).abs().pow(2)).sqrt().times(10).round().toNumber()
line.attributes.roofId = roof.id
line.attributes.currentRoofId = roof.lines[index].id
line.attributes.planeSize = lineLength
@@ -1829,6 +1867,8 @@ export function useMode() {
wallStrokeWidth = 4
break
}
+
+ //외벽선의 색깔 표시를 위해 라인을 추가한다.
const wallLine = new fabric.Line([line.x1, line.y1, line.x2, line.y2], {
parentId: wall.id,
name: 'wallLine',
diff --git a/src/util/canvas-util.js b/src/util/canvas-util.js
index fdc4de86..6ad06e45 100644
--- a/src/util/canvas-util.js
+++ b/src/util/canvas-util.js
@@ -1,5 +1,6 @@
import { intersect } from 'mathjs'
import * as turf from '@turf/turf'
+import Big from 'big.js'
/**
* Collection of function to use on canvas
@@ -128,9 +129,9 @@ export const formattedWithComma = (value, unit = 'mm') => {
}
export const distanceBetweenPoints = (point1, point2) => {
- const dx = point2.x - point1.x
- const dy = point2.y - point1.y
- return Math.sqrt(dx * dx + dy * dy)
+ const dx = Big(point2.x).minus(Big(point1.x))
+ const dy = Big(point2.y).minus(Big(point1.y))
+ return dx.pow(2).plus(dy.pow(2)).sqrt().round(1).toNumber()
}
/**
diff --git a/src/util/qpolygon-utils.js b/src/util/qpolygon-utils.js
index edb8574c..91116ee8 100644
--- a/src/util/qpolygon-utils.js
+++ b/src/util/qpolygon-utils.js
@@ -6,6 +6,7 @@ import { QPolygon } from '@/components/fabric/QPolygon'
import * as turf from '@turf/turf'
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
import { OUTER_LINE_TYPE } from '@/store/outerLineAtom'
+import Big from 'big.js'
const TWO_PI = Math.PI * 2
@@ -15,9 +16,15 @@ export const defineQPloygon = () => {
}
}
+/**
+ * point1에서 point2를 잇는 방향의 각도를 구한다.
+ * @param point1
+ * @param point2
+ * @returns {number}
+ */
export const calculateAngle = (point1, point2) => {
- const deltaX = point2.x - point1.x
- const deltaY = point2.y - point1.y
+ const deltaX = Big(point2.x).minus(point1.x).toNumber()
+ const deltaY = Big(point2.y).minus(point1.y).toNumber()
const angleInRadians = Math.atan2(deltaY, deltaX)
return angleInRadians * (180 / Math.PI)
}
@@ -86,13 +93,19 @@ function createPolygon(vertices) {
}
}
+/**
+ * edgeA와 edgeB가 마주치는 포인트의 좌표를 반환한다.
+ * @param edgeA
+ * @param edgeB
+ * @returns {{x: *, y: *, isIntersectionOutside: boolean}|null}
+ */
function edgesIntersection(edgeA, edgeB) {
const den =
(edgeB.vertex2.y - edgeB.vertex1.y) * (edgeA.vertex2.x - edgeA.vertex1.x) -
(edgeB.vertex2.x - edgeB.vertex1.x) * (edgeA.vertex2.y - edgeA.vertex1.y)
if (den === 0) {
- return null // lines are parallel or coincident
+ return null // 선들이 평행하거나 일치합니다
}
const ua =
@@ -105,7 +118,7 @@ function edgesIntersection(edgeA, edgeB) {
(edgeA.vertex2.y - edgeA.vertex1.y) * (edgeA.vertex1.x - edgeB.vertex1.x)) /
den
- // Edges are not intersecting but the lines defined by them are
+ // 교차점이 두 선분의 범위 내에 있는지 확인
const isIntersectionOutside = ua < 0 || ub < 0 || ua > 1 || ub > 1
return {
@@ -296,7 +309,7 @@ export const isSamePoint = (a, b) => {
* @param roofId
* @param canvas
*/
-export const drawGabledRoof = (roofId, canvas) => {
+export const drawGabledRoof = (roofId, canvas, settingModalFirstOptions) => {
const roof = canvas?.getObjects().find((object) => object.id === roofId)
const roofLines = roof.lines
const wallLines = canvas?.getObjects().find((object) => object.name === POLYGON_TYPE.WALL && object.attributes.roofId === roof.id).lines
@@ -634,7 +647,7 @@ export const drawGabledRoof = (roofId, canvas) => {
* @param roofId
* @param canvas
*/
-export const drawShedRoof = (roofId, canvas) => {
+export const drawShedRoof = (roofId, canvas, settingModalFirstOptions) => {
const roof = canvas?.getObjects().find((object) => object.id === roofId)
const hasNonParallelLines = roof.lines.filter((line) => Math.abs(line.x1 - line.x2) > 1 && Math.abs(line.y1 - line.y2) > 1)
if (hasNonParallelLines.length > 0) {
@@ -690,6 +703,8 @@ export const drawShedRoof = (roofId, canvas) => {
x2 = eave.x1
}
points.sort((a, b) => a - b)
+ const planeSize = Math.round(Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)) * 10)
+ const actualSize = Math.round(Math.sqrt(Math.pow(planeSize, 2) + Math.pow(getHeight(planeSize, shedDegree), 2)) * 10)
const line = new QLine([x1, y1, x2, y2], {
parentId: roof.id,
stroke: '#000000',
@@ -700,6 +715,8 @@ export const drawShedRoof = (roofId, canvas) => {
attributes: {
roofId: roof.id,
type: 'pitchSizeLine',
+ planeSize: planeSize,
+ actualSize: actualSize,
},
})
pitchSizeLines.push(line)
@@ -718,18 +735,36 @@ export const drawShedRoof = (roofId, canvas) => {
maxLine.setLengthText(lengthText)
}
-export const drawRidgeRoof = (roofId, canvas) => {
+export const drawRidgeRoof = (roofId, canvas, settingModalFirstOptions) => {
const roof = canvas?.getObjects().find((object) => object.id === roofId)
- const hasNonParallelLines = roof.lines.filter((line) => Math.abs(line.x1 - line.x2) > 1 && Math.abs(line.y1 - line.y2) > 1)
+ let textMode = 'plane'
+
+ const dimensionDisplay = settingModalFirstOptions?.dimensionDisplay.find((opt) => opt.selected).id
+ ? settingModalFirstOptions?.dimensionDisplay.find((opt) => opt.selected).id
+ : 1
+ switch (dimensionDisplay) {
+ case 1:
+ textMode = 'plane'
+ break
+ case 2:
+ textMode = 'actual'
+ break
+ case 3:
+ textMode = 'none'
+ break
+ }
+ //Math.abs(line.x1 - line.x2) > 1 && Math.abs(line.y1 - line.y2) > 1
+ const hasNonParallelLines = roof.lines.filter((line) => Big(line.x1).minus(Big(line.x2)).gt(1) && Big(line.y1).minus(Big(line.y2)).gt(1))
if (hasNonParallelLines.length > 0) {
alert('대각선이 존재합니다.')
return
}
- drawRidge(roof, canvas)
- drawHips(roof, canvas)
- connectLinePoint(roof, canvas)
- modifyRidge(roof, canvas)
- drawCenterLine(roof, canvas)
+
+ drawRidge(roof, canvas, textMode)
+ drawHips(roof, canvas, textMode)
+ connectLinePoint(roof, canvas, textMode)
+ modifyRidge(roof, canvas, textMode)
+ drawCenterLine(roof, canvas, textMode)
}
/**
@@ -737,8 +772,10 @@ export const drawRidgeRoof = (roofId, canvas) => {
*
* @param roof
* @param canvas
+ * @param textMode
*/
-const drawRidge = (roof, canvas) => {
+const drawRidge = (roof, canvas, textMode) => {
+ console.log('roof.lines : ', roof.lines)
const wallLines = canvas?.getObjects().find((object) => object.name === POLYGON_TYPE.WALL && object.attributes.roofId === roof.id).lines // 외벽의 라인
const roofLines = roof.lines // 지붕의 라인
let ridgeRoof = []
@@ -751,16 +788,18 @@ const drawRidge = (roof, canvas) => {
prevRoof = index === 0 ? wallLines[wallLines.length - 1] : wallLines[index - 1]
nextRoof = index === wallLines.length - 1 ? wallLines[0] : index === wallLines.length ? wallLines[1] : wallLines[index + 1]
- const angle1 = calculateAngle(prevRoof.startPoint, prevRoof.endPoint)
- const angle2 = calculateAngle(nextRoof.startPoint, nextRoof.endPoint)
- if (Math.round(Math.abs(angle1 - angle2)) === 180 && currentWall.attributes.planeSize <= currentRoof.attributes.planeSize) {
+ const angle1 = Big(calculateAngle(prevRoof.startPoint, prevRoof.endPoint))
+ const angle2 = Big(calculateAngle(nextRoof.startPoint, nextRoof.endPoint))
+ if (
+ angle1.minus(angle2).abs().round(Big.roundHalfUp).toNumber() === 180 &&
+ currentWall.attributes.planeSize <= currentRoof.attributes.planeSize
+ ) {
ridgeRoof.push({ index: index, roof: currentRoof, length: currentRoof.attributes.planeSize })
}
})
// 지붕의 길이가 짧은 순으로 정렬
ridgeRoof.sort((a, b) => a.length - b.length)
- console.log('마루 순서 : ', ridgeRoof.map((item) => item.length).join(','))
ridgeRoof.forEach((item) => {
if (getMaxRidge(roofLines.length) > roof.ridges.length) {
@@ -777,75 +816,84 @@ const drawRidge = (roof, canvas) => {
const anotherRoof = roofLines.filter((roof) => roof !== currentRoof && roof !== prevRoof && roof !== nextRoof)
- let currentX1 = currentRoof.x1,
- currentY1 = currentRoof.y1,
- currentX2 = currentRoof.x2,
- currentY2 = currentRoof.y2
- let ridgeMaxLength = Math.max(prevRoof.attributes.planeSize, nextRoof.attributes.planeSize) / 10
- let ridgeMinLength = Math.min(prevRoof.attributes.planeSize, nextRoof.attributes.planeSize) / 10
+ let currentX1 = Big(currentRoof.x1),
+ currentY1 = Big(currentRoof.y1),
+ currentX2 = Big(currentRoof.x2),
+ currentY2 = Big(currentRoof.y2)
+ let ridgeMaxLength = Big(Math.max(prevRoof.attributes.planeSize, nextRoof.attributes.planeSize)).div(10)
+ let ridgeMinLength = Big(Math.min(prevRoof.attributes.planeSize, nextRoof.attributes.planeSize)).div(10)
- const currentAngle = Math.atan2(currentY2 - currentY1, currentX2 - currentX1) * (180 / Math.PI)
+ const currentAngle = Math.atan2(currentY2.minus(currentY1).toNumber(), currentX2.minus(currentX1).toNumber()) * (180 / Math.PI)
anotherRoof
.filter((roof) => isInnerLine(prevRoof, currentRoof, nextRoof, roof))
.forEach((innerRoof) => {
- const vector1 = { x: currentRoof.x2 - currentRoof.x1, y: currentRoof.y2 - currentRoof.y1 }
- const vector2 = { x: innerRoof.x2 - innerRoof.x1, y: innerRoof.y2 - innerRoof.y1 }
+ const vector1 = { x: currentX2.minus(currentX1), y: currentY2.minus(currentY1) }
+ const vector2 = {
+ x: Big(innerRoof.x2).minus(Big(innerRoof.x1)),
+ y: Big(innerRoof.y2).minus(Big(innerRoof.y1)),
+ }
- const dotProduct = vector1.x * vector2.x + vector1.y * vector2.y
- 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 angle = (Math.acos(dotProduct / (magnitude1 * magnitude2)) * 180) / Math.PI
+ const dotProduct = vector1.x.times(vector2.x).plus(vector1.y.times(vector2.y))
+ const magnitude1 = vector1.x.pow(2).plus(vector1.y.pow(2)).sqrt()
+ const magnitude2 = vector2.x.pow(2).plus(vector2.y.pow(2)).sqrt()
+ const angle = (Math.acos(dotProduct.div(magnitude1.times(magnitude2).toNumber())) * 180) / Math.PI
- //현재 지붕선과 직각인 선
+ // 현재 지붕선과 직각인 선
if (Math.abs(angle) === 90) {
const innerBefore = roofLines.find((line) => innerRoof.x1 === line.x2 && innerRoof.y1 === line.y2)
- const ibAngle = Math.atan2(innerBefore.y2 - innerBefore.y1, innerBefore.x2 - innerBefore.x1) * (180 / Math.PI)
- if (Math.abs(currentAngle - ibAngle) === 180) {
+ const ibAngle =
+ Math.atan2(Big(innerBefore.y2).minus(Big(innerBefore.y1)).toNumber(), Big(innerBefore.x2).minus(Big(innerBefore.x1)).toNumber()) *
+ (180 / Math.PI)
+ if (Math.abs(Big(currentAngle).minus(Big(ibAngle))) === 180) {
if (currentAngle === 0 || currentAngle === 180) {
currentX2 = innerRoof.x1
- ridgeMinLength =
- Math.round(
- Math.sqrt(
- Math.pow(Math.round(Math.abs(nextRoof.x1 - nextRoof.x2) * 10), 2) +
- Math.pow(Math.round(Math.abs(nextRoof.y1 - innerRoof.y2) * 10), 2),
- ),
- ) / 10
+ ridgeMinLength = Big(nextRoof.x1)
+ .minus(Big(nextRoof.x2))
+ .times(10)
+ .round()
+ .pow(2)
+ .plus(Big(nextRoof.y1).minus(Big(nextRoof.y2)).times(10).round().pow(2))
+ .sqrt()
+ .div(10)
}
if (currentAngle === 90 || currentAngle === 270) {
currentY2 = innerRoof.y1
- ridgeMinLength =
- Math.round(
- Math.sqrt(
- Math.pow(Math.round(Math.abs(nextRoof.x1 - innerRoof.x2) * 10), 2) +
- Math.pow(Math.round(Math.abs(nextRoof.y1 - nextRoof.y2) * 10), 2),
- ),
- ) / 10
+ ridgeMinLength = Big(nextRoof.x1)
+ .minus(Big(innerRoof.x2))
+ .times(10)
+ .round()
+ .pow(2)
+ .plus(Big(nextRoof.y1).minus(Big(nextRoof.y2)).times(10).round().pow(2))
+ .sqrt()
+ .div(10)
}
}
if (Math.abs(currentAngle - ibAngle) === 0) {
if (currentAngle === 0 || currentAngle === 180) {
currentX1 = innerRoof.x2
- ridgeMinLength =
- Math.round(
- Math.sqrt(
- Math.pow(Math.round(Math.abs(prevRoof.x1 - prevRoof.x2) * 10), 2) +
- Math.pow(Math.round(Math.abs(prevRoof.y1 - innerRoof.y1) * 10), 2),
- ),
- ) / 10
+ ridgeMinLength = Big(prevRoof.x1)
+ .minus(Big(prevRoof.x2))
+ .times(10)
+ .round()
+ .pow(2)
+ .plus(Big(prevRoof.y1).minus(Big(innerRoof.y1)).times(10).round().pow(2))
+ .sqrt()
+ .div(10)
}
if (currentAngle === 90 || currentAngle === 270) {
currentY1 = innerRoof.y2
- ridgeMinLength =
- Math.round(
- Math.sqrt(
- Math.pow(Math.round(Math.abs(prevRoof.x1 - innerRoof.x1) * 10), 2) +
- Math.pow(Math.round(Math.abs(prevRoof.y1 - prevRoof.y2) * 10), 2),
- ),
- ) / 10
+ ridgeMinLength = Big(prevRoof.x1)
+ .minus(innerRoof.x1)
+ .times(10)
+ .round()
+ .pow(2)
+ .plus(Big(prevRoof.y2).minus(prevRoof.y2).times(10).round().pow(2))
+ .sqrt()
+ .div(10)
}
}
}
- //현재 지붕선과 반대인 선
+ // 현재 지붕선과 반대인 선
if (Math.abs(angle) === 180) {
if (currentAngle === 0 || currentAngle === 180) {
}
@@ -854,24 +902,39 @@ const drawRidge = (roof, canvas) => {
}
})
- const midX = (currentX1 + currentX2) / 2 // 지붕의 X 중심
- const midY = (currentY1 + currentY2) / 2 // 지붕의 Y 중심
- const alpha = (currentRoof.x1 + currentRoof.x2) / 2 - (wallLine.x1 + wallLine.x2) / 2 // 벽과 지붕의 X 거리
- const beta = (currentRoof.y1 + currentRoof.y2) / 2 - (wallLine.y1 + wallLine.y2) / 2 // 벽과 지붕의 Y 거리
- const hypotenuse = Math.sqrt(Math.pow(alpha, 2) + Math.pow(beta, 2)) // 벽과 지붕의 거리
+ // 지붕선의 X 중심
+ const midX = currentX1.plus(currentX2).div(2)
+ // 지붕선의 Y 중심
+ const midY = currentY1.plus(currentY2).div(2)
- const currentPlaneSize = Math.sqrt(
- Math.pow(Math.round(Math.abs(currentX1 - currentX2) * 10), 2) + Math.pow(Math.round(Math.abs(currentY1 - currentY2) * 10), 2),
- )
- let ridgeBaseLength = Math.round(currentPlaneSize / 2) / 10 // 지붕의 기반 길이
+ // 외선벽과 지붕선의 X 거리
+ const alpha = Big(currentRoof.x1)
+ .plus(Big(currentRoof.x2))
+ .div(2)
+ .minus(Big(wallLine.x1).plus(Big(wallLine.x2)).div(2))
+ // 외벽벽과 지붕선의 Y 거리
+ const beta = Big(currentRoof.y1)
+ .plus(Big(currentRoof.y2))
+ .div(2)
+ .minus(Big(wallLine.y1).plus(Big(wallLine.y2)).div(2))
+ // 외벽벽과 지붕선의 거리
+ const hypotenuse = alpha.pow(2).plus(beta.pow(2)).sqrt()
- startXPoint = Math.round(midX + (-1 * (alpha / hypotenuse) * (currentPlaneSize / 2)) / 10)
- startYPoint = Math.round(midY + (-1 * (beta / hypotenuse) * (currentPlaneSize / 2)) / 10)
+ // 지붕선의 평면길이
+ const currentPlaneSize = Big(calcLinePlaneSize({ x1: currentX1, y1: currentY1, x2: currentX2, y2: currentY2 }))
+ // 용마루의 기반길이(지붕선에서 떨어진 정도)
+ let ridgeBaseLength = currentPlaneSize.div(2).round().div(10)
- const checkEndXPoint = Math.round(startXPoint + Math.sign(alpha) * -1 * (ridgeMaxLength + ridgeBaseLength))
- const checkEndYPoint = Math.round(startYPoint + Math.sign(beta) * -1 * (ridgeMaxLength + ridgeBaseLength))
+ // 시작점은 현재 지붕선을 대각선으로 한 직각이등변삼각형으로 판단하고 현재 지붕선의 가운데에서 지붕에서 90도방향으로 지붕선의 절반만큼 떨어진 방향으로 설정한다.
+ startXPoint = midX.plus(alpha.div(hypotenuse).times(currentPlaneSize.div(2)).neg().div(10))
+ startYPoint = midY.plus(beta.div(hypotenuse).times(currentPlaneSize.div(2)).neg().div(10))
- const checkLine = new QLine([startXPoint, startYPoint, checkEndXPoint, checkEndYPoint], {
+ // 종료점은 시작점에서 용마루의 최대길이 + 기반길이 만큼 그려진것으로 판단하여 늘린다.
+ const checkEndXPoint = startXPoint.plus(Big(Math.sign(alpha.toNumber())).times(ridgeMaxLength.plus(ridgeBaseLength)).neg())
+ const checkEndYPoint = startYPoint.plus(Big(Math.sign(beta.toNumber())).times(ridgeMaxLength.plus(ridgeBaseLength)).neg())
+
+ // 맞은편 외벽선을 확인하기 위한 라인을 생성
+ const checkLine = new QLine([startXPoint.toNumber(), startYPoint.toNumber(), checkEndXPoint.toNumber(), checkEndYPoint.toNumber()], {
parentId: roof.id,
fontSize: roof.fontSize,
stroke: 'red',
@@ -879,6 +942,11 @@ const drawRidge = (roof, canvas) => {
name: LINE_TYPE.SUBLINE.HIP,
attributes: { roofId: roof.id, currentRoofId: currentRoof.id, actualSize: 0 },
})
+ // 디버그시 주석제거해서 라인 확인
+ // canvas.add(checkLine)
+ // canvas.renderAll()
+
+ // checkLine 과 마주치는 지붕선을 모두 찾아낸다.
const intersectLines = []
roofLines.forEach((line) => {
const intersection = edgesIntersection(
@@ -889,62 +957,99 @@ const drawRidge = (roof, canvas) => {
intersectLines.push({ x: intersection.x, y: intersection.y, line: line })
}
})
+ // intersectLines 중 현재 지붕선과 가장 가까운 지붕선을 찾는다.
if (intersectLines.length > 0) {
intersectLines.reduce((prev, current) => {
if (prev !== undefined) {
- const prevDistance = Math.sqrt(Math.pow(prev.x - startXPoint, 2) + Math.pow(prev.y - startYPoint, 2))
- const currentDistance = Math.sqrt(Math.pow(current.x - startXPoint, 2) + Math.pow(current.y - startYPoint, 2))
+ const prevDistance = Big(prev.x).minus(startXPoint).pow(2).plus(Big(prev.y).minus(startYPoint).pow(2)).sqrt()
+ const currentDistance = Big(current.x).minus(startXPoint).pow(2).plus(Big(current.y).minus(startYPoint).pow(2)).sqrt()
return prevDistance > currentDistance ? current : prev
} else {
return current
}
}, undefined)
}
-
+ // 현재 지붕선과 마주하는 지붕선이 있는 경우
if (intersectLines.length > 0) {
+ // 마주하는 지붕선
const intersectLine = intersectLines[0]
- const diffX = Math.round(intersectLine.x - startXPoint)
- const diffY = Math.round(intersectLine.y - startYPoint)
- endXPoint = Math.sign(diffX) * Math.round(Math.abs(diffX) - ridgeBaseLength) + startXPoint
- endYPoint = Math.sign(diffY) * Math.round(Math.abs(diffY) - ridgeBaseLength) + startYPoint
- const hypo = Math.sqrt(Math.pow(Math.abs(startXPoint - endXPoint), 2) + Math.pow(Math.abs(startYPoint - endYPoint), 2))
+ //지붕선에서 마주하는 지붕선까지의 x,y 좌표의 차이
- const intersectLength = Math.sqrt(Math.pow(Math.abs(midX - intersectLine.x), 2) + Math.pow(Math.abs(midY - intersectLine.y), 2))
- if (intersectLength < prevRoof.attributes.planeSize / 10 && intersectLength < nextRoof.attributes.planeSize / 10) {
+ const diffX = Big(intersectLine.x).minus(startXPoint).round(1).abs().lt(1) ? Big(0) : Big(intersectLine.x).minus(startXPoint).round(1)
+ const diffY = Big(intersectLine.y).minus(startYPoint).round(1).abs().lt(1) ? Big(0) : Big(intersectLine.y).minus(startYPoint).round(1)
+ // 시작점에서 ridgeBaseLength 만큼 떨어진 지점까지 용마루 길이로 본다.
+ endXPoint = startXPoint.plus(Big(Math.sign(diffX.toNumber())).times(diffX.abs().minus(ridgeBaseLength)))
+ endYPoint = startYPoint.plus(Big(Math.sign(diffY.toNumber())).times(diffY.abs().minus(ridgeBaseLength)))
+
+ // 시작점에서 종료점까지의 평면길이
+ //startXPoint.minus(endXPoint).abs().pow(2).plus(startYPoint.minus(endYPoint).abs().pow(2)).sqrt()
+ const hypo = Big(
+ calcLinePlaneSize({
+ x1: startXPoint.toNumber(),
+ y1: startYPoint.toNumber(),
+ x2: endXPoint.toNumber(),
+ y2: endYPoint.toNumber(),
+ }),
+ ).div(10)
+ // 현재 지붕선과 마주하는 지붕선을 잇는 선분의 교차점까지의 길이
+ const intersectLength = Big(
+ calcLinePlaneSize({
+ x1: midX.toNumber(),
+ y1: midY.toNumber(),
+ x2: intersectLine.x,
+ y2: intersectLine.y,
+ }),
+ ).div(10)
+ //마주하는 지붕선까지의 길이가 현재 지붕선의 이전, 다음 지붕선의 길이보다 작을때
+ if (intersectLength.lt(Big(prevRoof.attributes.planeSize).div(10)) && intersectLength.lt(Big(nextRoof.attributes.planeSize).div(10))) {
endXPoint = startXPoint
endYPoint = startYPoint
} else {
- if (ridgeMinLength < hypo) {
- endXPoint = Math.round(startXPoint + Math.sign(diffX) * ridgeMinLength)
- endYPoint = Math.round(startYPoint + Math.sign(diffY) * ridgeMinLength)
+ if (ridgeMinLength.lt(hypo)) {
+ endXPoint = startXPoint.plus(Big(Math.sign(diffX.toNumber())).times(ridgeMinLength))
+ endYPoint = startYPoint.plus(Big(Math.sign(diffY.toNumber())).times(ridgeMinLength))
}
}
} else {
- endXPoint = Math.round(startXPoint + Math.sign(alpha) * -1 * ridgeMinLength)
- endYPoint = Math.round(startYPoint + Math.sign(beta) * -1 * ridgeMinLength)
+ endXPoint = startXPoint.plus(Big(Math.sign(alpha.toNumber())).times(ridgeMinLength).neg())
+ endYPoint = startYPoint.plus(Big(Math.sign(beta.toNumber())).times(ridgeMinLength).neg())
}
- const ridge = new QLine([startXPoint, startYPoint, endXPoint, endYPoint], {
+ // 용마루 선을 그린다.
+ const ridge = new QLine([startXPoint.toNumber(), startYPoint.toNumber(), endXPoint.toNumber(), endYPoint.toNumber()], {
parentId: roof.id,
fontSize: roof.fontSize,
stroke: '#1083E3',
strokeWidth: 2,
name: LINE_TYPE.SUBLINE.RIDGE,
- attributes: { roofId: roof.id },
+ textMode: textMode,
+ attributes: {
+ roofId: roof.id,
+ planeSize: calcLinePlaneSize({
+ x1: startXPoint.toNumber(),
+ y1: startYPoint.toNumber(),
+ x2: endXPoint.toNumber(),
+ y2: endYPoint.toNumber(),
+ }),
+ actualSize: calcLinePlaneSize({
+ x1: startXPoint.toNumber(),
+ y1: startYPoint.toNumber(),
+ x2: endXPoint.toNumber(),
+ y2: endYPoint.toNumber(),
+ }),
+ },
})
- ridge.attributes.planeSize = Math.round(Math.sqrt(Math.pow(ridge.x1 - ridge.x2, 2) + Math.pow(ridge.y1 - ridge.y2, 2)) * 10)
- ridge.attributes.actualSize = Math.round(Math.sqrt(Math.pow(ridge.x1 - ridge.x2, 2) + Math.pow(ridge.y1 - ridge.y2, 2)) * 10)
-
+ // 용마루의 길이가 0보다 클때만 canvas 에 추가 한다.
if (ridge.attributes.planeSize > 0) {
canvas.add(ridge)
roof.ridges.push(ridge)
roof.innerLines.push(ridge)
- const distance = (x1, y1, x2, y2) => Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2))
- const dist1 = distance(startXPoint, startYPoint, currentRoof.x1, currentRoof.y1)
- const dist2 = distance(endXPoint, endYPoint, currentRoof.x1, currentRoof.y1)
+ const distance = (x1, y1, x2, y2) => x2.minus(x1).pow(2).plus(y2.minus(y1).pow(2)).sqrt()
+ const dist1 = distance(startXPoint, startYPoint, Big(currentRoof.x1), Big(currentRoof.y1))
+ const dist2 = distance(endXPoint, endYPoint, Big(currentRoof.x1), Big(currentRoof.y1))
currentRoof.attributes.ridgeCoordinate = {
x1: dist1 < dist2 ? startXPoint : endXPoint,
@@ -965,22 +1070,28 @@ const drawRidge = (roof, canvas) => {
let x2 = Math.max(ridge.x1, ridge2.x1, ridge.x2, ridge2.x2)
let y1 = Math.min(ridge.y1, ridge2.y1, ridge.y2, ridge2.y2)
let y2 = Math.max(ridge.y1, ridge2.y1, ridge.y2, ridge2.y2)
+ //겹치는 용마루의 좌표를 합친다.
const newRidge = new QLine([x1, y1, x2, y2], {
parentId: roof.id,
fontSize: roof.fontSize,
stroke: '#1083E3',
strokeWidth: 2,
name: LINE_TYPE.SUBLINE.RIDGE,
- attributes: { roofId: roof.id },
+ textMode: textMode,
+ attributes: {
+ roofId: roof.id,
+ planeSize: calcLinePlaneSize({ x1, y1, x2, y2 }),
+ actualSize: calcLinePlaneSize({ x1, y1, x2, y2 }),
+ },
})
+ //겹치는 용마루를 제거한다.
roof.canvas.remove(ridge)
roof.canvas.remove(ridge2)
+
roof.ridges = roof.ridges.filter((r) => !(ridge.x1 === r.x1 && ridge.y1 === r.y1 && ridge.x2 === r.x2 && ridge.y2 === r.y2))
roof.ridges = roof.ridges.filter((r) => !(ridge2.x1 === r.x1 && ridge2.y1 === r.y1 && ridge2.x2 === r.x2 && ridge2.y2 === r.y2))
roof.innerLines = roof.innerLines.filter((r) => !(ridge.x1 === r.x1 && ridge.y1 === r.y1 && ridge.x2 === r.x2 && ridge.y2 === r.y2))
roof.innerLines = roof.innerLines.filter((r) => !(ridge2.x1 === r.x1 && ridge2.y1 === r.y1 && ridge2.x2 === r.x2 && ridge2.y2 === r.y2))
- newRidge.attributes.planeSize = Math.round(Math.sqrt(Math.pow(ridge.x1 - ridge.x2, 2) + Math.pow(ridge.y1 - ridge.y2, 2)) * 10)
- newRidge.attributes.actualSize = Math.round(Math.sqrt(Math.pow(ridge.x1 - ridge.x2, 2) + Math.pow(ridge.y1 - ridge.y2, 2)) * 10)
canvas.add(newRidge)
roof.ridges.push(newRidge)
roof.innerLines.push(newRidge)
@@ -1035,8 +1146,9 @@ export const segmentsOverlap = (line1, line2) => {
* 추녀마루를 그린다.
* @param roof
* @param canvas
+ * @param textMode
*/
-const drawHips = (roof, canvas) => {
+const drawHips = (roof, canvas, textMode) => {
const roofLines = roof.lines
const ridgeLines = canvas?.getObjects().filter((object) => object.name === LINE_TYPE.SUBLINE.RIDGE && object.attributes.roofId === roof.id)
@@ -1050,50 +1162,84 @@ const drawHips = (roof, canvas) => {
const currentDegree = currentRoof.attributes.pitch > 0 ? getDegreeByChon(currentRoof.attributes.pitch) : currentRoof.attributes.degree
const nextDegree = nextRoof.attributes.pitch > 0 ? getDegreeByChon(nextRoof.attributes.pitch) : nextRoof.attributes.degree
+ //용마루 작성시 입력된 용마루 좌표가 있는 경우 처리
const ridgeCoordinate = currentRoof.attributes.ridgeCoordinate
- const vectorX1 = ridgeCoordinate.x1 - currentRoof.x1
- const vectorY1 = ridgeCoordinate.y1 - currentRoof.y1
- const angle1 = Math.atan2(vectorY1, vectorX1) * (180 / Math.PI)
- if (Math.abs(Math.round(angle1)) % 45 === 0) {
+ const vectorX1 = Big(ridgeCoordinate.x1).minus(Big(currentRoof.x1))
+ const vectorY1 = Big(ridgeCoordinate.y1).minus(Big(currentRoof.y1))
+ //현재 지붕선의 좌표와 용마루 좌표의 각도를 구한다.
+ const angle1 = Big(Math.atan2(vectorY1.toNumber(), vectorX1.toNumber())).times(Big(180).div(Math.PI))
+
+ // 용마루 까지의 각도가 45도 인 경우 작성.
+ if (Big(angle1.abs().toNumber()).mod(45).eq(0)) {
const hip1 = new QLine([currentRoof.x1, currentRoof.y1, ridgeCoordinate.x1, ridgeCoordinate.y1], {
parentId: roof.id,
fontSize: roof.fontSize,
stroke: '#1083E3',
strokeWidth: 2,
name: LINE_TYPE.SUBLINE.HIP,
- attributes: { roofId: roof.id, currentRoofId: currentRoof.id, actualSize: 0 },
+ attributes: {
+ roofId: roof.id,
+ currentRoofId: currentRoof.id,
+ planeSize: calcLinePlaneSize({
+ x1: currentRoof.x1,
+ y1: currentRoof.y1,
+ x2: ridgeCoordinate.x1,
+ y2: ridgeCoordinate.y1,
+ }),
+ actualSize:
+ prevDegree === currentDegree
+ ? calcLineActualSize(
+ {
+ x1: currentRoof.x1,
+ y1: currentRoof.y1,
+ x2: ridgeCoordinate.x1,
+ y2: ridgeCoordinate.y1,
+ },
+ currentDegree,
+ )
+ : 0,
+ },
})
canvas.add(hip1)
- const hip1Base = ((Math.abs(hip1.x1 - hip1.x2) + Math.abs(hip1.y1 - hip1.y2)) / 2) * 10
- const hip1Height = Math.round(hip1Base / Math.tan(((90 - currentDegree) * Math.PI) / 180))
- hip1.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip1.x1 - hip1.x2, 2) + Math.pow(hip1.y1 - hip1.y2, 2))) * 10
- if (prevDegree === currentDegree) {
- hip1.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip1.attributes.planeSize, 2) + Math.pow(hip1Height, 2)))
- }
roof.hips.push(hip1)
roof.innerLines.push(hip1)
}
- const vectorX2 = ridgeCoordinate.x1 - currentRoof.x2
- const vectorY2 = ridgeCoordinate.y1 - currentRoof.y2
- const angle2 = Math.atan2(vectorY2, vectorX2) * (180 / Math.PI)
- if (Math.abs(Math.round(angle2)) % 45 === 0) {
+ const vectorX2 = Big(ridgeCoordinate.x1).minus(Big(currentRoof.x2))
+ const vectorY2 = Big(ridgeCoordinate.y1).minus(Big(currentRoof.y2))
+ const angle2 = Big(Math.atan2(vectorY2.toNumber(), vectorX2.toNumber())).times(Big(180).div(Math.PI))
+ if (Big(angle2.abs().toNumber()).mod(45).eq(0)) {
const hip2 = new QLine([currentRoof.x2, currentRoof.y2, ridgeCoordinate.x1, ridgeCoordinate.y1], {
parentId: roof.id,
fontSize: roof.fontSize,
stroke: '#1083E3',
strokeWidth: 2,
name: LINE_TYPE.SUBLINE.HIP,
- attributes: { roofId: roof.id, currentRoofId: currentRoof.id, actualSize: 0 },
+ attributes: {
+ roofId: roof.id,
+ currentRoofId: currentRoof.id,
+ planeSize: calcLinePlaneSize({
+ x1: currentRoof.x2,
+ y1: currentRoof.y2,
+ x2: ridgeCoordinate.x1,
+ y2: ridgeCoordinate.y1,
+ }),
+ actualSize:
+ prevDegree === currentDegree
+ ? calcLineActualSize(
+ {
+ x1: currentRoof.x2,
+ y1: currentRoof.y2,
+ x2: ridgeCoordinate.x1,
+ y2: ridgeCoordinate.y1,
+ },
+ currentDegree,
+ )
+ : 0,
+ },
})
canvas.add(hip2)
- const hip2Base = ((Math.abs(hip2.x1 - hip2.x2) + Math.abs(hip2.y1 - hip2.y2)) / 2) * 10
- const hip2Height = Math.round(hip2Base / Math.tan(((90 - currentDegree) * Math.PI) / 180))
- hip2.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip2.x1 - hip2.x2, 2) + Math.pow(hip2.y1 - hip2.y2, 2))) * 10
- if (nextDegree === currentDegree) {
- hip2.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip2.attributes.planeSize, 2) + Math.pow(hip2Height, 2)))
- }
roof.hips.push(hip2)
roof.innerLines.push(hip2)
}
@@ -1122,26 +1268,27 @@ const drawHips = (roof, canvas) => {
let ridgePoints = []
ridgeLines.forEach((ridge) => {
- const deltaX1 = Math.round((ridge.x1 - currentRoof.x1) * 10) / 10
- const deltaY1 = Math.round((ridge.y1 - currentRoof.y1) * 10) / 10
- const deltaX2 = Math.round((ridge.x2 - currentRoof.x1) * 10) / 10
- const deltaY2 = Math.round((ridge.y2 - currentRoof.y1) * 10) / 10
+ const deltaX1 = Big(ridge.x1).minus(Big(currentRoof.x1))
+ const deltaY1 = Big(ridge.y1).minus(Big(currentRoof.y1))
+ const deltaX2 = Big(ridge.x2).minus(Big(currentRoof.x1))
+ const deltaY2 = Big(ridge.y2).minus(Big(currentRoof.y1))
- if (Math.round(Math.abs(deltaY1 / deltaX1) * 10) / 10 === 1) {
+ if (deltaY1.div(deltaX1).abs().round(1).eq(1)) {
ridgePoints.push({ x: ridge.x1, y: ridge.y1 })
}
- if (Math.round(Math.abs(deltaY2 / deltaX2) * 10) / 10 === 1) {
+ if (deltaY2.div(deltaX2).abs().round(1).eq(1)) {
ridgePoints.push({ x: ridge.x2, y: ridge.y2 })
}
})
ridgePoints = ridgePoints.reduce((prev, current) => {
if (prev !== undefined) {
- const deltaPrevX = Math.abs(prev.x - currentRoof.x1)
- const deltaPrevY = Math.abs(prev.y - currentRoof.y1)
- const deltaCurrentX = Math.abs(current.x - currentRoof.x1)
- const deltaCurrentY = Math.abs(current.y - currentRoof.y1)
- if (deltaPrevX < deltaCurrentX && deltaPrevY < deltaCurrentY) {
+ // Math.abs(prev.x - currentRoof.x1)
+ const deltaPrevX = Big(prev.x).minus(Big(currentRoof.x1)).abs()
+ const deltaPrevY = Big(prev.y).minus(Big(currentRoof.y1)).abs()
+ const deltaCurrentX = Big(current.x).minus(Big(currentRoof.x1)).abs()
+ const deltaCurrentY = Big(current.y).minus(Big(currentRoof.y1)).abs()
+ if (deltaPrevX.lt(deltaCurrentX) && deltaPrevY.lt(deltaCurrentY)) {
return prev
} else {
return current
@@ -1158,15 +1305,30 @@ const drawHips = (roof, canvas) => {
stroke: '#1083E3',
strokeWidth: 2,
name: LINE_TYPE.SUBLINE.HIP,
- attributes: { roofId: roof.id, currentRoofId: currentRoof.id, actualSize: 0 },
+ attributes: {
+ roofId: roof.id,
+ currentRoofId: currentRoof.id,
+ planeSize: calcLinePlaneSize({
+ x1: currentRoof.x1,
+ y1: currentRoof.y1,
+ x2: ridgePoints.x,
+ y2: ridgePoints.y,
+ }),
+ actualSize:
+ prevDegree === currentDegree
+ ? calcLineActualSize(
+ {
+ x1: currentRoof.x1,
+ y1: currentRoof.y1,
+ x2: ridgePoints.x,
+ y2: ridgePoints.y,
+ },
+ currentDegree,
+ )
+ : 0,
+ },
})
canvas.add(hip)
- const hipBase = ((Math.abs(hip.x1 - hip.x2) + Math.abs(hip.y1 - hip.y2)) / 2) * 10
- const hipHeight = Math.round(hipBase / Math.tan(((90 - currentDegree) * Math.PI) / 180))
- hip.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip.x1 - hip.x2, 2) + Math.pow(hip.y1 - hip.y2, 2))) * 10
- if (prevDegree === currentDegree) {
- hip.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip.attributes.planeSize, 2) + Math.pow(hipHeight, 2)))
- }
roof.hips.push(hip)
roof.innerLines.push(hip)
}
@@ -1178,10 +1340,17 @@ const drawHips = (roof, canvas) => {
* 3개 이상 이어지지 않은 라인 포인트 계산
* 모임지붕에서 point 는 3개 이상의 라인과 접해야 함.
* @param polygon
+ * @param canvas
+ * @param textMode
*/
-const connectLinePoint = (polygon) => {
+const connectLinePoint = (polygon, canvas, textMode) => {
// 연결되지 않은 모든 라인의 포인트를 구한다.
let missedPoints = []
+
+ const lineDegrees = [
+ ...new Set(polygon.lines.map((line) => (line.attributes.pitch > 0 ? getDegreeByChon(line.attributes.pitch) : line.attributes.degree))),
+ ]
+
//마루
polygon.ridges.forEach((ridge) => {
if (ridge.x1 === ridge.x2) {
@@ -1261,13 +1430,16 @@ const connectLinePoint = (polygon) => {
missedLine.forEach((p) => {
const line = new QLine([p.x1, p.y1, p.x2, p.y2], {
parentId: polygon.id,
- attributes: { roofId: polygon.id },
+ attributes: {
+ roofId: polygon.id,
+ planeSize: calcLinePlaneSize(p),
+ actualSize: lineDegrees.length > 0 ? 0 : calcLineActualSize(p, lineDegrees[0]),
+ },
fontSize: polygon.fontSize,
stroke: '#1083E3',
strokeWidth: 2,
+ textMode: textMode,
})
- line.attributes.planeSize = Math.round(Math.sqrt(Math.pow(line.x1 - line.x2, 2) + Math.pow(line.y1 - line.y2, 2)) * 10) / 10
- line.attributes.actualSize = Math.round(Math.sqrt(Math.pow(line.x1 - line.x2, 2) + Math.pow(line.y1 - line.y2, 2)) * 10) / 10
polygon.canvas.add(line)
polygon.innerLines.push(line)
})
@@ -1319,10 +1491,15 @@ const connectLinePoint = (polygon) => {
missedLine.forEach((p) => {
const line = new QLine([p.x1, p.y1, p.x2, p.y2], {
- attributes: { roofId: polygon.id },
+ attributes: {
+ roofId: polygon.id,
+ planeSize: calcLinePlaneSize(p),
+ actualSize: lineDegrees.length > 0 ? 0 : calcLineActualSize(p, lineDegrees[0]),
+ },
fontSize: polygon.fontSize,
stroke: '#1083E3',
strokeWidth: 2,
+ textMode: textMode,
})
line.attributes.planeSize = Math.round(Math.sqrt(Math.pow(line.x1 - line.x2, 2) + Math.pow(line.y1 - line.y2, 2)) * 10)
line.attributes.actualSize = Math.round(Math.sqrt(Math.pow(line.x1 - line.x2, 2) + Math.pow(line.y1 - line.y2, 2)) * 10)
@@ -1378,7 +1555,12 @@ const connectLinePoint = (polygon) => {
stroke: '#1083E3',
strokeWidth: 2,
name: LINE_TYPE.SUBLINE.RIDGE,
- attributes: { roofId: polygon.id },
+ textMode: textMode,
+ attributes: {
+ roofId: polygon.id,
+ planeSize: calcLinePlaneSize(ridge),
+ actualSize: lineDegrees.length > 0 ? 0 : calcLineActualSize(ridge, lineDegrees[0]),
+ },
})
if (polygon.ridges.filter((r) => newRidge.x1 === r.x1 && newRidge.y1 === r.y1 && newRidge.x2 === r.x2 && newRidge.y2 === r.y2).length === 0) {
polygon.canvas.remove(ridge)
@@ -1400,7 +1582,13 @@ const connectLinePoint = (polygon) => {
polygon.canvas.renderAll()
}
-const modifyRidge = (roof, canvas) => {
+/**
+ * 외벽선 속성에 따라서 모양을 수정한다.
+ * @param roof
+ * @param canvas
+ * @param textMode
+ */
+const modifyRidge = (roof, canvas, textMode) => {
const ridgeLines = canvas?.getObjects().filter((object) => object.name === LINE_TYPE.SUBLINE.RIDGE && object.attributes.roofId === roof.id)
const hipLines = canvas?.getObjects().filter((object) => object.name === LINE_TYPE.SUBLINE.HIP && object.attributes.roofId === roof.id)
@@ -1430,19 +1618,19 @@ const modifyRidge = (roof, canvas) => {
if (currentRoof !== undefined) {
switch (currentRoof.attributes.type) {
case LINE_TYPE.WALLLINE.EAVES:
- changeEavesRoof(currentRoof, canvas)
+ changeEavesRoof(currentRoof, canvas, textMode)
break
case LINE_TYPE.WALLLINE.GABLE:
- changeGableRoof(currentRoof, canvas)
+ changeGableRoof(currentRoof, canvas, textMode)
break
case LINE_TYPE.WALLLINE.HIPANDGABLE:
- changeHipAndGableRoof(currentRoof, canvas)
+ changeHipAndGableRoof(currentRoof, canvas, textMode)
break
case LINE_TYPE.WALLLINE.JERKINHEAD:
- changeJerkInHeadRoof(currentRoof, canvas)
+ changeJerkInHeadRoof(currentRoof, canvas, textMode)
break
case LINE_TYPE.WALLLINE.WALL:
- changeWallRoof(currentRoof, canvas)
+ changeWallRoof(currentRoof, canvas, textMode)
break
}
}
@@ -1470,19 +1658,19 @@ const modifyRidge = (roof, canvas) => {
if (currentRoof !== undefined) {
switch (currentRoof.attributes.type) {
case LINE_TYPE.WALLLINE.EAVES:
- changeEavesRoof(currentRoof, canvas)
+ changeEavesRoof(currentRoof, canvas, textMode)
break
case LINE_TYPE.WALLLINE.GABLE:
- changeGableRoof(currentRoof, canvas)
+ changeGableRoof(currentRoof, canvas, textMode)
break
case LINE_TYPE.WALLLINE.HIPANDGABLE:
- changeHipAndGableRoof(currentRoof, canvas)
+ changeHipAndGableRoof(currentRoof, canvas, textMode)
break
case LINE_TYPE.WALLLINE.JERKINHEAD:
- changeJerkInHeadRoof(currentRoof, canvas)
+ changeJerkInHeadRoof(currentRoof, canvas, textMode)
break
case LINE_TYPE.WALLLINE.WALL:
- changeWallRoof(currentRoof, canvas)
+ changeWallRoof(currentRoof, canvas, textMode)
break
}
}
@@ -1501,8 +1689,9 @@ const getMaxRidge = (length) => {
* 처마지붕으로 변경
* @param currentRoof
* @param canvas
+ * @param textMode
*/
-const changeEavesRoof = (currentRoof, canvas) => {
+const changeEavesRoof = (currentRoof, canvas, textMode) => {
if (currentRoof.attributes.type === LINE_TYPE.WALLLINE.EAVES) {
const roofId = currentRoof.attributes.roofId
const wall = canvas?.getObjects().find((object) => object.name === POLYGON_TYPE.WALL && object.attributes.roofId === roofId)
@@ -1522,15 +1711,15 @@ const changeEavesRoof = (currentRoof, canvas) => {
}
})
- const midX = (currentRoof.x1 + currentRoof.x2) / 2 // 지붕의 X 중심
- const midY = (currentRoof.y1 + currentRoof.y2) / 2 // 지붕의 Y 중심
- const midWallX = (wallLine.x1 + wallLine.x2) / 2 // 벽의 X 중심
- const midWallY = (wallLine.y1 + wallLine.y2) / 2 // 벽의 Y 중심
- const alpha = midX - midWallX // 벽과 지붕의 X 거리
- const beta = midY - midWallY // 벽과 지붕의 Y 거리
- const hypotenuse = Math.sqrt(Math.pow(alpha, 2) + Math.pow(beta, 2)) // 벽과 지붕의 거리
- const hipX2 = Math.round(midX + -1 * (alpha / hypotenuse) * (currentRoof.length / 2))
- const hipY2 = Math.round(midY + -1 * (beta / hypotenuse) * (currentRoof.length / 2))
+ const midX = Big(currentRoof.x1).plus(Big(currentRoof.x2)).div(2) // 지붕의 X 중심
+ const midY = Big(currentRoof.y1).plus(Big(currentRoof.y2)).div(2) // 지붕의 Y 중심
+ const midWallX = Big(wallLine.x1).plus(Big(wallLine.x2)).div(2)
+ const midWallY = Big(wallLine.y1).plus(Big(wallLine.y2)).div(2) // 벽의 Y 중심
+ const alpha = midX.minus(midWallX) // 벽과 지붕의 X 거리
+ const beta = midY.minus(midWallY) // 벽과 지붕의 Y 거리
+ const hypotenuse = alpha.pow(2).plus(beta.pow(2)).sqrt() // 벽과 지붕의 거리
+ const hipX2 = midX.plus(alpha.div(hypotenuse).times(Big(currentRoof.length).div(2)).neg())
+ const hipY2 = midY.plus(beta.div(hypotenuse).times(Big(currentRoof.length).div(2)).neg())
const innerLines = canvas
?.getObjects()
@@ -1608,8 +1797,8 @@ const changeEavesRoof = (currentRoof, canvas) => {
const ridge = ridgeLines[0]
if (ridge.x1 === currentRoof.attributes.ridgeCoordinate.x1 && ridge.y1 === currentRoof.attributes.ridgeCoordinate.y1) {
ridge.set({
- x1: hipX2,
- y1: hipY2,
+ x1: hipX2.toNumber(),
+ y1: hipY2.toNumber(),
x2: ridge.x2,
y2: ridge.y2,
})
@@ -1619,13 +1808,14 @@ const changeEavesRoof = (currentRoof, canvas) => {
ridge.set({
x1: ridge.x1,
y1: ridge.y1,
- x2: hipX2,
- y2: hipY2,
+ x2: hipX2.toNumber(),
+ y2: hipY2.toNumber(),
})
currentRoof.attributes.ridgeCoordinate = { x1: ridge.x2, y1: ridge.y2 }
}
- ridge.attributes.planeSize = Math.round(Math.sqrt(Math.pow(ridge.x1 - ridge.x2, 2) + Math.pow(ridge.y1 - ridge.y2, 2)) * 10)
- ridge.attributes.actualSize = Math.round(Math.sqrt(Math.pow(ridge.x1 - ridge.x2, 2) + Math.pow(ridge.y1 - ridge.y2, 2)) * 10)
+ //Math.round(Math.sqrt(Math.pow(ridge.x1 - ridge.x2, 2) + Math.pow(ridge.y1 - ridge.y2, 2)) * 10)
+ ridge.attributes.planeSize = calcLinePlaneSize({ x1: ridge.x1, y1: ridge.y1, x2: ridge.x2, y2: ridge.y2 })
+ ridge.attributes.actualSize = calcLinePlaneSize({ x1: ridge.x1, y1: ridge.y1, x2: ridge.x2, y2: ridge.y2 })
}
hipLines.forEach((hip) => {
@@ -1639,47 +1829,61 @@ const changeEavesRoof = (currentRoof, canvas) => {
const currentDegree = currentRoof.attributes.pitch > 0 ? getDegreeByChon(currentRoof.attributes.pitch) : currentRoof.attributes.degree
const nextDegree = nextRoof.attributes.pitch > 0 ? getDegreeByChon(nextRoof.attributes.pitch) : nextRoof.attributes.degree
- const hip1 = new QLine([currentRoof.x1, currentRoof.y1, hipX2, hipY2], {
+ const hip1 = new QLine([currentRoof.x1, currentRoof.y1, hipX2.toNumber(), hipY2.toNumber()], {
parentId: roof.id,
fontSize: roof.fontSize,
stroke: '#1083E3',
strokeWidth: 2,
name: LINE_TYPE.SUBLINE.HIP,
+ textMode: textMode,
attributes: {
roofId: roof.id,
currentRoofId: currentRoof.id,
+ planeSize: calcLinePlaneSize({
+ x1: currentRoof.x1,
+ y1: currentRoof.y1,
+ x2: hipX2.toNumber(),
+ y2: hipY2.toNumber(),
+ }),
+ actualSize:
+ prevDegree === currentDegree
+ ? calcLineActualSize(
+ { x1: currentRoof.x1, y1: currentRoof.y1, x2: hipX2.toNumber(), y2: hipY2.toNumber() },
+ Big(90 - currentDegree).toNumber(),
+ )
+ : 0,
},
})
canvas?.add(hip1)
roof.innerLines.push(hip1)
- const hip1Base = ((Math.abs(hip1.x1 - hip1.x2) + Math.abs(hip1.y1 - hip1.y2)) / 2) * 10
- const hip1Height = Math.round(hip1Base / Math.tan(((90 - currentDegree) * Math.PI) / 180))
- hip1.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip1.x1 - hip1.x2, 2) + Math.pow(hip1.y1 - hip1.y2, 2))) * 10
- if (prevDegree === currentDegree) {
- hip1.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip1.attributes.planeSize, 2) + Math.pow(hip1Height, 2)))
- }
- const hip2 = new QLine([currentRoof.x2, currentRoof.y2, hipX2, hipY2], {
+ const hip2 = new QLine([currentRoof.x2, currentRoof.y2, hipX2.toNumber(), hipY2.toNumber()], {
parentId: roof.id,
fontSize: roof.fontSize,
stroke: '#1083E3',
strokeWidth: 2,
name: LINE_TYPE.SUBLINE.HIP,
+ textMode: textMode,
attributes: {
roofId: roof.id,
currentRoofId: currentRoof.id,
- planeSize: currentRoof.length,
- actualSize: currentRoof.length,
+ planeSize: calcLinePlaneSize({
+ x1: currentRoof.x2,
+ y1: currentRoof.y2,
+ x2: hipX2.toNumber(),
+ y2: hipY2.toNumber(),
+ }),
+ actualSize:
+ currentDegree === nextDegree
+ ? calcLineActualSize(
+ { x1: currentRoof.x2, y1: currentRoof.y2, x2: hipX2.toNumber(), y2: hipY2.toNumber() },
+ Big(90 - currentDegree).toNumber(),
+ )
+ : 0,
},
})
canvas?.add(hip2)
roof.innerLines.push(hip2)
- const hip2Base = ((Math.abs(hip2.x1 - hip2.x2) + Math.abs(hip2.y1 - hip2.y2)) / 2) * 10
- const hip2Height = Math.round(hip2Base / Math.tan(((90 - currentDegree) * Math.PI) / 180))
- hip2.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip2.x1 - hip2.x2, 2) + Math.pow(hip2.y1 - hip2.y2, 2))) * 10
- if (currentDegree === nextDegree) {
- hip2.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip2.attributes.planeSize, 2) + Math.pow(hip2Height, 2)))
- }
}
}
@@ -1687,17 +1891,17 @@ const changeEavesRoof = (currentRoof, canvas) => {
* 박공지붕으로 변경
* @param currentRoof
* @param canvas
+ * @param textMode
*/
-const changeGableRoof = (currentRoof, canvas) => {
+const changeGableRoof = (currentRoof, canvas, textMode) => {
if (currentRoof.attributes.type === LINE_TYPE.WALLLINE.GABLE) {
const roofId = currentRoof.attributes.roofId
- console.log('roofId', roofId)
const roof = canvas?.getObjects().find((object) => object.name === POLYGON_TYPE.ROOF && object.id === roofId)
let hipLines = canvas?.getObjects().filter((object) => object.name === LINE_TYPE.SUBLINE.HIP && object.attributes.roofId === roofId)
let ridgeLines = canvas?.getObjects().filter((object) => object.name === LINE_TYPE.SUBLINE.RIDGE && object.attributes.roofId === roofId)
- const midX = (currentRoof.x1 + currentRoof.x2) / 2 // 지붕의 X 중심
- const midY = (currentRoof.y1 + currentRoof.y2) / 2 // 지붕의 Y 중심
+ const midX = Big(currentRoof.x1).plus(Big(currentRoof.x2)).div(2) // 지붕의 X 중심
+ const midY = Big(currentRoof.y1).plus(Big(currentRoof.y2)).div(2) // 지붕의 Y 중심
const innerLines = canvas
?.getObjects()
@@ -1741,8 +1945,6 @@ const changeGableRoof = (currentRoof, canvas) => {
hipLines = hipLines.filter(
(hip) => (hip.x1 === currentRoof.x1 && hip.y1 === currentRoof.y1) || (hip.x1 === currentRoof.x2 && hip.y1 === currentRoof.y2),
)
- console.log('ridgeLines : ', ridgeLines)
- console.log('hipLines : ', hipLines)
if (hipLines === undefined || hipLines.length === 0) {
hipLines = innerLines.filter(
@@ -1795,8 +1997,8 @@ const changeGableRoof = (currentRoof, canvas) => {
const ridge = ridgeLines[0]
if (ridge.x1 === currentRoof.attributes.ridgeCoordinate.x1 && ridge.y1 === currentRoof.attributes.ridgeCoordinate.y1) {
ridge.set({
- x1: midX,
- y1: midY,
+ x1: midX.toNumber(),
+ y1: midY.toNumber(),
x2: ridge.x2,
y2: ridge.y2,
})
@@ -1806,33 +2008,49 @@ const changeGableRoof = (currentRoof, canvas) => {
ridge.set({
x1: ridge.x1,
y1: ridge.y1,
- x2: midX,
- y2: midY,
+ x2: midX.toNumber(),
+ y2: midY.toNumber(),
})
currentRoof.attributes.ridgeCoordinate = { x1: ridge.x2, y1: ridge.y2 }
}
- ridge.attributes.planeSize = Math.round(Math.sqrt(Math.pow(ridge.x1 - ridge.x2, 2) + Math.pow(ridge.y1 - ridge.y2, 2)) * 10)
- ridge.attributes.actualSize = Math.round(Math.sqrt(Math.pow(ridge.x1 - ridge.x2, 2) + Math.pow(ridge.y1 - ridge.y2, 2)) * 10)
+ ridge.attributes.planeSize = calcLinePlaneSize({ x1: ridge.x1, y1: ridge.y1, x2: ridge.x2, y2: ridge.y2 })
+ ridge.attributes.actualSize = calcLinePlaneSize({ x1: ridge.x1, y1: ridge.y1, x2: ridge.x2, y2: ridge.y2 })
- let hip1 = new QLine([currentRoof.x1, currentRoof.y1, midX, midY], {
+ let hip1 = new QLine([currentRoof.x1, currentRoof.y1, midX.toNumber(), midY.toNumber()], {
parentId: roof.id,
fontSize: roof.fontSize,
stroke: '#1083E3',
strokeWidth: 2,
name: LINE_TYPE.SUBLINE.HIP,
+ textMode: textMode,
attributes: {
roofId: roofId,
currentRoofId: currentRoof.id,
+ planeSize: calcLinePlaneSize({
+ x1: currentRoof.x1,
+ y1: currentRoof.y1,
+ x2: midX.toNumber(),
+ y2: midY.toNumber(),
+ }),
+ actualSize: calcLineActualSize(
+ {
+ x1: currentRoof.x1,
+ y1: currentRoof.y1,
+ x2: midX.toNumber(),
+ y2: midY.toNumber(),
+ },
+ Big(90 - prevDegree),
+ ),
},
})
canvas?.add(hip1)
- const hip1Base = ((Math.abs(hip1.x1 - hip1.x2) + Math.abs(hip1.y1 - hip1.y2)) / 2) * 10
- const hip1Height = Math.round(hip1Base / Math.tan(((90 - prevDegree) * Math.PI) / 180))
- hip1.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip1.x1 - hip1.x2, 2) + Math.pow(hip1.y1 - hip1.y2, 2))) * 10
- hip1.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip1.attributes.planeSize, 2) + Math.pow(hip1Height, 2)))
+ // const hip1Base = ((Math.abs(hip1.x1 - hip1.x2) + Math.abs(hip1.y1 - hip1.y2)) / 2) * 10
+ // const hip1Height = Math.round(hip1Base / Math.tan(((90 - prevDegree) * Math.PI) / 180))
+ // hip1.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip1.x1 - hip1.x2, 2) + Math.pow(hip1.y1 - hip1.y2, 2))) * 10
+ // hip1.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip1.attributes.planeSize, 2) + Math.pow(hip1Height, 2)))
roof.innerLines.push(hip1)
- let hip2 = new QLine([currentRoof.x2, currentRoof.y2, midX, midY], {
+ let hip2 = new QLine([currentRoof.x2, currentRoof.y2, midX.toNumber(), midY.toNumber()], {
parentId: roof.id,
fontSize: roof.fontSize,
stroke: '#1083E3',
@@ -1841,15 +2059,23 @@ const changeGableRoof = (currentRoof, canvas) => {
attributes: {
roofId: roofId,
currentRoofId: currentRoof.id,
- planeSize: currentRoof.length,
- actualSize: currentRoof.length,
+ planeSize: calcLinePlaneSize({
+ x1: currentRoof.x2,
+ y1: currentRoof.y2,
+ x2: midX.toNumber(),
+ y2: midY.toNumber(),
+ }),
+ actualSize: calcLineActualSize(
+ { x1: currentRoof.x2, y1: currentRoof.y2, x2: midX.toNumber(), y2: midY.toNumber() },
+ Big(90 - nextDegree).toNumber(),
+ ),
},
})
canvas?.add(hip2)
- const hip2Base = ((Math.abs(hip2.x1 - hip2.x2) + Math.abs(hip2.y1 - hip2.y2)) / 2) * 10
- const hip2Height = Math.round(hip2Base / Math.tan(((90 - nextDegree) * Math.PI) / 180))
- hip2.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip2.x1 - hip2.x2, 2) + Math.pow(hip2.y1 - hip2.y2, 2))) * 10
- hip2.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip2.attributes.planeSize, 2) + Math.pow(hip2Height, 2)))
+ // const hip2Base = ((Math.abs(hip2.x1 - hip2.x2) + Math.abs(hip2.y1 - hip2.y2)) / 2) * 10
+ // const hip2Height = Math.round(hip2Base / Math.tan(((90 - nextDegree) * Math.PI) / 180))
+ // hip2.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip2.x1 - hip2.x2, 2) + Math.pow(hip2.y1 - hip2.y2, 2))) * 10
+ // hip2.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip2.attributes.planeSize, 2) + Math.pow(hip2Height, 2)))
roof.innerLines.push(hip2)
canvas?.renderAll()
}
@@ -1860,8 +2086,9 @@ const changeGableRoof = (currentRoof, canvas) => {
* 팔작지붕으로 변경
* @param currentRoof
* @param canvas
+ * @param textMode
*/
-const changeHipAndGableRoof = (currentRoof, canvas) => {
+const changeHipAndGableRoof = (currentRoof, canvas, textMode) => {
if (
currentRoof.attributes.type === LINE_TYPE.WALLLINE.HIPANDGABLE &&
currentRoof.attributes.width !== undefined &&
@@ -1885,19 +2112,35 @@ const changeHipAndGableRoof = (currentRoof, canvas) => {
}
})
- const midX = (currentRoof.x1 + currentRoof.x2) / 2 // 지붕의 X 중심
- const midY = (currentRoof.y1 + currentRoof.y2) / 2 // 지붕의 Y 중심
- const midWallX = (wallLine.x1 + wallLine.x2) / 2 // 벽의 X 중심
- const midWallY = (wallLine.y1 + wallLine.y2) / 2 // 벽의 Y 중심
- const alpha = midX - midWallX // 벽과 지붕의 X 거리
- const beta = midY - midWallY // 벽과 지붕의 Y 거리
- const hypotenuse = Math.sqrt(Math.pow(alpha, 2) + Math.pow(beta, 2)) // 벽과 지붕의 거리
- const xWidth = Math.sign(midX - midWallX) * (alpha / hypotenuse) * currentRoof.attributes.width // 지붕의 X 너비
- const yWidth = Math.sign(midY - midWallY) * (beta / hypotenuse) * currentRoof.attributes.width // 지붕의 Y 너비
- const hipX2 = Math.sign(midX - midWallX) * (alpha / hypotenuse) * (currentRoof.length / 2) // 추녀마루의 X 너비
- const hipY2 = Math.sign(midY - midWallY) * (beta / hypotenuse) * (currentRoof.length / 2) // 추녀마루의 Y 너비
+ const midX = Big(currentRoof.x1).plus(Big(currentRoof.x2)).div(2) // 지붕의 X 중심
+ const midY = Big(currentRoof.y1).plus(Big(currentRoof.y2)).div(2) // 지붕의 Y 중심
+ const midWallX = Big(wallLine.x1).plus(Big(wallLine.x2)).div(2) // 벽의 X 중심
+ const midWallY = Big(wallLine.y1).plus(Big(wallLine.y2)).div(2) // 벽의 Y 중심
+ const alpha = midX.minus(midWallX) // 벽과 지붕의 X 거리
+ const beta = midY.minus(midWallY) // 벽과 지붕의 Y 거리
+ // Math.sqrt(Math.pow(alpha, 2) + Math.pow(beta, 2))
+ const hypotenuse = alpha.pow(2).plus(beta.pow(2)).sqrt() // 벽과 지붕의 거리
+ const xWidth = Big(Math.sign(midX.minus(midWallX).toNumber()))
+ .times(alpha.div(hypotenuse))
+ .times(currentRoof.attributes.width) // 지붕의 X 너비
+ const yWidth = Big(Math.sign(midY.minus(midWallY)))
+ .times(beta.div(hypotenuse))
+ .times(currentRoof.attributes.width) // 지붕의 Y 너비
+ const hipX2 = Big(Math.sign(midX.minus(midWallX).toNumber()))
+ .times(alpha.div(hypotenuse))
+ .times(currentRoof.length / 2) // 추녀마루의 X 너비
+ const hipY2 = Big(Math.sign(midY.minus(midWallY)))
+ .times(beta.div(hypotenuse))
+ .times(currentRoof.length / 2) // 추녀마루의 Y 너비
- if (Math.sqrt(Math.pow(xWidth, 2) + Math.pow(yWidth, 2)) < Math.sqrt(Math.pow(hipX2, 2) + Math.pow(hipY2, 2))) {
+ // if (Math.sqrt(Math.pow(xWidth, 2) + Math.pow(yWidth, 2)) < Math.sqrt(Math.pow(hipX2, 2) + Math.pow(hipY2, 2))) {
+ if (
+ xWidth
+ .pow(2)
+ .plus(yWidth.pow(2))
+ .sqrt()
+ .lt(hipX2.pow(2).plus(hipY2.pow(2)).sqrt())
+ ) {
const innerLines = canvas
?.getObjects()
.filter(
@@ -1980,69 +2223,100 @@ const changeHipAndGableRoof = (currentRoof, canvas) => {
if (ridgeLines.length > 0) {
const ridge = ridgeLines[0]
if (ridge.x1 === currentRoof.attributes.ridgeCoordinate.x1 && ridge.y1 === currentRoof.attributes.ridgeCoordinate.y1) {
- const signX = Math.sign(midX - ridge.x1)
- const signY = Math.sign(midY - ridge.y1)
+ const signX = Math.sign(midX.minus(ridge.x1).toNumber())
+ const signY = Math.sign(midY.minus(ridge.y1).toNumber())
ridge.set({
- x1: midX - signX * Math.abs(xWidth),
- y1: midY - signY * Math.abs(yWidth),
+ x1: midX.minus(xWidth.abs().times(signX)).toNumber(),
+ y1: midY.minus(yWidth.abs().times(signY)).toNumber(),
x2: ridge.x2,
y2: ridge.y2,
})
currentRoof.attributes.ridgeCoordinate = { x1: ridge.x1, y1: ridge.y1 }
}
if (ridge.x2 === currentRoof.attributes.ridgeCoordinate.x1 && ridge.y2 === currentRoof.attributes.ridgeCoordinate.y1) {
- const signX = Math.sign(midX - ridge.x2)
- const signY = Math.sign(midY - ridge.y2)
+ const signX = Math.sign(midX.minus(ridge.x2).toNumber())
+ const signY = Math.sign(midY.minus(ridge.y2).toNumber())
ridge.set({
x1: ridge.x1,
y1: ridge.y1,
- x2: midX - signX * Math.abs(xWidth),
- y2: midY - signY * Math.abs(yWidth),
+ x2: midX.minus(xWidth.abs().times(signX)).toNumber(),
+ y2: midY.minus(yWidth.abs().times(signY)).toNumber(),
})
currentRoof.attributes.ridgeCoordinate = { x1: ridge.x2, y1: ridge.y2 }
}
- ridge.attributes.planeSize = Math.round(Math.sqrt(Math.pow(ridge.x1 - ridge.x2, 2) + Math.pow(ridge.y1 - ridge.y2, 2)) * 10)
- ridge.attributes.actualSize = Math.round(Math.sqrt(Math.pow(ridge.x1 - ridge.x2, 2) + Math.pow(ridge.y1 - ridge.y2, 2)) * 10)
+ ridge.attributes.planeSize = calcLinePlaneSize({ x1: ridge.x1, y1: ridge.y1, x2: ridge.x2, y2: ridge.y2 })
+ ridge.attributes.actualSize = calcLinePlaneSize({ x1: ridge.x1, y1: ridge.y1, x2: ridge.x2, y2: ridge.y2 })
}
- const hip1 = new QLine([currentRoof.x1, currentRoof.y1, midX + hipX2, midY + hipY2], {
- parentId: roof.id,
- fontSize: roof.fontSize,
- stroke: '#1083E3',
- strokeWidth: 2,
- name: LINE_TYPE.SUBLINE.HIP,
- attributes: {
- roofId: roof.id,
- currentRoofId: currentRoof.id,
- },
- })
const prevDegree = prevRoof.attributes.pitch > 0 ? getDegreeByChon(prevRoof.attributes.pitch) : prevRoof.attributes.degree
const nextDegree = nextRoof.attributes.pitch > 0 ? getDegreeByChon(nextRoof.attributes.pitch) : nextRoof.attributes.degree
- const hip1Base = ((Math.abs(hip1.x1 - hip1.x2) + Math.abs(hip1.y1 - hip1.y2)) / 2) * 10
- const hip1Height = Math.round(hip1Base / Math.tan(((90 - prevDegree) * Math.PI) / 180))
- hip1.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip1.x1 - hip1.x2, 2) + Math.pow(hip1.y1 - hip1.y2, 2))) * 10
- hip1.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip1.attributes.planeSize, 2) + Math.pow(hip1Height, 2)))
- canvas?.add(hip1)
- roof.innerLines.push(hip1)
-
- const hip2 = new QLine([currentRoof.x2, currentRoof.y2, midX + hipX2, midY + hipY2], {
+ const hip1 = new QLine([currentRoof.x1, currentRoof.y1, midX.plus(hipX2).toNumber(), midY.plus(hipY2).toNumber()], {
parentId: roof.id,
fontSize: roof.fontSize,
stroke: '#1083E3',
strokeWidth: 2,
name: LINE_TYPE.SUBLINE.HIP,
+ textMode: textMode,
attributes: {
roofId: roof.id,
currentRoofId: currentRoof.id,
- planeSize: currentRoof.length,
- actualSize: currentRoof.length,
+ planeSize: calcLinePlaneSize({
+ x1: currentRoof.x1,
+ y1: currentRoof.y1,
+ x2: midX.plus(hipX2).toNumber(),
+ y2: midY.plus(hipY2).toNumber(),
+ }),
+ actualSize: calcLineActualSize(
+ {
+ x1: currentRoof.x1,
+ y1: currentRoof.y1,
+ x2: midX.plus(hipX2).toNumber(),
+ y2: midY.plus(hipY2).toNumber(),
+ },
+ Big(90 - prevDegree).toNumber(),
+ ),
},
})
- const hip2Base = ((Math.abs(hip2.x1 - hip2.x2) + Math.abs(hip2.y1 - hip2.y2)) / 2) * 10
- const hip2Height = Math.round(hip2Base / Math.tan(((90 - nextDegree) * Math.PI) / 180))
- hip2.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip2.x1 - hip2.x2, 2) + Math.pow(hip2.y1 - hip2.y2, 2))) * 10
- hip2.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip2.attributes.planeSize, 2) + Math.pow(hip2Height, 2)))
+
+ // const hip1Base = ((Math.abs(hip1.x1 - hip1.x2) + Math.abs(hip1.y1 - hip1.y2)) / 2) * 10
+ // const hip1Height = Math.round(hip1Base / Math.tan(((90 - prevDegree) * Math.PI) / 180))
+ // hip1.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip1.x1 - hip1.x2, 2) + Math.pow(hip1.y1 - hip1.y2, 2))) * 10
+ // hip1.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip1.attributes.planeSize, 2) + Math.pow(hip1Height, 2)))
+ canvas?.add(hip1)
+ roof.innerLines.push(hip1)
+
+ const hip2 = new QLine([currentRoof.x2, currentRoof.y2, midX.plus(hipX2).toNumber(), midY.plus(hipY2).toNumber()], {
+ parentId: roof.id,
+ fontSize: roof.fontSize,
+ stroke: '#1083E3',
+ strokeWidth: 2,
+ name: LINE_TYPE.SUBLINE.HIP,
+ textMode: textMode,
+ attributes: {
+ roofId: roof.id,
+ currentRoofId: currentRoof.id,
+ planeSize: calcLinePlaneSize({
+ x1: currentRoof.x2,
+ y1: currentRoof.y2,
+ x2: midX.plus(hipX2).toNumber(),
+ y2: midY.plus(hipY2).toNumber(),
+ }),
+ actualSize: calcLineActualSize(
+ {
+ x1: currentRoof.x2,
+ y1: currentRoof.y2,
+ x2: midX.plus(hipX2).toNumber(),
+ y2: midY.plus(hipY2).toNumber(),
+ },
+ Big(90 - nextDegree).toNumber(),
+ ),
+ },
+ })
+ // const hip2Base = ((Math.abs(hip2.x1 - hip2.x2) + Math.abs(hip2.y1 - hip2.y2)) / 2) * 10
+ // const hip2Height = Math.round(hip2Base / Math.tan(((90 - nextDegree) * Math.PI) / 180))
+ // hip2.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip2.x1 - hip2.x2, 2) + Math.pow(hip2.y1 - hip2.y2, 2))) * 10
+ // hip2.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip2.attributes.planeSize, 2) + Math.pow(hip2Height, 2)))
canvas?.add(hip2)
roof.innerLines.push(hip2)
@@ -2050,8 +2324,8 @@ const changeHipAndGableRoof = (currentRoof, canvas) => {
hipLines.push(hip2)
hipLines.forEach((hip) => {
- const singHipX = Math.sign(hip.x1 - midWallX)
- const singHipY = Math.sign(hip.y1 - midWallY)
+ const singHipX = Math.sign(hip.x1 - midWallX.toNumber())
+ const singHipY = Math.sign(hip.y1 - midWallY.toNumber())
hip.set({
x1: hip.x1,
@@ -2062,6 +2336,7 @@ const changeHipAndGableRoof = (currentRoof, canvas) => {
})
hipLines.forEach((hip, i) => {
+ const gableDegree = i === 0 ? prevDegree : nextDegree
const gableLine = new QLine([hip.x2, hip.y2, currentRoof.attributes.ridgeCoordinate.x1, currentRoof.attributes.ridgeCoordinate.y1], {
parentId: roof.id,
fontSize: roof.fontSize,
@@ -2071,15 +2346,30 @@ const changeHipAndGableRoof = (currentRoof, canvas) => {
attributes: {
roofId: roof.id,
currentRoofId: currentRoof.id,
- actualSize: 0,
+ textMode: textMode,
+ planeSize: calcLinePlaneSize({
+ x1: hip.x2,
+ y1: hip.y2,
+ x2: currentRoof.attributes.ridgeCoordinate.x1,
+ y2: currentRoof.attributes.ridgeCoordinate.y1,
+ }),
+ actualSize: calcLineActualSize(
+ {
+ x1: hip.x2,
+ y1: hip.y2,
+ x2: currentRoof.attributes.ridgeCoordinate.x1,
+ y2: currentRoof.attributes.ridgeCoordinate.y1,
+ },
+ Big(90 - gableDegree).toNumber(),
+ ),
},
})
- const gableDegree = i === 0 ? prevDegree : nextDegree
- const gableBase = ((Math.abs(gableLine.x1 - gableLine.x2) + Math.abs(gableLine.y1 - gableLine.y2)) / 2) * 10
- const gableHeight = Math.round(gableBase / Math.tan(((90 - gableDegree) * Math.PI) / 180))
- gableLine.attributes.planeSize =
- Math.round(Math.sqrt(Math.pow(gableLine.x1 - gableLine.x2, 2) + Math.pow(gableLine.y1 - gableLine.y2, 2))) * 10
- gableLine.attributes.actualSize = Math.round(Math.sqrt(Math.pow(gableLine.attributes.planeSize, 2) + Math.pow(gableHeight, 2)))
+
+ // const gableBase = ((Math.abs(gableLine.x1 - gableLine.x2) + Math.abs(gableLine.y1 - gableLine.y2)) / 2) * 10
+ // const gableHeight = Math.round(gableBase / Math.tan(((90 - gableDegree) * Math.PI) / 180))
+ // gableLine.attributes.planeSize =
+ // Math.round(Math.sqrt(Math.pow(gableLine.x1 - gableLine.x2, 2) + Math.pow(gableLine.y1 - gableLine.y2, 2))) * 10
+ // gableLine.attributes.actualSize = Math.round(Math.sqrt(Math.pow(gableLine.attributes.planeSize, 2) + Math.pow(gableHeight, 2)))
canvas?.add(gableLine)
roof.innerLines.push(gableLine)
})
@@ -2092,8 +2382,9 @@ const changeHipAndGableRoof = (currentRoof, canvas) => {
* 반절처 지붕으로 변경
* @param currentRoof
* @param canvas
+ * @param textMode
*/
-const changeJerkInHeadRoof = (currentRoof, canvas) => {
+const changeJerkInHeadRoof = (currentRoof, canvas, textMode) => {
if (
currentRoof.attributes.type === LINE_TYPE.WALLLINE.JERKINHEAD &&
currentRoof.attributes.width !== undefined &&
@@ -2121,21 +2412,36 @@ const changeJerkInHeadRoof = (currentRoof, canvas) => {
const prevDegree = prevRoof.attributes.pitch > 0 ? getDegreeByChon(prevRoof.attributes.pitch) : prevRoof.attributes.degree
const nextDegree = nextRoof.attributes.pitch > 0 ? getDegreeByChon(nextRoof.attributes.pitch) : nextRoof.attributes.degree
- const midX = (currentRoof.x1 + currentRoof.x2) / 2 // 지붕의 X 중심
- const midY = (currentRoof.y1 + currentRoof.y2) / 2 // 지붕의 Y 중심
- const midWallX = (wallLine.x1 + wallLine.x2) / 2 // 벽의 X 중심
- const midWallY = (wallLine.y1 + wallLine.y2) / 2 // 벽의 Y 중심
- const alpha = midX - midWallX // 벽과 지붕의 X 거리
- const beta = midY - midWallY // 벽과 지붕의 Y 거리
- const hypotenuse = Math.sqrt(Math.pow(alpha, 2) + Math.pow(beta, 2)) // 벽과 지붕의 거리
- const xWidth = Math.sign(midX - midWallX) * (alpha / hypotenuse) * (currentRoof.attributes.width / 2) // 지붕의 X 너비
- const yWidth = Math.sign(midY - midWallY) * (beta / hypotenuse) * (currentRoof.attributes.width / 2) // 지붕의 Y 너비
- const addHipX2 = Math.sign(midX - midWallX) * (alpha / hypotenuse) * (currentRoof.length / 2) // 추녀마루의 X 너비
- const addHipY2 = Math.sign(midY - midWallY) * (beta / hypotenuse) * (currentRoof.length / 2) // 추녀마루의 Y 너비
+ const midX = Big(currentRoof.x1).plus(Big(currentRoof.x2)).div(2) // 지붕의 X 중심
+ const midY = Big(currentRoof.y1).plus(Big(currentRoof.y2)).div(2) // 지붕의 Y 중심
+ const midWallX = Big(wallLine.x1).plus(Big(wallLine.x2)).div(2) // 벽의 X 중심
+ const midWallY = Big(wallLine.y1).plus(Big(wallLine.y2)).div(2) // 벽의 Y 중심
+ const alpha = midX.minus(midWallX) // 벽과 지붕의 X 거리
+ const beta = midY.minus(midWallY) // 벽과 지붕의 Y 거리
+ // Math.sqrt(Math.pow(alpha, 2) + Math.pow(beta, 2))
+ const hypotenuse = alpha.pow(2).plus(beta.pow(2)).sqrt() // 벽과 지붕의 거리
+ const xWidth = Big(Math.sign(midX.minus(midWallX).toNumber()))
+ .times(alpha.div(hypotenuse))
+ .times(currentRoof.attributes.width / 2) // 지붕의 X 너비
+ const yWidth = Big(Math.sign(midY.minus(midWallY)))
+ .times(beta.div(hypotenuse))
+ .times(currentRoof.attributes.width / 2) // 지붕의 Y 너비
+ const addHipX2 = Big(Math.sign(midX.minus(midWallX).toNumber()))
+ .times(alpha.div(hypotenuse))
+ .times(currentRoof.length / 2) // 추녀마루의 X 너비
+ const addHipY2 = Big(Math.sign(midY.minus(midWallY)))
+ .times(beta.div(hypotenuse))
+ .times(currentRoof.length / 2) // 추녀마루의 Y 너비
let hipX2 = 0
let hipY2 = 0
- if (Math.sqrt(Math.pow(xWidth, 2) + Math.pow(yWidth, 2)) < Math.sqrt(Math.pow(addHipX2, 2) + Math.pow(addHipY2, 2))) {
+ // if (Math.sqrt(Math.pow(xWidth, 2) + Math.pow(yWidth, 2)) < Math.sqrt(Math.pow(addHipX2, 2) + Math.pow(addHipY2, 2))) {
+ if (
+ xWidth
+ .pow(2)
+ .plus(yWidth.pow(2))
+ .lt(addHipX2.pow(2).plus(addHipY2.pow(2)))
+ ) {
// reDrawPolygon(roof, canvas)
const innerLines = canvas
@@ -2220,11 +2526,11 @@ const changeJerkInHeadRoof = (currentRoof, canvas) => {
if (ridgeLines.length > 0) {
const ridge = ridgeLines[0]
if (ridge.x1 === currentRoof.attributes.ridgeCoordinate.x1 && ridge.y1 === currentRoof.attributes.ridgeCoordinate.y1) {
- const signX = Math.sign(midX - ridge.x1)
- const signY = Math.sign(midY - ridge.y1)
+ const signX = Math.sign(midX.minus(ridge.x1).toNumber())
+ const signY = Math.sign(midY.minus(ridge.y1).toNumber())
ridge.set({
- x1: midX - signX * Math.abs(xWidth),
- y1: midY - signY * Math.abs(yWidth),
+ x1: midX.minus(xWidth.abs().times(signX)).toNumber(),
+ y1: midY.minus(yWidth.abs().times(signY)).toNumber(),
x2: ridge.x2,
y2: ridge.y2,
})
@@ -2239,60 +2545,90 @@ const changeJerkInHeadRoof = (currentRoof, canvas) => {
ridge.set({
x1: ridge.x1,
y1: ridge.y1,
- x2: midX - signX * Math.abs(xWidth),
- y2: midY - signY * Math.abs(yWidth),
+ x2: midX.minus(xWidth.abs().times(signX)).toNumber(),
+ y2: midY.minus(yWidth.abs().times(signY)).toNumber(),
})
currentRoof.attributes.ridgeCoordinate = { x1: ridge.x2, y1: ridge.y2 }
hipX2 = ridge.x2
hipY2 = ridge.y2
}
- ridge.attributes.planeSize = Math.round(Math.sqrt(Math.pow(ridge.x1 - ridge.x2, 2) + Math.pow(ridge.y1 - ridge.y2, 2)) * 10)
- ridge.attributes.actualSize = Math.round(Math.sqrt(Math.pow(ridge.x1 - ridge.x2, 2) + Math.pow(ridge.y1 - ridge.y2, 2)) * 10)
+ ridge.attributes.planeSize = calcLinePlaneSize({ x1: ridge.x1, y1: ridge.y1, x2: ridge.x2, y2: ridge.y2 })
+ ridge.attributes.actualSize = calcLinePlaneSize({ x1: ridge.x1, y1: ridge.y1, x2: ridge.x2, y2: ridge.y2 })
}
let hipX1 = (Math.sign(currentRoof.x1 - midX) * currentRoof.attributes.width) / 2
let hipY1 = (Math.sign(currentRoof.y1 - midY) * currentRoof.attributes.width) / 2
- const gable1 = new QLine([midX + hipX1, midY + hipY1, hipX2, hipY2], {
+ const gableDegree = currentRoof.attributes.degree > 0 ? currentRoof.attributes.degree : getDegreeByChon(currentRoof.attributes.pitch)
+ const gable1 = new QLine([midX.plus(hipX1).toNumber(), midY.plus(hipY1).toNumber(), hipX2, hipY2], {
parentId: roof.id,
fontSize: roof.fontSize,
stroke: '#1083E3',
strokeWidth: 2,
name: LINE_TYPE.SUBLINE.GABLE,
+ textMode: textMode,
attributes: {
roofId: roof.id,
currentRoofId: currentRoof.id,
- actualSize: 0,
+ planeSize: calcLinePlaneSize({
+ x1: midX.plus(hipX1).toNumber(),
+ y1: midY.plus(hipY1).toNumber(),
+ x2: hipX2,
+ y2: hipY2,
+ }),
+ actualSize: calcLineActualSize(
+ {
+ x1: midX.plus(hipX1).toNumber(),
+ y1: midY.plus(hipY1).toNumber(),
+ x2: hipX2,
+ y2: hipY2,
+ },
+ Big(90 - gableDegree).toNumber(),
+ ),
},
})
- const gableDegree = currentRoof.attributes.degree > 0 ? currentRoof.attributes.degree : getDegreeByChon(currentRoof.attributes.pitch)
- const gable1Base = ((Math.abs(gable1.x1 - gable1.x2) + Math.abs(gable1.y1 - gable1.y2)) / 2) * 10
- const gable1Height = Math.round(gable1Base / Math.tan(((90 - gableDegree) * Math.PI) / 180))
- gable1.attributes.planeSize = Math.round(Math.sqrt(Math.pow(gable1.x1 - gable1.x2, 2) + Math.pow(gable1.y1 - gable1.y2, 2))) * 10
- gable1.attributes.actualSize = Math.round(Math.sqrt(Math.pow(gable1.attributes.planeSize, 2) + Math.pow(gable1Height, 2)))
+ // const gable1Base = ((Math.abs(gable1.x1 - gable1.x2) + Math.abs(gable1.y1 - gable1.y2)) / 2) * 10
+ // const gable1Height = Math.round(gable1Base / Math.tan(((90 - gableDegree) * Math.PI) / 180))
+ // gable1.attributes.planeSize = Math.round(Math.sqrt(Math.pow(gable1.x1 - gable1.x2, 2) + Math.pow(gable1.y1 - gable1.y2, 2))) * 10
+ // gable1.attributes.actualSize = Math.round(Math.sqrt(Math.pow(gable1.attributes.planeSize, 2) + Math.pow(gable1Height, 2)))
canvas?.add(gable1)
roof.innerLines.push(gable1)
hipX1 = (Math.sign(currentRoof.x2 - midX) * currentRoof.attributes.width) / 2
hipY1 = (Math.sign(currentRoof.y2 - midY) * currentRoof.attributes.width) / 2
- const gable2 = new QLine([midX + hipX1, midY + hipY1, hipX2, hipY2], {
+ const gable2 = new QLine([midX.plus(hipX1).toNumber(), midY.plus(hipY1).toNumber(), hipX2, hipY2], {
parentId: roof.id,
fontSize: roof.fontSize,
stroke: '#1083E3',
strokeWidth: 2,
name: LINE_TYPE.SUBLINE.GABLE,
+ textMode: textMode,
attributes: {
roofId: roof.id,
currentRoofId: currentRoof.id,
- actualSize: 0,
+ planeSize: calcLinePlaneSize({
+ x1: midX.plus(hipX1).toNumber(),
+ y1: midY.plus(hipY1).toNumber(),
+ x2: hipX2,
+ y2: hipY2,
+ }),
+ actualSize: calcLineActualSize(
+ {
+ x1: midX.plus(hipX1).toNumber(),
+ y1: midY.plus(hipY1).toNumber(),
+ x2: hipX2,
+ y2: hipY2,
+ },
+ Big(90 - gableDegree).toNumber(),
+ ),
},
})
- const gable2Base = ((Math.abs(gable2.x1 - gable2.x2) + Math.abs(gable2.y1 - gable2.y2)) / 2) * 10
- const gable2Height = Math.round(gable2Base / Math.tan(((90 - gableDegree) * Math.PI) / 180))
- gable2.attributes.planeSize = Math.round(Math.sqrt(Math.pow(gable2.x1 - gable2.x2, 2) + Math.pow(gable2.y1 - gable2.y2, 2))) * 10
- gable2.attributes.actualSize = Math.round(Math.sqrt(Math.pow(gable2.attributes.planeSize, 2) + Math.pow(gable2Height, 2)))
+ // const gable2Base = ((Math.abs(gable2.x1 - gable2.x2) + Math.abs(gable2.y1 - gable2.y2)) / 2) * 10
+ // const gable2Height = Math.round(gable2Base / Math.tan(((90 - gableDegree) * Math.PI) / 180))
+ // gable2.attributes.planeSize = Math.round(Math.sqrt(Math.pow(gable2.x1 - gable2.x2, 2) + Math.pow(gable2.y1 - gable2.y2, 2))) * 10
+ // gable2.attributes.actualSize = Math.round(Math.sqrt(Math.pow(gable2.attributes.planeSize, 2) + Math.pow(gable2Height, 2)))
canvas?.add(gable2)
roof.innerLines.push(gable2)
@@ -2302,14 +2638,17 @@ const changeJerkInHeadRoof = (currentRoof, canvas) => {
stroke: '#1083E3',
strokeWidth: 2,
name: LINE_TYPE.SUBLINE.GABLE,
+ textMode: textMode,
+ visible: false,
attributes: {
roofId: roof.id,
currentRoofId: currentRoof.id,
- actualSize: 0,
+ planeSize: calcLinePlaneSize({ x1: gable1.x1, y1: gable1.y1, x2: gable2.x1, y2: gable2.y1 }),
+ actualSize: calcLinePlaneSize({ x1: gable1.x1, y1: gable1.y1, x2: gable2.x1, y2: gable2.y1 }),
},
})
- gable3.attributes.planeSize = Math.round(Math.sqrt(Math.pow(gable3.x1 - gable3.x2, 2) + Math.pow(gable3.y1 - gable3.y2, 2))) * 10
- gable3.attributes.actualSize = Math.round(Math.sqrt(Math.pow(gable3.x1 - gable3.x2, 2) + Math.pow(gable3.y1 - gable3.y2, 2))) * 10
+ // gable3.attributes.planeSize = Math.round(Math.sqrt(Math.pow(gable3.x1 - gable3.x2, 2) + Math.pow(gable3.y1 - gable3.y2, 2))) * 10
+ // gable3.attributes.actualSize = Math.round(Math.sqrt(Math.pow(gable3.x1 - gable3.x2, 2) + Math.pow(gable3.y1 - gable3.y2, 2))) * 10
canvas?.add(gable3)
// roof.innerLines.push(gable3)
@@ -2319,16 +2658,27 @@ const changeJerkInHeadRoof = (currentRoof, canvas) => {
stroke: '#1083E3',
strokeWidth: 2,
name: LINE_TYPE.SUBLINE.HIP,
+ textMode: textMode,
+ visible: false,
attributes: {
roofId: roof.id,
currentRoofId: currentRoof.id,
- actualSize: 0,
+ planeSize: calcLinePlaneSize({ x1: currentRoof.x1, y1: currentRoof.y1, x2: gable1.x1, y2: gable1.y1 }),
+ actualSize: calcLineActualSize(
+ {
+ x1: currentRoof.x1,
+ y1: currentRoof.y1,
+ x2: gable1.x1,
+ y2: gable1.y1,
+ },
+ Big(90 - prevDegree).toNumber(),
+ ),
},
})
- const hip1Base = ((Math.abs(hip1.x1 - hip1.x2) + Math.abs(hip1.y1 - hip1.y2)) / 2) * 10
- const hip1Height = Math.round(hip1Base / Math.tan(((90 - prevDegree) * Math.PI) / 180))
- hip1.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip1.x1 - hip1.x2, 2) + Math.pow(hip1.y1 - hip1.y2, 2))) * 10
- hip1.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip1.attributes.planeSize, 2) + Math.pow(hip1Height, 2)))
+ // const hip1Base = ((Math.abs(hip1.x1 - hip1.x2) + Math.abs(hip1.y1 - hip1.y2)) / 2) * 10
+ // const hip1Height = Math.round(hip1Base / Math.tan(((90 - prevDegree) * Math.PI) / 180))
+ // hip1.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip1.x1 - hip1.x2, 2) + Math.pow(hip1.y1 - hip1.y2, 2))) * 10
+ // hip1.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip1.attributes.planeSize, 2) + Math.pow(hip1Height, 2)))
canvas?.add(hip1)
// roof.innerLines.push(hip1)
@@ -2338,25 +2688,34 @@ const changeJerkInHeadRoof = (currentRoof, canvas) => {
stroke: '#1083E3',
strokeWidth: 2,
name: LINE_TYPE.SUBLINE.HIP,
+ textMode: textMode,
+ visible: false,
attributes: {
roofId: roof.id,
currentRoofId: currentRoof.id,
- actualSize: 0,
+ planeSize: calcLinePlaneSize({ x1: currentRoof.x2, y1: currentRoof.y2, x2: gable2.x1, y2: gable2.y1 }),
+ actualSize: calcLineActualSize(
+ {
+ x1: currentRoof.x2,
+ y1: currentRoof.y2,
+ x2: gable2.x1,
+ y2: gable2.y1,
+ },
+ Big(90 - nextDegree).toNumber(),
+ ),
},
})
- const hip2Base = ((Math.abs(hip2.x1 - hip2.x2) + Math.abs(hip2.y1 - hip2.y2)) / 2) * 10
- const hip2Height = Math.round(hip2Base / Math.tan(((90 - nextDegree) * Math.PI) / 180))
- hip2.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip2.x1 - hip2.x2, 2) + Math.pow(hip2.y1 - hip2.y2, 2))) * 10
- hip2.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip2.attributes.planeSize, 2) + Math.pow(hip2Height, 2)))
+ // const hip2Base = ((Math.abs(hip2.x1 - hip2.x2) + Math.abs(hip2.y1 - hip2.y2)) / 2) * 10
+ // const hip2Height = Math.round(hip2Base / Math.tan(((90 - nextDegree) * Math.PI) / 180))
+ // hip2.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip2.x1 - hip2.x2, 2) + Math.pow(hip2.y1 - hip2.y2, 2))) * 10
+ // hip2.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip2.attributes.planeSize, 2) + Math.pow(hip2Height, 2)))
canvas?.add(hip2)
- console.log('currentRoof.id : ', currentRoof.id)
-
- hip1.set({ visible: false })
+ // hip1.set({ visible: false })
hip1.setViewLengthText(false)
- gable3.set({ visible: false })
+ // gable3.set({ visible: false })
gable3.setViewLengthText(false)
- hip2.set({ visible: false })
+ // hip2.set({ visible: false })
hip2.setViewLengthText(false)
}
}
@@ -2366,8 +2725,9 @@ const changeJerkInHeadRoof = (currentRoof, canvas) => {
* 벽지붕으로 변경
* @param currentRoof
* @param canvas
+ * @param textMode
*/
-const changeWallRoof = (currentRoof, canvas) => {
+const changeWallRoof = (currentRoof, canvas, textMode) => {
const roofId = currentRoof.attributes.roofId
const roof = canvas?.getObjects().find((object) => object.name === 'roof' && object.id === roofId)
const roofLines = roof.lines
@@ -2398,31 +2758,31 @@ const changeWallRoof = (currentRoof, canvas) => {
(hip) => (hip.x1 === currentRoof.x1 && hip.y1 === currentRoof.y1) || (hip.x1 === currentRoof.x2 && hip.y1 === currentRoof.y2),
)
- const wallMidX = (wallLine.x1 + wallLine.x2) / 2
- const wallMidY = (wallLine.y1 + wallLine.y2) / 2
- const roofMidX = (currentRoof.x1 + currentRoof.x2) / 2
- const roofMidY = (currentRoof.y1 + currentRoof.y2) / 2
+ const wallMidX = Big(wallLine.x1).plus(Big(wallLine.x2)).div(2)
+ const wallMidY = Big(wallLine.y1).plus(Big(wallLine.y2)).div(2)
+ const roofMidX = Big(currentRoof.x1).plus(Big(currentRoof.x2)).div(2)
+ const roofMidY = Big(currentRoof.y1).plus(Big(currentRoof.y2)).div(2)
- const alpha = wallMidX - roofMidX === 0 ? 0 : wallMidX - roofMidX
- const beta = wallMidY - roofMidY === 0 ? 0 : wallMidY - roofMidY
+ const alpha = wallMidX.minus(roofMidX)
+ const beta = wallMidY.minus(roofMidY)
currentRoof.set({
- x1: currentRoof.x1 + alpha,
- y1: currentRoof.y1 + beta,
- x2: currentRoof.x2 + alpha,
- y2: currentRoof.y2 + beta,
+ x1: alpha.plus(currentRoof.x1).toNumber(),
+ y1: beta.plus(currentRoof.y1).toNumber(),
+ x2: alpha.plus(currentRoof.x2).toNumber(),
+ y2: beta.plus(currentRoof.y2).toNumber(),
})
prevRoof.set({
x1: prevRoof.x1,
y1: prevRoof.y1,
- x2: prevRoof.x2 + alpha,
- y2: prevRoof.y2 + beta,
+ x2: alpha.plus(prevRoof.x2),
+ y2: beta.plus(prevRoof.y2),
})
nextRoof.set({
- x1: nextRoof.x1 + alpha,
- y1: nextRoof.y1 + beta,
+ x1: alpha.plus(nextRoof.x1),
+ y1: beta.plus(nextRoof.y1),
x2: nextRoof.x2,
y2: nextRoof.y2,
})
@@ -2464,10 +2824,10 @@ const changeWallRoof = (currentRoof, canvas) => {
const prevWidthY = prevSignY === 0 ? 0 : prevSignY * currentRoof.attributes.width
const nextWidthX = nextSignX === 0 ? 0 : nextSignX * currentRoof.attributes.width
const nextWidthY = nextSignY === 0 ? 0 : nextSignY * currentRoof.attributes.width
- const prevX2 = prevRoof.x2 - prevWidthX
- const prevY2 = prevRoof.y2 - prevWidthY
- const nextX1 = nextRoof.x1 + nextWidthX
- const nextY1 = nextRoof.y1 + nextWidthY
+ const prevX2 = Big(prevRoof.x2).minus(prevWidthX)
+ const prevY2 = Big(prevRoof.y2).minus(prevWidthY)
+ const nextX1 = Big(nextRoof.x1).plus(nextWidthX)
+ const nextY1 = Big(nextRoof.y1).plus(nextWidthY)
currentRoof.set({
x1: wallLine.x1,
@@ -2479,54 +2839,126 @@ const changeWallRoof = (currentRoof, canvas) => {
prevRoof.set({
x1: prevRoof.x1,
y1: prevRoof.y1,
- x2: prevX2,
- y2: prevY2,
+ x2: prevX2.toNumber(),
+ y2: prevY2.toNumber(),
})
nextRoof.set({
- x1: nextX1,
- y1: nextY1,
+ x1: nextX1.toNumber(),
+ y1: nextY1.toNumber(),
x2: nextRoof.x2,
y2: nextRoof.y2,
})
- const addPrevWallLine1 = new QLine([prevX2, prevY2, wallLine.x1 - prevWidthX, wallLine.y1 - prevWidthY], {
- parentId: roof.id,
- fontSize: roof.fontSize,
- stroke: '#1083E3',
- strokeWidth: 2,
- name: 'roofLine',
- attributes: { roofId: roofId, type: LINE_TYPE.WALLLINE.ETC },
- })
-
- const addPrevWallLine2 = new QLine(
- [addPrevWallLine1.x2, addPrevWallLine1.y2, addPrevWallLine1.x2 + prevWidthX, addPrevWallLine1.y2 + prevWidthY],
+ const addPrevWallLine1 = new QLine(
+ [prevX2.toNumber(), prevY2.toNumber(), Big(wallLine.x1).minus(prevWidthX).toNumber(), Big(wallLine.y1).minus(prevWidthY).toNumber()],
{
parentId: roof.id,
fontSize: roof.fontSize,
stroke: '#1083E3',
strokeWidth: 2,
name: 'roofLine',
- attributes: { roofId: roofId, type: LINE_TYPE.WALLLINE.ETC },
+ textMode: textMode,
+ attributes: {
+ roofId: roofId,
+ type: LINE_TYPE.WALLLINE.ETC,
+ planeSize: calcLinePlaneSize({
+ x1: prevX2.toNumber(),
+ y1: prevY2.toNumber(),
+ x2: Big(wallLine.x1).minus(prevWidthX).toNumber(),
+ y2: Big(wallLine.y1).minus(prevWidthY).toNumber(),
+ }),
+ actualSize: calcLinePlaneSize({
+ x1: prevX2.toNumber(),
+ y1: prevY2.toNumber(),
+ x2: Big(wallLine.x1).minus(prevWidthX).toNumber(),
+ y2: Big(wallLine.y1).minus(prevWidthY).toNumber(),
+ }),
+ },
},
)
- const addNextWallLine1 = new QLine([wallLine.x2, wallLine.y2, wallLine.x2 + nextWidthX, wallLine.y2 + nextWidthY], {
- parentId: roof.id,
- fontSize: roof.fontSize,
- stroke: '#1083E3',
- strokeWidth: 2,
- name: 'roofLine',
- attributes: { roofId: roofId, type: LINE_TYPE.WALLLINE.ETC },
- })
+ const addPrevWallLine2 = new QLine(
+ [
+ addPrevWallLine1.x2,
+ addPrevWallLine1.y2,
+ Big(addPrevWallLine1.x2).plus(prevWidthX).toNumber(),
+ Big(addPrevWallLine1.y2).plus(prevWidthY).toNumber(),
+ ],
+ {
+ parentId: roof.id,
+ fontSize: roof.fontSize,
+ stroke: '#1083E3',
+ strokeWidth: 2,
+ name: 'roofLine',
+ textMode: textMode,
+ attributes: {
+ roofId: roofId,
+ type: LINE_TYPE.WALLLINE.ETC,
+ planeSize: calcLinePlaneSize({
+ x1: addPrevWallLine1.x2,
+ y1: addPrevWallLine1.y2,
+ x2: Big(addPrevWallLine1.x2).plus(prevWidthX).toNumber(),
+ y2: Big(addPrevWallLine1.y2).plus(prevWidthY).toNumber(),
+ }),
+ actualSize: calcLinePlaneSize({
+ x1: addPrevWallLine1.x2,
+ y1: addPrevWallLine1.y2,
+ x2: Big(addPrevWallLine1.x2).plus(prevWidthX).toNumber(),
+ y2: Big(addPrevWallLine1.y2).plus(prevWidthY).toNumber(),
+ }),
+ },
+ },
+ )
- const addNextWallLine2 = new QLine([addNextWallLine1.x2, addNextWallLine1.y2, nextX1, nextY1], {
+ const addNextWallLine1 = new QLine(
+ [wallLine.x2, wallLine.y2, Big(wallLine.x2).plus(nextWidthX).toNumber(), Big(wallLine.y2).plus(nextWidthY).toNumber()],
+ {
+ parentId: roof.id,
+ fontSize: roof.fontSize,
+ stroke: '#1083E3',
+ strokeWidth: 2,
+ name: 'roofLine',
+ textMode: textMode,
+ attributes: {
+ roofId: roofId,
+ type: LINE_TYPE.WALLLINE.ETC,
+ planeSize: calcLinePlaneSize({
+ x1: wallLine.x2,
+ y1: wallLine.y2,
+ x2: Big(wallLine.x2).plus(nextWidthX).toNumber(),
+ y2: Big(wallLine.y2).plus(nextWidthY).toNumber(),
+ }),
+ actualSize: calcLinePlaneSize({
+ x1: wallLine.x2,
+ y1: wallLine.y2,
+ }),
+ },
+ },
+ )
+
+ const addNextWallLine2 = new QLine([addNextWallLine1.x2, addNextWallLine1.y2, nextX1.toNumber(), nextY1.toNumber()], {
parentId: roof.id,
fontSize: roof.fontSize,
stroke: '#1083E3',
strokeWidth: 2,
name: 'roofLine',
- attributes: { roofId: roofId, type: LINE_TYPE.WALLLINE.ETC },
+ attributes: {
+ roofId: roofId,
+ type: LINE_TYPE.WALLLINE.ETC,
+ planeSize: calcLinePlaneSize({
+ x1: addNextWallLine1.x2,
+ y1: addNextWallLine1.y2,
+ x2: nextX1.toNumber(),
+ y2: nextY1.toNumber(),
+ }),
+ actualSize: calcLinePlaneSize({
+ x1: addNextWallLine1.x2,
+ y1: addNextWallLine1.y2,
+ x2: nextX1.toNumber(),
+ y2: nextY1.toNumber(),
+ }),
+ },
})
canvas?.renderAll()
@@ -2542,31 +2974,59 @@ const changeWallRoof = (currentRoof, canvas) => {
if (ridgeLines.length > 0) {
const ridge = ridgeLines[0]
if (ridge.x1 === currentRoof.attributes.ridgeCoordinate.x1 && ridge.y1 === currentRoof.attributes.ridgeCoordinate.y1) {
- const diffX = ridge.x1 - wallMidX === 0 ? 0 : ridge.x1 - wallMidX
- const diffY = ridge.y1 - wallMidY === 0 ? 0 : ridge.y1 - wallMidY
+ const diffX = Big(ridge.x1).minus(wallMidX)
+ const diffY = Big(ridge.y1).minus(wallMidY)
ridge.set({
- x1: ridge.x1 - diffX,
- y1: ridge.y1 - diffY,
+ x1: Big(ridge.x1).minus(diffX).toNumber(),
+ y1: Big(ridge.y1).minus(diffY).toNumber(),
x2: ridge.x2,
y2: ridge.y2,
})
}
if (ridge.x2 === currentRoof.attributes.ridgeCoordinate.x1 && ridge.y2 === currentRoof.attributes.ridgeCoordinate.y1) {
- const diffX = ridge.x2 - wallMidX === 0 ? 0 : ridge.x2 - wallMidX
- const diffY = ridge.y2 - wallMidY === 0 ? 0 : ridge.y2 - wallMidY
+ const diffX = Big(ridge.x2).minus(wallMidX)
+ const diffY = Big(ridge.y2).minus(wallMidY)
ridge.set({
x1: ridge.x1,
y1: ridge.y1,
- x2: ridge.x2 - diffX,
- y2: ridge.y2 - diffY,
+ x2: Big(ridge.x2).minus(diffX).toNumber(),
+ y2: Big(ridge.y2).minus(diffY).toNumber(),
})
}
- ridge.attributes.planeSize = Math.round(Math.sqrt(Math.pow(ridge.x1 - ridge.x2, 2) + Math.pow(ridge.y1 - ridge.y2, 2)) * 10)
- ridge.attributes.actualSize = Math.round(Math.sqrt(Math.pow(ridge.x1 - ridge.x2, 2) + Math.pow(ridge.y1 - ridge.y2, 2)) * 10)
+ // ridge.attributes.planeSize = Math.round(Math.sqrt(Math.pow(ridge.x1 - ridge.x2, 2) + Math.pow(ridge.y1 - ridge.y2, 2)) * 10)
+ ridge.attributes.planeSize = calcLinePlaneSize({ x1: ridge.x1, y1: ridge.y1, x2: ridge.x2, y2: ridge.y2 })
+ ridge.attributes.actualSize = calcLinePlaneSize({ x1: ridge.x1, y1: ridge.y1, x2: ridge.x2, y2: ridge.y2 })
- let hip1 = new QLine([currentRoof.x1, currentRoof.y1, wallMidX, wallMidY], {
+ let hip1 = new QLine([currentRoof.x1, currentRoof.y1, wallMidX.toNumber(), wallMidY.toNumber()], {
+ parentId: roof.id,
+ fontSize: roof.fontSize,
+ stroke: '#1083E3',
+ strokeWidth: 2,
+ name: LINE_TYPE.SUBLINE.HIP,
+ textMode: textMode,
+ attributes: {
+ roofId: roof.id,
+ currentRoofId: currentRoof.id,
+ planeSize: calcLinePlaneSize({
+ x1: currentRoof.x1,
+ y1: currentRoof.y1,
+ x2: wallMidX.toNumber(),
+ y2: wallMidY.toNumber(),
+ }),
+ actualSize: calcLineActualSize(
+ { x1: currentRoof.x1, y1: currentRoof.y1, x2: wallMidX.toNumber(), y2: wallMidY.toNumber() },
+ Big(90 - prevDegree).toNumber(),
+ ),
+ },
+ })
+ // const hip1Base = ((Math.abs(hip1.x1 - hip1.x2) + Math.abs(hip1.y1 - hip1.y2)) / 2) * 10
+ // const hip1Height = Math.round(hip1Base / Math.tan(((90 - prevDegree) * Math.PI) / 180))
+ // hip1.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip1.x1 - hip1.x2, 2) + Math.pow(hip1.y1 - hip1.y2, 2))) * 10
+ // hip1.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip1.attributes.planeSize, 2) + Math.pow(hip1Height, 2)))
+
+ let hip2 = new QLine([currentRoof.x2, currentRoof.y2, wallMidX.toNumber(), wallMidY.toNumber()], {
parentId: roof.id,
fontSize: roof.fontSize,
stroke: '#1083E3',
@@ -2575,31 +3035,22 @@ const changeWallRoof = (currentRoof, canvas) => {
attributes: {
roofId: roof.id,
currentRoofId: currentRoof.id,
- actualSize: 0,
+ planeSize: calcLinePlaneSize({
+ x1: currentRoof.x2,
+ y1: currentRoof.y2,
+ x2: wallMidX.toNumber(),
+ y2: wallMidY.toNumber(),
+ }),
+ actualSize: calcLineActualSize(
+ { x1: currentRoof.x2, y1: currentRoof.y2, x2: wallMidX.toNumber(), y2: wallMidY.toNumber() },
+ Big(90 - nextDegree).toNumber(),
+ ),
},
})
- const hip1Base = ((Math.abs(hip1.x1 - hip1.x2) + Math.abs(hip1.y1 - hip1.y2)) / 2) * 10
- const hip1Height = Math.round(hip1Base / Math.tan(((90 - prevDegree) * Math.PI) / 180))
- hip1.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip1.x1 - hip1.x2, 2) + Math.pow(hip1.y1 - hip1.y2, 2))) * 10
- hip1.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip1.attributes.planeSize, 2) + Math.pow(hip1Height, 2)))
-
- let hip2 = new QLine([currentRoof.x2, currentRoof.y2, wallMidX, wallMidY], {
- parentId: roof.id,
- fontSize: roof.fontSize,
- stroke: '#1083E3',
- strokeWidth: 2,
- name: LINE_TYPE.SUBLINE.HIP,
- attributes: {
- roofId: roof.id,
- currentRoofId: currentRoof.id,
- planeSize: currentRoof.length,
- actualSize: currentRoof.length,
- },
- })
- const hip2Base = ((Math.abs(hip2.x1 - hip2.x2) + Math.abs(hip2.y1 - hip2.y2)) / 2) * 10
- const hip2Height = Math.round(hip2Base / Math.tan(((90 - nextDegree) * Math.PI) / 180))
- hip2.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip2.x1 - hip2.x2, 2) + Math.pow(hip2.y1 - hip2.y2, 2))) * 10
- hip2.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip2.attributes.planeSize, 2) + Math.pow(hip2Height, 2)))
+ // const hip2Base = ((Math.abs(hip2.x1 - hip2.x2) + Math.abs(hip2.y1 - hip2.y2)) / 2) * 10
+ // const hip2Height = Math.round(hip2Base / Math.tan(((90 - nextDegree) * Math.PI) / 180))
+ // hip2.attributes.planeSize = Math.round(Math.sqrt(Math.pow(hip2.x1 - hip2.x2, 2) + Math.pow(hip2.y1 - hip2.y2, 2))) * 10
+ // hip2.attributes.actualSize = Math.round(Math.sqrt(Math.pow(hip2.attributes.planeSize, 2) + Math.pow(hip2Height, 2)))
canvas?.add(hip1)
canvas?.add(hip2)
roof.innerLines.push(hip1)
@@ -2724,12 +3175,13 @@ const reDrawPolygon = (polygon, canvas) => {
line.attributes = l.attributes
}
})
- const lineLength = Math.sqrt(
- Math.pow(Math.round(Math.abs(line.x1 - line.x2) * 10), 2) + Math.pow(Math.round(Math.abs(line.y1 - line.y2) * 10), 2),
- )
+ // const lineLength = Math.sqrt(
+ // Math.pow(Math.round(Math.abs(line.x1 - line.x2) * 10), 2) + Math.pow(Math.round(Math.abs(line.y1 - line.y2) * 10), 2),
+ // )
+ const lineLength = calcLinePlaneSize({ x1: line.x1, y1: line.y1, x2: line.x2, y2: line.y2 })
if (line.attributes !== undefined) {
line.attributes.planeSize = lineLength
- line.attributes.actualSize = line
+ line.attributes.actualSize = lineLength
} else {
line.attributes = {
roofId: newPolygon.id,
@@ -2745,7 +3197,13 @@ const reDrawPolygon = (polygon, canvas) => {
return newPolygon
}
-const drawCenterLine = (roof, canvas) => {
+/**
+ * 지붕의 centerLine을 그린다.
+ * @param roof
+ * @param canvas
+ * @param textMode
+ */
+const drawCenterLine = (roof, canvas, textMode) => {
//현재 지붕의 centerLine을 다 지운다.
canvas
.getObjects()
@@ -2758,7 +3216,6 @@ const drawCenterLine = (roof, canvas) => {
const hips = roof.innerLines.filter(
(line) => (currentRoof.x1 === line.x1 && currentRoof.y1 === line.y1) || (currentRoof.x2 === line.x1 && currentRoof.y2 === line.y1),
)
- // console.log('hips : ', hips)
const ridge = roof.innerLines
.filter((line) => line.name === LINE_TYPE.SUBLINE.RIDGE)
@@ -2784,41 +3241,17 @@ const drawCenterLine = (roof, canvas) => {
}
return prevDistance < currentDistance ? prev : current
}, null)
- /*console.log('currentRoof : ', currentRoof.attributes.planeSize, currentRoof)
- console.log(
- roof.innerLines
- .filter((line) => line.name === LINE_TYPE.SUBLINE.RIDGE)
- .filter((line) => {
- if (currentRoof.x1 === currentRoof.x2) {
- console.log('currentRoof.x1 === currentRoof.x2', line.x1 === line.x2, line)
- if (line.x1 === line.x2) {
- return line
- }
- } else {
- console.log('currentRoof.x1 !== currentRoof.x2', line.y1 === line.y2, line)
- if (line.y1 === line.y2) {
- return line
- }
- }
- }),
- )
- console.log('currentRoof.x1 === currentRoof.x2 : ', currentRoof.x1 === currentRoof.x2)
- console.log('ridge : ', ridge)
- console.log('hips : ', hips)*/
let points = []
if (hips.length === 2 && Math.abs(hips[0].x2 - hips[1].x2) < 1 && Math.abs(hips[0].y2 - hips[1].y2) < 1) {
- // console.log('삼각')
const x1 = (currentRoof.x1 + currentRoof.x2) / 2
const y1 = (currentRoof.y1 + currentRoof.y2) / 2
points.push(x1, y1, hips[0].x2, hips[0].y2)
} else if (hips.length > 1) {
- // console.log('삼각 아님')
if (
((ridge?.x1 === hips[0].x2 && ridge?.y1 === hips[0].y2) || (ridge?.x2 === hips[0].x2 && ridge?.y2 === hips[0].y2)) &&
((ridge?.x1 === hips[1].x2 && ridge?.y1 === hips[1].y2) || (ridge?.x2 === hips[1].x2 && ridge?.y2 === hips[1].y2))
) {
//사각이면 마루와 현재 라인 사이에 길이를 구한다
- // console.log('사각')
if (Math.sign(currentRoof.x1 - currentRoof.x2) === 0) {
const yPoints = [currentRoof.y1, currentRoof.y2, ridge.y1, ridge.y2].sort((a, b) => a - b)
const x1 = (currentRoof.x1 + currentRoof.x2) / 2
@@ -2843,7 +3276,6 @@ const drawCenterLine = (roof, canvas) => {
}
}
} else {
- // console.log('사각 아님')
if (Math.sign(currentRoof.x1 - currentRoof.x2) === 0) {
let xPoints = []
xPoints.push(ridge?.x1, ridge?.x2)
@@ -2929,7 +3361,6 @@ const drawCenterLine = (roof, canvas) => {
}
}
} else {
- // console.log('else : ')
if (currentRoof.attributes.type === LINE_TYPE.WALLLINE.JERKINHEAD) {
const gables = canvas
.getObjects()
@@ -2966,6 +3397,7 @@ const drawCenterLine = (roof, canvas) => {
}
}
if (points !== null) {
+ const currentDegree = currentRoof.attributes.pitch > 0 ? getDegreeByChon(currentRoof.attributes.pitch) : currentRoof.attributes.degree
const pitchSizeLine = new QLine(points, {
parentId: roof.id,
stroke: '#000000',
@@ -2973,22 +3405,16 @@ const drawCenterLine = (roof, canvas) => {
strokeDashArray: [5, 5],
selectable: false,
fontSize: roof.fontSize,
+ textMode: textMode,
attributes: {
roofId: roof.id,
type: 'pitchSizeLine',
+ planeSize: calcLineActualSize({ x1: points[0], y1: points[1], x2: points[2], y2: points[3] }, currentDegree),
+ actualSize: calcLineActualSize({ x1: points[0], y1: points[1], x2: points[2], y2: points[3] }, currentDegree),
},
})
canvas.add(pitchSizeLine)
canvas.renderAll()
-
- const adjust = Math.sqrt(
- Math.pow(Math.round(Math.abs(pitchSizeLine.x1 - pitchSizeLine.x2) * 10), 2) +
- Math.pow(Math.round(Math.abs(pitchSizeLine.y1 - pitchSizeLine.y2) * 10), 2),
- )
- const currentDegree = currentRoof.attributes.pitch > 0 ? getDegreeByChon(currentRoof.attributes.pitch) : currentRoof.attributes.degree
- const height = Math.tan(currentDegree * (Math.PI / 180)) * adjust
- const lengthText = Math.round(Math.sqrt(Math.pow(adjust, 2) + Math.pow(height, 2)))
- pitchSizeLine.setLengthText(lengthText)
}
})
}
@@ -3084,3 +3510,26 @@ export const inPolygon = (polygonPoints, rectPoints) => {
return allPointsInsidePolygon && noPolygonPointsInsideRect
}
+
+/**
+ * 포인트를 기준으로 선의 길이를 구한다. 선의 길이는 10을 곱하여 사용한다.
+ * @param points {{x1, y1, x2, y2}}
+ */
+export const calcLinePlaneSize = (points) => {
+ const { x1, y1, x2, y2 } = points
+ return Big(x1).minus(x2).pow(2).plus(Big(y1).minus(y2).pow(2)).sqrt().abs().times(10).round().toNumber()
+}
+
+/**
+ * 포인트와 기울기를 기준으로 선의 길이를 구한다.
+ * @param points
+ * @param degree
+ * @returns number
+ */
+export const calcLineActualSize = (points, degree) => {
+ const { x1, y1, x2, y2 } = points
+ const planeSize = calcLinePlaneSize(points)
+ const height = Big(Math.tan(Big(degree).times(Math.PI / 180))).times(planeSize)
+ // Math.round(Math.sqrt(Math.pow(line.attributes.planeSize, 2) + Math.pow(height, 2)))
+ return Big(planeSize).pow(2).plus(height.pow(2)).sqrt().abs().round().toNumber()
+}