QPolygon containsPoint 계산 수정
This commit is contained in:
parent
849ba0e0d5
commit
7e0e4643e2
@ -387,7 +387,15 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
||||
this.canvas = canvas
|
||||
},
|
||||
fillCellABType(
|
||||
cell = { width: 50, height: 100, padding: 5, wallDirection: 'left', referenceDirection: 'none', startIndex: -1, isCellCenter: false },
|
||||
cell = {
|
||||
width: 50,
|
||||
height: 100,
|
||||
padding: 5,
|
||||
wallDirection: 'left',
|
||||
referenceDirection: 'none',
|
||||
startIndex: -1,
|
||||
isCellCenter: false,
|
||||
},
|
||||
) {
|
||||
const points = this.points
|
||||
|
||||
@ -689,6 +697,59 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
||||
|
||||
return intersects % 2 === 1
|
||||
},
|
||||
|
||||
inPolygonImproved(point) {
|
||||
const vertices = this.points
|
||||
let inside = false
|
||||
const testX = point.x
|
||||
const testY = point.y
|
||||
|
||||
for (let i = 0, j = vertices.length - 1; i < vertices.length; j = i++) {
|
||||
const xi = vertices[i].x
|
||||
const yi = vertices[i].y
|
||||
const xj = vertices[j].x
|
||||
const yj = vertices[j].y
|
||||
|
||||
// 점이 정점 위에 있는지 확인
|
||||
if (Math.abs(xi - testX) < 0.01 && Math.abs(yi - testY) < 0.01) {
|
||||
return true
|
||||
}
|
||||
|
||||
// 점이 선분 위에 있는지 확인
|
||||
if (this.isPointOnSegment(point, { x: xi, y: yi }, { x: xj, y: yj })) {
|
||||
return true
|
||||
}
|
||||
|
||||
// Ray casting 알고리즘
|
||||
if (((yi > testY) !== (yj > testY)) &&
|
||||
(testX < (xj - xi) * (testY - yi) / (yj - yi) + xi)) {
|
||||
inside = !inside
|
||||
}
|
||||
}
|
||||
|
||||
return inside
|
||||
},
|
||||
|
||||
isPointOnSegment(point, segStart, segEnd) {
|
||||
const tolerance = 0.1
|
||||
const dxSegment = segEnd.x - segStart.x
|
||||
const dySegment = segEnd.y - segStart.y
|
||||
const dxPoint = point.x - segStart.x
|
||||
const dyPoint = point.y - segStart.y
|
||||
|
||||
// 벡터의 외적을 계산하여 점이 선분 위에 있는지 확인
|
||||
const crossProduct = Math.abs(dxPoint * dySegment - dyPoint * dxSegment)
|
||||
|
||||
if (crossProduct > tolerance) {
|
||||
return false
|
||||
}
|
||||
|
||||
// 점이 선분의 범위 내에 있는지 확인
|
||||
const dotProduct = dxPoint * dxSegment + dyPoint * dySegment
|
||||
const squaredLength = dxSegment * dxSegment + dySegment * dySegment
|
||||
|
||||
return dotProduct >= 0 && dotProduct <= squaredLength
|
||||
},
|
||||
setCoords: function () {
|
||||
// 부모 클래스의 setCoords 호출
|
||||
this.callSuper('setCoords')
|
||||
@ -699,10 +760,10 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
||||
delete this.oCoords
|
||||
delete this.aCoords
|
||||
delete this.__corner
|
||||
|
||||
|
||||
// 다시 부모 setCoords 호출
|
||||
this.callSuper('setCoords')
|
||||
|
||||
|
||||
// 한 번 더 강제로 bounding rect 재계산
|
||||
this._clearCache && this._clearCache()
|
||||
}
|
||||
@ -711,7 +772,7 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
||||
containsPoint: function (point) {
|
||||
// 먼저 좌표 업데이트
|
||||
this.setCoords()
|
||||
|
||||
|
||||
// 캔버스 줌과 viewport transform 고려한 좌표 변환
|
||||
let localPoint = point
|
||||
if (this.canvas) {
|
||||
@ -722,13 +783,25 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
||||
localPoint = fabric.util.transformPoint(point, inverted)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 오브젝트의 transform matrix를 고려한 좌표 변환
|
||||
const matrix = this.calcTransformMatrix()
|
||||
const invertedMatrix = fabric.util.invertTransform(matrix)
|
||||
const transformedPoint = fabric.util.transformPoint(localPoint, invertedMatrix)
|
||||
|
||||
// pathOffset을 고려한 최종 좌표 계산
|
||||
const pathOffset = this.get('pathOffset')
|
||||
const finalPoint = {
|
||||
x: transformedPoint.x + pathOffset.x,
|
||||
y: transformedPoint.y + pathOffset.y,
|
||||
}
|
||||
|
||||
if (this.name === POLYGON_TYPE.ROOF && this.isFixed) {
|
||||
const isInside = this.inPolygon(localPoint)
|
||||
const isInside = this.inPolygonImproved(finalPoint)
|
||||
this.set('selectable', isInside)
|
||||
return isInside
|
||||
} else {
|
||||
return this.callSuper('containsPoint', localPoint)
|
||||
return this.inPolygonImproved(finalPoint)
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user