로직변경1
This commit is contained in:
parent
3663636b5d
commit
3cbfbbd0b3
@ -453,7 +453,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||
left: line.x1 + 5,
|
||||
top: line.y1 - 20,
|
||||
fontSize: 10,
|
||||
fill: 'green',
|
||||
fill: 'magenta',
|
||||
fontFamily: 'Arial',
|
||||
selectable: false,
|
||||
hasControls: false,
|
||||
@ -813,12 +813,12 @@ if((roof.moveUpDown??0 > 0) ) {
|
||||
|
||||
//현재 roof는 무조건 시계방향
|
||||
|
||||
const getAddLine = (p1, p2, stroke = '#1083E3') => {
|
||||
const getAddLine = (p1, p2, stroke = '') => {
|
||||
movedLines.push({ index, p1, p2 })
|
||||
|
||||
// Usage:
|
||||
let mergeLines = mergeMovedLines(movedLines);
|
||||
console.log("mergeLines:::::::", mergeLines);
|
||||
//console.log("mergeLines:::::::", mergeLines);
|
||||
const line = new QLine([p1.x, p1.y, p2.x, p2.y], {
|
||||
parentId : roof.id,
|
||||
fontSize : roof.fontSize,
|
||||
@ -855,6 +855,7 @@ if((roof.moveUpDown??0 > 0) ) {
|
||||
if (fullyMoved ) {
|
||||
//반시계방향향
|
||||
console.log("moveFully:::::::::::::", wallBaseLine, newPStart, newPEnd)
|
||||
console.log("moveFully:::::::::::::", roofLine.direction)
|
||||
const mLine = getSelectLinePosition(wall, wallBaseLine)
|
||||
|
||||
if (getOrientation(roofLine) === 'vertical') {
|
||||
@ -864,26 +865,68 @@ if((roof.moveUpDown??0 > 0) ) {
|
||||
(mLine.position === 'right' && wallLine.x1 > wallBaseLine.x1)
|
||||
? 'in' : 'out';
|
||||
const condition = `${mLine.position}_${positionType}`;
|
||||
|
||||
let isStartEnd = findInteriorPoint(wallBaseLine, sortedWallBaseLines)
|
||||
let sPoint, ePoint;
|
||||
switch (condition) {
|
||||
case 'left_in':
|
||||
isIn = true
|
||||
newPEnd.y = wallBaseLine.y2;
|
||||
getAddLine({ x: newPEnd.x, y: wallBaseLine.y2 }, { x: wallBaseLine.x2, y: wallBaseLine.y2 })
|
||||
findPoints.push({ x: wallBaseLine.x2, y: wallBaseLine.y2 });
|
||||
break;
|
||||
|
||||
|
||||
if (isStartEnd.start ) {
|
||||
const moveDist = Big(wallBaseLine.x1).minus(wallLine.x1).abs().toNumber()
|
||||
sPoint = {x: wallBaseLine.x1, y: wallBaseLine.y1};
|
||||
newPEnd.y = wallBaseLine.y2;
|
||||
newPStart.x = wallBaseLine.x2
|
||||
getAddLine({ x: newPEnd.x, y: newPEnd.y }, { x: sPoint.x, y: sPoint.y }, 'blue')
|
||||
findPoints.push({ x: sPoint.x, y: sPoint.y });
|
||||
const newPointX = Big(roofLine.x1).plus(moveDist).toNumber()
|
||||
getAddLine({ x: roofLine.x1, y: roofLine.y1 }, { x: newPointX, y: roofLine.y1 }, 'orange')
|
||||
|
||||
}else if(isStartEnd.end) {
|
||||
newPStart.y = roofLine.y1;
|
||||
newPStart.x = roofLine.x1;
|
||||
|
||||
const moveDist = Big(wallBaseLine.x2).minus(wallLine.x2).abs().toNumber()
|
||||
ePoint = {x: wallBaseLine.x2, y: wallBaseLine.y2};
|
||||
newPEnd.y = wallBaseLine.y2
|
||||
|
||||
findPoints.push({ x: ePoint.x, y: ePoint.y });
|
||||
const newPointX = Big(roofLine.x1).plus(moveDist).toNumber()
|
||||
|
||||
|
||||
const pDist = Big(wallLine.x1).minus(roofLine.x1).abs().toNumber()
|
||||
const pLineY = Big(roofLine.y2).minus(0).abs().toNumber()
|
||||
|
||||
getAddLine({ x: newPEnd.x, y: newPEnd.y }, { x: ePoint.x, y: ePoint.y }, 'blue')
|
||||
getAddLine({ x: roofLine.x1, y: roofLine.y1 }, { x: newPointX, y: roofLine.y1 }, 'orange')
|
||||
if(Math.abs(wallBaseLine.y2 - wallLine.y2) < 0.1) {
|
||||
getAddLine({ x: roofLine.x1, y: pLineY }, { x: newPointX, y: pLineY }, 'green')
|
||||
getAddLine({ x: newPointX, y: pLineY }, { x: ePoint.x, y: ePoint.y }, 'pink')
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
case 'left_out':
|
||||
const moveX = Math.abs(wallBaseLine.x1 - wallLine.x1)
|
||||
const aStartY = Math.abs(newPEnd.y + moveX)
|
||||
const bStartY = Math.abs(wallLine.y2 + moveX)
|
||||
findPoints.push({ x: newPEnd.x, y: aStartY });
|
||||
const inLine = findLineContainingPoint(innerLines, { x: newPEnd.x, y: aStartY })
|
||||
// console.log("startLines:::::::", inLine);
|
||||
getAddLine({ x: wallLine.x1, y: roofLine.y2 }, { x: wallLine.x1, y: bStartY })
|
||||
getAddLine({ x: wallLine.x2, y: bStartY }, { x: inLine.x2, y: inLine.y2 }, 'pink')
|
||||
const eLineY = Math.abs(bStartY - wallLine.y2)
|
||||
newPStart.y += eLineY
|
||||
newPEnd.y = aStartY
|
||||
if(isStartEnd.start){
|
||||
const moveX = Math.abs(wallBaseLine.x1 - wallLine.x1)
|
||||
const aStartY = Math.abs(newPEnd.y + moveX)
|
||||
const bStartY = Math.abs(wallLine.y2 + moveX)
|
||||
findPoints.push({ x: newPEnd.x, y: aStartY });
|
||||
const inLine = findLineContainingPoint(innerLines, { x: newPEnd.x, y: aStartY })
|
||||
// console.log("startLines:::::::", inLine);
|
||||
getAddLine({ x: wallLine.x1, y: roofLine.y2 }, { x: wallLine.x1, y: bStartY })
|
||||
getAddLine({ x: wallLine.x2, y: bStartY }, { x: inLine.x2, y: inLine.y2 }, 'pink')
|
||||
const eLineY = Math.abs(bStartY - wallLine.y2)
|
||||
newPStart.y += eLineY
|
||||
newPEnd.y = aStartY
|
||||
|
||||
}else if(isStartEnd.end){
|
||||
|
||||
}
|
||||
break;
|
||||
case 'right_in':
|
||||
newPEnd.y = wallBaseLine.y2;
|
||||
@ -972,17 +1015,34 @@ if((roof.moveUpDown??0 > 0) ) {
|
||||
const condition = `${mLine.position}_${positionType}`;
|
||||
let isStartEnd = findInteriorPoint(wallBaseLine, sortedWallBaseLines)
|
||||
|
||||
let sPoint, ePoint;
|
||||
|
||||
switch (condition) {
|
||||
case 'top_in':
|
||||
|
||||
console.log("findInteriorPoint result:::::::", isStartEnd);
|
||||
|
||||
let sPoint, ePoint;
|
||||
|
||||
if (isStartEnd.start ) {
|
||||
const moveDist = Big(wallLine.y1).minus(wallBaseLine.y1).abs().toNumber()
|
||||
sPoint = {x: wallBaseLine.x1, y: wallBaseLine.y1};
|
||||
newPStart.x = wallBaseLine.x1;
|
||||
getAddLine({ x: newPStart.x, y: newPStart.y }, { x: sPoint.x, y: sPoint.y })
|
||||
|
||||
|
||||
const newPointY = Big(roofLine.y2).plus(moveDist).toNumber()
|
||||
|
||||
const pDist = Big(wallLine.y2).minus(roofLine.y2).abs().toNumber()
|
||||
const pLineX = Big(roofLine.x1).minus(0).abs().toNumber()
|
||||
getAddLine({ x: newPStart.x, y: newPStart.y }, { x: sPoint.x, y: sPoint.y }, 'blue')
|
||||
findPoints.push({ x: sPoint.x, y: sPoint.y });
|
||||
|
||||
if(Math.abs(wallBaseLine.x1 - wallLine.x1) < 0.1) {
|
||||
getAddLine({ x: pLineX, y: roofLine.y2 }, { x: pLineX, y: newPointY }, 'green')
|
||||
getAddLine({ x: pLineX, y: newPointY }, { x: sPoint.x, y: sPoint.y }, 'pink')
|
||||
}
|
||||
|
||||
|
||||
//getAddLine({ x: roofLine.x2, y: roofLine.y2 }, { x: roofLine.x2, y: newPointY }, 'orange')
|
||||
}
|
||||
|
||||
if(isStartEnd.end){
|
||||
@ -994,7 +1054,6 @@ if((roof.moveUpDown??0 > 0) ) {
|
||||
|
||||
break;
|
||||
case 'top_out':
|
||||
|
||||
console.log("findInteriorPoint result:::::::", isStartEnd);
|
||||
|
||||
const moveY = Math.abs(wallLine.y1 - wallBaseLine.y1)
|
||||
@ -1015,9 +1074,46 @@ if((roof.moveUpDown??0 > 0) ) {
|
||||
break;
|
||||
case 'bottom_in':
|
||||
|
||||
if (isStartEnd.start ) {
|
||||
const moveDist = Big(wallLine.y1).minus(wallBaseLine.y1).abs().toNumber()
|
||||
sPoint = {x: wallBaseLine.x1, y: wallBaseLine.y1};
|
||||
newPStart.x = wallBaseLine.x1;
|
||||
getAddLine({ x: newPStart.x, y: newPStart.y }, { x: sPoint.x, y: sPoint.y })
|
||||
findPoints.push({ x: sPoint.x, y: sPoint.y });
|
||||
const newPointY = Big(roofLine.y2).minus(moveDist).abs().toNumber()
|
||||
//getAddLine({ x: roofLine.x2, y: roofLine.y2 }, { x: roofLine.x2, y: newPointY }, 'orange')
|
||||
}
|
||||
|
||||
if(isStartEnd.end){
|
||||
const moveDist = Big(wallLine.y2).minus(wallBaseLine.y2).abs().toNumber()
|
||||
sPoint = {x: wallBaseLine.x1, y: wallBaseLine.y1};
|
||||
newPStart.x = wallBaseLine.x1;
|
||||
getAddLine({ x: newPStart.x, y: newPStart.y }, { x: sPoint.x, y: sPoint.y })
|
||||
findPoints.push({ x: sPoint.x, y: sPoint.y });
|
||||
const newPointY = Big(roofLine.y1).minus(moveDist).abs().toNumber()
|
||||
//getAddLine({ x: roofLine.x1, y: roofLine.y1 }, { x: roofLine.x1, y: newPointY }, 'orange')
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
case 'bottom_out':
|
||||
|
||||
// console.log("findInteriorPoint result:::::::", isStartEnd);
|
||||
//
|
||||
// const moveY = Math.abs(wallLine.y1 - wallBaseLine.y1)
|
||||
// const dist = Math.abs(roofLine.y1 - wallLine.y1)
|
||||
// const aStartX = Math.abs(newPStart.x + moveY)
|
||||
// const bStartX = Math.abs(wallLine.x1 + moveY)
|
||||
//
|
||||
// //newPStart.x += moveX
|
||||
// //wallLine.x1 += moveX
|
||||
// findPoints.push({ x: aStartX, y: newPEnd.y });
|
||||
// const inLine = findLineContainingPoint(innerLines, { x: aStartX, y: newPEnd.y })
|
||||
// console.log("startLines:::::::", inLine);
|
||||
// getAddLine({ x: bStartX, y: wallLine.y1 }, { x: roofLine.x1, y: wallLine.y1 })
|
||||
// getAddLine({ x: bStartX, y: wallLine.y2 }, { x: inLine.x2, y: inLine.y2 }, 'pink')
|
||||
// const eLineX = Math.abs(bStartX - wallLine.x1)
|
||||
// newPEnd.x += eLineX
|
||||
// newPStart.x = aStartX
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1095,72 +1191,115 @@ if((roof.moveUpDown??0 > 0) ) {
|
||||
}
|
||||
|
||||
getAddLine(newPStart, newPEnd, 'red')
|
||||
}
|
||||
/*
|
||||
} else if (movedStart ) { //end 변경경
|
||||
|
||||
} /* else if (movedStart ) { //end 변경경
|
||||
|
||||
|
||||
if (getOrientation(roofLine) === 'vertical') { //green 수직
|
||||
|
||||
if (getOrientation(roofLine) === 'vertical') { //brown 수직
|
||||
const mLine = getSelectLinePosition(wall, wallBaseLine)
|
||||
if (['left', 'right'].includes(mLine.position)) {
|
||||
const positionType =
|
||||
(mLine.position === 'left' && wallLine.x1 <= wallBaseLine.x1) ||
|
||||
(mLine.position === 'right' && wallLine.x1 >= wallBaseLine.x1)
|
||||
? 'in' : 'out';
|
||||
|
||||
const condition = `${mLine.position}_${positionType}`;
|
||||
let isStartEnd = findInteriorPoint(wallBaseLine, sortedWallBaseLines)
|
||||
let sPoint, ePoint;
|
||||
let isCross = false
|
||||
if (Math.abs(currentRoofLine?.x2 - roofLine.x1) < 0.1 || Math.abs(currentRoofLine?.x1 - roofLine.x2) < 0.1) {
|
||||
isCross = true;
|
||||
}
|
||||
|
||||
|
||||
switch (condition) {
|
||||
case 'left_in':
|
||||
|
||||
if(isStartEnd.start){
|
||||
|
||||
}else if(isStartEnd.end){
|
||||
newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y1 : wallBaseLine.y1 }
|
||||
newPEnd ={ x: roofLine.x2, y: roofLine.y2 }
|
||||
}else {
|
||||
newPStart = { x: roofLine.x1, y: roofLine.y1 }
|
||||
newPEnd = { x: roofLine.x2, y: (isCross) ? currentRoofLine?.y1 : wallBaseLine.y1 }
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 'left_out':
|
||||
|
||||
break;
|
||||
case 'right_in':
|
||||
newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine?.y1 : wallBaseLine.y1 }
|
||||
newPEnd ={ x: roofLine.x2, y: roofLine.y2 }
|
||||
//대각선 라인을 보조라인으로 그린다.
|
||||
if(isCross){
|
||||
getAddLine({ x: wallBaseLine.x1, y: wallBaseLine.y1 }, { x: roofLine.x1, y: currentRoofLine?.y1 }, 'purple')
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
case 'right_out':
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(mLine.position === 'left') isIn = true
|
||||
if(mLine.position === 'right') isOut = true
|
||||
|
||||
let isCross = false
|
||||
if (Math.abs(currentRoofLine?.x2 - roofLine.x1) < 0.1 || Math.abs(currentRoofLine?.x1 - roofLine.x2) < 0.1) {
|
||||
isCross = true;
|
||||
}
|
||||
|
||||
if(newPStart.y <= wallBaseLine.y1 && wallBaseLine.y1 < wallBaseLine.y2 && wallBaseLine.y2 < newPEnd.y){//in bottom left
|
||||
if(isIn){
|
||||
newPStart = { x: roofLine.x1, y: roofLine.y1 }
|
||||
newPEnd = { x: roofLine.x2, y: (isCross) ? currentRoofLine?.y1 : wallBaseLine.y1 }
|
||||
}
|
||||
// if(isIn){
|
||||
// newPStart = { x: roofLine.x1, y: roofLine.y1 }
|
||||
// newPEnd = { x: roofLine.x2, y: (isCross) ? currentRoofLine?.y1 : wallBaseLine.y1 }
|
||||
// }
|
||||
|
||||
|
||||
}else if(newPEnd.y <= wallBaseLine.y2 && wallBaseLine.y2 < wallBaseLine.y1 && wallBaseLine.y1 <= newPStart.y){ //하단 오른쪽v
|
||||
newPStart = { x: roofLine.x1, y: roofLine.y1 }
|
||||
newPEnd = { x: roofLine.x2, y: (isCross) ? currentRoofLine?.y1 : wallBaseLine.y1 }
|
||||
// newPStart = { x: roofLine.x1, y: roofLine.y1 }
|
||||
// newPEnd = { x: roofLine.x2, y: (isCross) ? currentRoofLine?.y1 : wallBaseLine.y1 }
|
||||
|
||||
}else if(newPEnd.y <= wallBaseLine.y2 && wallBaseLine.y2 <= newPStart.y && newPStart.y <= wallBaseLine.y1) { //top right
|
||||
|
||||
newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine?.y1 : wallBaseLine.y1 }
|
||||
newPEnd ={ x: roofLine.x2, y: roofLine.y2 }
|
||||
|
||||
//대각선 라인을 보조라인으로 그린다.
|
||||
if(isCross){
|
||||
getAddLine({ x: wallBaseLine.x1, y: wallBaseLine.y1 }, { x: roofLine.x1, y: currentRoofLine?.y1 }, 'yellow')
|
||||
}
|
||||
// newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine?.y1 : wallBaseLine.y1 }
|
||||
// newPEnd ={ x: roofLine.x2, y: roofLine.y2 }
|
||||
//
|
||||
// //대각선 라인을 보조라인으로 그린다.
|
||||
// if(isCross){
|
||||
// getAddLine({ x: wallBaseLine.x1, y: wallBaseLine.y1 }, { x: roofLine.x1, y: currentRoofLine?.y1 }, 'purple')
|
||||
// }
|
||||
|
||||
}else if(newPStart.y <= wallBaseLine.y1 && wallBaseLine.y1 <= newPEnd.y && newPEnd.y <= wallBaseLine.y2) {//상단 오르쪽
|
||||
|
||||
newPStart = { x: roofLine.x1, y: roofLine.y1 }
|
||||
newPEnd = { x: roofLine.x2, y: (isCross) ? currentRoofLine.y1 : wallBaseLine.y1 }
|
||||
// newPStart = { x: roofLine.x1, y: roofLine.y1 }
|
||||
// newPEnd = { x: roofLine.x2, y: (isCross) ? currentRoofLine.y1 : wallBaseLine.y1 }
|
||||
|
||||
}else if(wallBaseLine.y1 <= newPStart.y && newPStart.y <= wallBaseLine.y2 && wallBaseLine.y2 <= newPEnd.y) { // out bottom left //bottom left
|
||||
if(isIn){
|
||||
newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y1 : wallBaseLine.y1 }
|
||||
newPEnd = { x: roofLine.x2, y: roofLine.y2 }
|
||||
|
||||
//대각선 라인을 보조라인으로 그린다.
|
||||
if(isCross){
|
||||
getAddLine( { x: wallBaseLine.x1, y: wallBaseLine.y1 }, { x: roofLine.x1, y: currentRoofLine.y1 }, 'yellow')
|
||||
}
|
||||
}else if(isOut){
|
||||
|
||||
}
|
||||
// if(isIn){
|
||||
// newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y1 : wallBaseLine.y1 }
|
||||
// newPEnd = { x: roofLine.x2, y: roofLine.y2 }
|
||||
//
|
||||
// //대각선 라인을 보조라인으로 그린다.
|
||||
// if(isCross){
|
||||
// getAddLine( { x: wallBaseLine.x1, y: wallBaseLine.y1 }, { x: roofLine.x1, y: currentRoofLine.y1 }, 'purple')
|
||||
// }
|
||||
// }else if(isOut){
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
|
||||
}else if (wallBaseLine.y2 <= newPEnd.y && newPEnd.y <= wallBaseLine.y1 && wallBaseLine.y1 <= newPStart.y) { //하단 왼쪽
|
||||
|
||||
newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y1 : wallBaseLine.y1 }
|
||||
newPEnd ={ x: roofLine.x2, y: roofLine.y2 }
|
||||
// newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y1 : wallBaseLine.y1 }
|
||||
// newPEnd ={ x: roofLine.x2, y: roofLine.y2 }
|
||||
}
|
||||
|
||||
|
||||
|
||||
} else if (getOrientation(roofLine) === 'horizontal') { //green 수평
|
||||
} else if (getOrientation(roofLine) === 'horizontal') { //magenta 수평
|
||||
|
||||
|
||||
const mLine = getSelectLinePosition(wall, wallBaseLine)
|
||||
@ -1193,7 +1332,7 @@ if((roof.moveUpDown??0 > 0) ) {
|
||||
|
||||
//대각선 라인을 보조라인으로 그린다.
|
||||
if(isCross){
|
||||
getAddLine({ x: currentRoofLine.x1, y: roofLine.y1 }, { x: wallBaseLine.x1, y: wallBaseLine.y1 }, 'yellow')
|
||||
getAddLine({ x: currentRoofLine.x1, y: roofLine.y1 }, { x: wallBaseLine.x1, y: wallBaseLine.y1 }, 'purple')
|
||||
}
|
||||
}else if(isOut){
|
||||
|
||||
@ -1213,7 +1352,7 @@ if((roof.moveUpDown??0 > 0) ) {
|
||||
|
||||
//대각선 라인을 보조라인으로 그린다.
|
||||
if(isCross){
|
||||
getAddLine({ x: wallBaseLine.x1, y: wallBaseLine.y1 },{ x: currentRoofLine.x1, y: roofLine.y1 }, 'yellow')
|
||||
getAddLine({ x: wallBaseLine.x1, y: wallBaseLine.y1 },{ x: currentRoofLine.x1, y: roofLine.y1 }, 'purple')
|
||||
}
|
||||
|
||||
}else if (wallBaseLine.x2 <= newPEnd.x && newPEnd.x <= wallBaseLine.x1 && wallBaseLine.x1 <= newPStart.x) { //right / top
|
||||
@ -1229,7 +1368,7 @@ if((roof.moveUpDown??0 > 0) ) {
|
||||
//newPEnd = { x: (isCross) ? currentRoofLine.x1 : origin.x1, y: roofLine.y1 } //수직라인 접점까지지
|
||||
}
|
||||
|
||||
getAddLine(newPStart, newPEnd, 'green')
|
||||
getAddLine(newPStart, newPEnd, 'magenta')
|
||||
//movedLines.push({ index, newPStart, newPEnd })
|
||||
//console.log("moveStart:::::::::::::", origin, newPStart, newPEnd)
|
||||
|
||||
@ -1239,68 +1378,115 @@ if((roof.moveUpDown??0 > 0) ) {
|
||||
|
||||
|
||||
if (getOrientation(roofLine) === 'vertical') { //수직 오렌지
|
||||
const mLine = getSelectLinePosition(wall, wallBaseLine)
|
||||
if(mLine.position === 'left') isIn = true
|
||||
if(mLine.position === 'right') isOut = true
|
||||
|
||||
let isCross = false
|
||||
if (Math.abs(currentRoofLine.x2 - roofLine.x1) < 0.1 || Math.abs(currentRoofLine.x1 - roofLine.x2) < 0.1) {
|
||||
isCross = true;
|
||||
const mLine = getSelectLinePosition(wall, wallBaseLine)
|
||||
if (['left', 'right'].includes(mLine.position)) {
|
||||
const positionType =
|
||||
(mLine.position === 'left' && wallLine.x1 <= wallBaseLine.x1) ||
|
||||
(mLine.position === 'right' && wallLine.x1 >= wallBaseLine.x1)
|
||||
? 'in' : 'out';
|
||||
|
||||
const condition = `${mLine.position}_${positionType}`;
|
||||
let isStartEnd = findInteriorPoint(wallBaseLine, sortedWallBaseLines)
|
||||
let sPoint, ePoint;
|
||||
let isCross = false
|
||||
if (Math.abs(currentRoofLine.x2 - roofLine.x1) < 0.1 || Math.abs(currentRoofLine.x1 - roofLine.x2) < 0.1) {
|
||||
isCross = true;
|
||||
}
|
||||
|
||||
switch (condition) {
|
||||
case 'left_in':
|
||||
|
||||
|
||||
newPStart = { x: roofLine.x1, y: roofLine.y1 }
|
||||
|
||||
newPEnd = { x: roofLine.x2, y: (isCross) ? currentRoofLine.y2 : wallBaseLine.y2 }
|
||||
|
||||
//대각선 라인을 보조라인으로 그린다.
|
||||
if (isCross) {
|
||||
getAddLine({ x: roofLine.x2, y: currentRoofLine.y2 }, {
|
||||
x: wallBaseLine.x2,
|
||||
y: wallBaseLine.y2
|
||||
}, 'purple')
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case 'left_out':
|
||||
|
||||
break;
|
||||
case 'right_in':
|
||||
newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y2 : wallBaseLine.y2 }
|
||||
newPEnd = { x: roofLine.x2, y: roofLine.y2 }
|
||||
|
||||
break;
|
||||
case 'right_out':
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// const mLine = getSelectLinePosition(wall, wallBaseLine)
|
||||
// if(mLine.position === 'left') isIn = true
|
||||
// if(mLine.position === 'right') isOut = true
|
||||
|
||||
|
||||
|
||||
if(newPStart.y <= wallBaseLine.y1 && wallBaseLine.y1 < wallBaseLine.y2 && wallBaseLine.y2 < newPEnd.y){//out top left
|
||||
|
||||
if(isIn) {
|
||||
newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y2 : wallBaseLine.y2 }
|
||||
newPEnd = { x: roofLine.x2, y: roofLine.y2 }
|
||||
}else if(isOut) {
|
||||
|
||||
newPStart = { x: roofLine.x1, y: roofLine.y1 }
|
||||
newPEnd = { x: roofLine.x2, y: wallLine.y2 }
|
||||
|
||||
}
|
||||
// if(isIn) {
|
||||
// newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y2 : wallBaseLine.y2 }
|
||||
// newPEnd = { x: roofLine.x2, y: roofLine.y2 }
|
||||
// }else if(isOut) {
|
||||
//
|
||||
// newPStart = { x: roofLine.x1, y: roofLine.y1 }
|
||||
// newPEnd = { x: roofLine.x2, y: wallLine.y2 }
|
||||
//
|
||||
// }
|
||||
|
||||
|
||||
}else if(newPEnd.y <= wallBaseLine.y2 && wallBaseLine.y2 < wallBaseLine.y1 && wallBaseLine.y1 <= newPStart.y){ //top /right
|
||||
newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y2 : wallBaseLine.y2 }
|
||||
newPEnd = { x: roofLine.x2, y: roofLine.y2 }
|
||||
// newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y2 : wallBaseLine.y2 }
|
||||
// newPEnd = { x: roofLine.x2, y: roofLine.y2 }
|
||||
|
||||
|
||||
}else if(newPEnd.y <= wallBaseLine.y2 && wallBaseLine.y2 <= newPStart.y && newPStart.y <= wallBaseLine.y1) { //top / left
|
||||
|
||||
newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y2 : wallBaseLine.y2 }
|
||||
newPEnd ={ x: roofLine.x2, y: roofLine.y2 }
|
||||
// newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y2 : wallBaseLine.y2 }
|
||||
// newPEnd ={ x: roofLine.x2, y: roofLine.y2 }
|
||||
|
||||
}else if(newPStart.y <= wallBaseLine.y1 && wallBaseLine.y1 <= newPEnd.y && newPEnd.y <= wallBaseLine.y2) {//in top left/
|
||||
|
||||
|
||||
if(isIn) {
|
||||
newPStart = { x: roofLine.x1, y: roofLine.y1 }
|
||||
newPEnd = { x: roofLine.x2, y: (isCross) ? currentRoofLine.y2 : wallBaseLine.y2 }
|
||||
|
||||
//대각선 라인을 보조라인으로 그린다.
|
||||
if (isCross) {
|
||||
getAddLine({ x: roofLine.x2, y: currentRoofLine.y2 }, {
|
||||
x: wallBaseLine.x2,
|
||||
y: wallBaseLine.y2
|
||||
}, 'yellow')
|
||||
}
|
||||
}
|
||||
// if(isIn) {
|
||||
// newPStart = { x: roofLine.x1, y: roofLine.y1 }
|
||||
// newPEnd = { x: roofLine.x2, y: (isCross) ? currentRoofLine.y2 : wallBaseLine.y2 }
|
||||
//
|
||||
// //대각선 라인을 보조라인으로 그린다.
|
||||
// if (isCross) {
|
||||
// getAddLine({ x: roofLine.x2, y: currentRoofLine.y2 }, {
|
||||
// x: wallBaseLine.x2,
|
||||
// y: wallBaseLine.y2
|
||||
// }, 'purple')
|
||||
// }
|
||||
// }
|
||||
|
||||
}else if(wallBaseLine.y1 <= newPStart.y && newPStart.y <= wallBaseLine.y2 && wallBaseLine.y2 <= newPEnd.y) { //하단 오른쪽v
|
||||
|
||||
newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y1 : wallBaseLine.y1 }
|
||||
newPEnd = { x: roofLine.x2, y: roofLine.y2 }
|
||||
// newPStart = { x: roofLine.x1, y: (isCross) ? currentRoofLine.y1 : wallBaseLine.y1 }
|
||||
// newPEnd = { x: roofLine.x2, y: roofLine.y2 }
|
||||
|
||||
}else if (wallBaseLine.y2 <= newPEnd.y && newPEnd.y <= wallBaseLine.y1 && wallBaseLine.y1 <= newPStart.y) { //bottom right
|
||||
|
||||
newPStart = { x: roofLine.x1, y: roofLine.y1 }
|
||||
newPEnd = { x: roofLine.x2, y: (isCross) ? currentRoofLine.y2 : wallBaseLine.y2 }
|
||||
|
||||
//대각선 라인을 보조라인으로 그린다.
|
||||
if(isCross){
|
||||
getAddLine({ x: roofLine.x2, y: currentRoofLine.y2 }, { x: wallBaseLine.x2, y: wallBaseLine.y2 }, 'yellow')
|
||||
}
|
||||
// newPStart = { x: roofLine.x1, y: roofLine.y1 }
|
||||
// newPEnd = { x: roofLine.x2, y: (isCross) ? currentRoofLine.y2 : wallBaseLine.y2 }
|
||||
//
|
||||
// //대각선 라인을 보조라인으로 그린다.
|
||||
// if(isCross){
|
||||
// getAddLine({ x: roofLine.x2, y: currentRoofLine.y2 }, { x: wallBaseLine.x2, y: wallBaseLine.y2 }, 'purple')
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
@ -1340,7 +1526,7 @@ if((roof.moveUpDown??0 > 0) ) {
|
||||
|
||||
//대각선 라인을 보조라인으로 그린다.
|
||||
if(isCross){
|
||||
getAddLine({ x: currentRoofLine.x2, y: roofLine.y2 }, { x:wallBaseLine.x2 , y: wallBaseLine.y2 }, 'yellow')
|
||||
getAddLine({ x: currentRoofLine.x2, y: roofLine.y2 }, { x:wallBaseLine.x2 , y: wallBaseLine.y2 }, 'purple')
|
||||
}
|
||||
|
||||
|
||||
@ -1356,7 +1542,7 @@ if((roof.moveUpDown??0 > 0) ) {
|
||||
newPEnd = { y: roofLine.y2, x: (isCross) ? currentRoofLine.x2 : wallBaseLine.x2 }
|
||||
//대각선 라인을 보조라인으로 그린다.
|
||||
if(isCross){
|
||||
getAddLine({ x: currentRoofLine.x2, y: roofLine.y2 }, { x:wallBaseLine.x2 , y: wallBaseLine.y2 }, 'yellow')
|
||||
getAddLine({ x: currentRoofLine.x2, y: roofLine.y2 }, { x:wallBaseLine.x2 , y: wallBaseLine.y2 }, 'purple')
|
||||
}
|
||||
}else if(isOut){
|
||||
// newPEnd = { x: roofLine.x2, y: roofLine.y2 }
|
||||
@ -4256,42 +4442,99 @@ function PointBasedOnBaseLength(x1, y1, x2, y2) {
|
||||
* @param {Array} polygonLines - 폴리곤을 구성하는 선분들의 배열
|
||||
* @returns {Object} - { start: boolean, end: boolean } 시작점과 끝점의 내부 여부
|
||||
*/
|
||||
function findInteriorPoint(line, polygonLines) {
|
||||
const { x1, y1, x2, y2 } = line;
|
||||
// function findInteriorPoint(line, polygonLines) {
|
||||
// const { x1, y1, x2, y2 } = line;
|
||||
//
|
||||
// // 선분의 방향 벡터
|
||||
// const dx = x2 - x1;
|
||||
// const dy = y2 - y1;
|
||||
//
|
||||
// // 수직 벡터 (왼쪽으로 90도 회전)
|
||||
// const perpX = -dy;
|
||||
// const perpY = dx;
|
||||
//
|
||||
// // 정규화
|
||||
// const length = Math.sqrt(perpX * perpX + perpY * perpY);
|
||||
// const nx = perpX / length;
|
||||
// const ny = perpY / length;
|
||||
//
|
||||
// // 오프셋 계산 (선분 길이의 1% 또는 최소 0.1)
|
||||
// const lineLength = Math.sqrt(dx*dx + dy*dy);
|
||||
// const offset = Math.max(0.1, lineLength * 0.01);
|
||||
//
|
||||
// // 시작점에서 수직 방향으로 약간 떨어진 점
|
||||
// const testPoint = {
|
||||
// x: x1 + nx * offset,
|
||||
// y: y1 + ny * offset
|
||||
// };
|
||||
//
|
||||
// // 반대 방향 점 추가 확인 (라인이 중앙에 있는 경우를 위해)
|
||||
// const testPoint2 = {
|
||||
// x: x1 - nx * offset,
|
||||
// y: y1 - ny * offset
|
||||
// };
|
||||
//
|
||||
// // 이 점이 폴리곤 내부에 있는지 확인
|
||||
// const isInside = isPointInPolygon(testPoint, polygonLines);
|
||||
// const isInside2 = isPointInPolygon(testPoint2, polygonLines);
|
||||
//
|
||||
// // 라인이 폴리곤 내부에 완전히 포함된 경우 (중앙) -> 양쪽 다 true
|
||||
// if (isInside && isInside2) {
|
||||
// return {
|
||||
// start: true,
|
||||
// end: true
|
||||
// };
|
||||
// }
|
||||
//
|
||||
// // 시작점이 내부를 향하는지 여부
|
||||
// return {
|
||||
// start: isInside,
|
||||
// // 끝점 방향은 시작점과 반대
|
||||
// end: !isInside
|
||||
// };
|
||||
// }
|
||||
|
||||
// 선분의 방향 벡터
|
||||
const dx = x2 - x1;
|
||||
const dy = y2 - y1;
|
||||
|
||||
// 수직 벡터 (왼쪽으로 90도 회전)
|
||||
const perpX = -dy;
|
||||
const perpY = dx;
|
||||
|
||||
// 정규화
|
||||
const length = Math.sqrt(perpX * perpX + perpY * perpY);
|
||||
const nx = perpX / length;
|
||||
const ny = perpY / length;
|
||||
|
||||
// 오프셋 계산 (선분 길이의 1% 또는 최소 0.1)
|
||||
const lineLength = Math.sqrt(dx*dx + dy*dy);
|
||||
const offset = Math.max(0.1, lineLength * 0.01);
|
||||
|
||||
// 시작점에서 수직 방향으로 약간 떨어진 점
|
||||
const testPoint = {
|
||||
x: x1 + nx * offset,
|
||||
y: y1 + ny * offset
|
||||
/**
|
||||
* 레이저(Ray)가 폴리곤의 다른 선분과 교차하는지 확인하는 헬퍼 함수
|
||||
* @param {Object} origin - 레이저 시작점 {x, y}
|
||||
* @param {Object} dir - 레이저 방향 벡터 {x, y} (정규화됨)
|
||||
* @param {Array} lines - 검사할 선분들
|
||||
* @param {Object} excludeLine - 자기 자신 라인 (제외)
|
||||
*/
|
||||
function checkRayIntersection(origin, dir, lines, excludeLine) {
|
||||
// 레이저를 아주 멀리까지 쏘아봅니다 (도면 크기에 따라 조절, 충분히 큰 값)
|
||||
const rayLength = 100000;
|
||||
const rayEnd = {
|
||||
x: origin.x + dir.x * rayLength,
|
||||
y: origin.y + dir.y * rayLength
|
||||
};
|
||||
|
||||
// 이 점이 폴리곤 내부에 있는지 확인
|
||||
const isInside = isPointInPolygon(testPoint, polygonLines);
|
||||
for (const line of lines) {
|
||||
// 자기 자신은 검사 제외
|
||||
if (line === excludeLine) continue;
|
||||
// 좌표 기반 비교로도 자기 자신 체크 (객체 참조가 다를 수 있으므로)
|
||||
if (Math.abs(line.x1 - excludeLine.x1) < 0.1 && Math.abs(line.y1 - excludeLine.y1) < 0.1 &&
|
||||
Math.abs(line.x2 - excludeLine.x2) < 0.1 && Math.abs(line.y2 - excludeLine.y2) < 0.1) continue;
|
||||
|
||||
// 시작점이 내부를 향하는지 여부
|
||||
return {
|
||||
start: isInside,
|
||||
// 끝점 방향은 시작점과 반대
|
||||
end: !isInside
|
||||
};
|
||||
const lineStart = { x: line.x1, y: line.y1 };
|
||||
const lineEnd = { x: line.x2, y: line.y2 };
|
||||
|
||||
// 선분 교차 검사
|
||||
const intersect = getLineIntersection(origin, rayEnd, lineStart, lineEnd);
|
||||
|
||||
if (intersect) {
|
||||
// 교차점이 시작점(origin)과 너무 가까우면(코너 등) 무시하고,
|
||||
// 확실히 전방에 있는 경우만 인정
|
||||
const dist = Math.hypot(intersect.x - origin.x, intersect.y - origin.y);
|
||||
if (dist > 1.0) { // 1.0 정도의 여유를 둠
|
||||
return true; // 부딪힘! (빨간 라인 후보)
|
||||
}
|
||||
}
|
||||
}
|
||||
return false; // 허공! (파란 라인 후보)
|
||||
}
|
||||
|
||||
|
||||
// 점이 선분의 어느 쪽에 있는지 확인
|
||||
function isPointInDirection(line, point) {
|
||||
const {x1, y1, x2, y2} = line;
|
||||
@ -4379,3 +4622,91 @@ function isPointOnLineSegment2(point, lineStart, lineEnd, tolerance = 0.1) {
|
||||
|
||||
return isOnSegment;
|
||||
}
|
||||
|
||||
/**
|
||||
* 세 점(p1 -> p2 -> p3)의 방향성을 계산합니다. (2D 외적)
|
||||
* 반시계 방향(CCW)으로 그려진 폴리곤(Y축 Down) 기준:
|
||||
* - 결과 > 0 : 오른쪽 턴 (Right Turn) -> 골짜기 (Valley/Reflex Vertex)
|
||||
* - 결과 < 0 : 왼쪽 턴 (Left Turn) -> 외곽 모서리 (Convex Vertex)
|
||||
* - 결과 = 0 : 직선
|
||||
*/
|
||||
function getTurnDirection(p1, p2, p3) {
|
||||
// 벡터 a: p1 -> p2
|
||||
// 벡터 b: p2 -> p3
|
||||
const val = (p2.x - p1.x) * (p3.y - p2.y) - (p2.y - p1.y) * (p3.x - p2.x);
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* 현재 점(point)을 기준으로 연결된 이전 라인과 다음 라인을 찾아 골짜기 여부 판단
|
||||
*/
|
||||
function isValleyVertex(targetPoint, connectedLine, allLines, isStartVertex) {
|
||||
const tolerance = 0.1;
|
||||
|
||||
// 1. 연결된 '다른' 라인을 찾습니다.
|
||||
// isStartVertex가 true면 : 이 점으로 '들어오는' 라인(Previous Line)을 찾아야 함
|
||||
// isStartVertex가 false면 : 이 점에서 '나가는' 라인(Next Line)을 찾아야 함
|
||||
|
||||
let neighborLine = null;
|
||||
|
||||
if (isStartVertex) {
|
||||
// targetPoint가 Start이므로, 어떤 라인의 End가 targetPoint와 같아야 함 (Previous Line)
|
||||
neighborLine = allLines.find(l =>
|
||||
l !== connectedLine &&
|
||||
isSamePoint(l.endPoint || {x:l.x2, y:l.y2}, targetPoint, tolerance)
|
||||
);
|
||||
} else {
|
||||
// targetPoint가 End이므로, 어떤 라인의 Start가 targetPoint와 같아야 함 (Next Line)
|
||||
neighborLine = allLines.find(l =>
|
||||
l !== connectedLine &&
|
||||
isSamePoint(l.startPoint || {x:l.x1, y:l.y1}, targetPoint, tolerance)
|
||||
);
|
||||
}
|
||||
|
||||
// 연결된 라인을 못 찾았거나 끊겨있으면 판단 불가 (일단 false)
|
||||
if (!neighborLine) return false;
|
||||
|
||||
// 2. 세 점을 구성하여 회전 방향(Turn) 계산
|
||||
// 순서: PrevLine.Start -> [TargetVertex] -> NextLine.End
|
||||
let p1, p2, p3;
|
||||
|
||||
if (isStartVertex) {
|
||||
// neighbor(Prev) -> connected(Current)
|
||||
p1 = neighborLine.startPoint || {x: neighborLine.x1, y: neighborLine.y1};
|
||||
p2 = targetPoint; // 접점
|
||||
p3 = connectedLine.endPoint || {x: connectedLine.x2, y: connectedLine.y2};
|
||||
} else {
|
||||
// connected(Current) -> neighbor(Next)
|
||||
p1 = connectedLine.startPoint || {x: connectedLine.x1, y: connectedLine.y1};
|
||||
p2 = targetPoint; // 접점
|
||||
p3 = neighborLine.endPoint || {x: neighborLine.x2, y: neighborLine.y2};
|
||||
}
|
||||
|
||||
// 3. 외적 계산 (Y축이 아래로 증가하는 캔버스 좌표계 + CCW 진행 기준)
|
||||
// 값이 양수(+)면 오른쪽 턴 = 골짜기
|
||||
const crossProduct = getTurnDirection(p1, p2, p3);
|
||||
|
||||
return crossProduct > 0;
|
||||
}
|
||||
|
||||
function findInteriorPoint(line, polygonLines) {
|
||||
const { x1, y1, x2, y2 } = line;
|
||||
|
||||
// line 객체 포맷 통일
|
||||
const currentLine = {
|
||||
...line,
|
||||
startPoint: { x: x1, y: y1 },
|
||||
endPoint: { x: x2, y: y2 }
|
||||
};
|
||||
|
||||
// 1. 시작점이 골짜기인지 확인 (들어오는 라인과 나가는 라인의 각도)
|
||||
const startIsValley = isValleyVertex(currentLine.startPoint, currentLine, polygonLines, true);
|
||||
|
||||
// 2. 끝점이 골짜기인지 확인
|
||||
const endIsValley = isValleyVertex(currentLine.endPoint, currentLine, polygonLines, false);
|
||||
|
||||
return {
|
||||
start: startIsValley,
|
||||
end: endIsValley
|
||||
};
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user