raycasting note content box detect
This commit is contained in:
@@ -506,6 +506,59 @@ namespace DwgExtractorManual.Models
|
|||||||
return noteTextIds;
|
return noteTextIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 모든 Line과 Polyline 엔터티를 통합된 Line 세그먼트 리스트로 변환합니다.
|
||||||
|
/// Polyline은 구성 Line 세그먼트로 분해됩니다.
|
||||||
|
/// </summary>
|
||||||
|
private List<Line> GetAllLineSegments(Transaction tran, List<ObjectId> polylineIds, List<ObjectId> lineIds)
|
||||||
|
{
|
||||||
|
var allLineSegments = new List<Line>();
|
||||||
|
|
||||||
|
// Polylines를 Line 세그먼트로 분해하여 추가
|
||||||
|
foreach (var polylineId in polylineIds)
|
||||||
|
{
|
||||||
|
using (var polyline = tran.GetObject(polylineId, OpenMode.ForRead) as Polyline)
|
||||||
|
{
|
||||||
|
if (polyline == null) continue;
|
||||||
|
var explodedEntities = new DBObjectCollection();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
polyline.Explode(explodedEntities);
|
||||||
|
foreach (DBObject obj in explodedEntities)
|
||||||
|
{
|
||||||
|
if (obj is Line line)
|
||||||
|
{
|
||||||
|
allLineSegments.Add(line.Clone() as Line);
|
||||||
|
}
|
||||||
|
obj.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (System.Exception ex)
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"[DEBUG] Polyline 분해 중 오류: {ex.Message}");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
explodedEntities.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 기존 Line들을 추가
|
||||||
|
foreach (var lineId in lineIds)
|
||||||
|
{
|
||||||
|
using (var line = tran.GetObject(lineId, OpenMode.ForRead) as Line)
|
||||||
|
{
|
||||||
|
if (line != null)
|
||||||
|
{
|
||||||
|
allLineSegments.Add(line.Clone() as Line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return allLineSegments;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Note 텍스트 아래에 있는 콘텐츠 박스를 찾습니다.
|
/// Note 텍스트 아래에 있는 콘텐츠 박스를 찾습니다.
|
||||||
/// Note의 정렬점을 기준으로 안정적인 검색 라인을 사용합니다.
|
/// Note의 정렬점을 기준으로 안정적인 검색 라인을 사용합니다.
|
||||||
@@ -513,83 +566,84 @@ namespace DwgExtractorManual.Models
|
|||||||
private (Point3d minPoint, Point3d maxPoint)? FindNoteBox(
|
private (Point3d minPoint, Point3d maxPoint)? FindNoteBox(
|
||||||
Transaction tran, DBText noteText, List<ObjectId> polylineIds, List<ObjectId> lineIds, HashSet<(Point3d minPoint, Point3d maxPoint)> usedBoxes)
|
Transaction tran, DBText noteText, List<ObjectId> polylineIds, List<ObjectId> lineIds, HashSet<(Point3d minPoint, Point3d maxPoint)> usedBoxes)
|
||||||
{
|
{
|
||||||
var allLineSegments = new List<Line>();
|
var allLineSegments = GetAllLineSegments(tran, polylineIds, lineIds);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var notePos = noteText.Position;
|
var notePos = noteText.Position;
|
||||||
var noteHeight = noteText.Height;
|
var noteHeight = noteText.Height;
|
||||||
|
|
||||||
// Polylines를 Line 세그먼트로 분해하여 추가
|
// Note의 X 좌표 결정 (정렬 방식에 따라)
|
||||||
foreach (var polylineId in polylineIds)
|
double noteX;
|
||||||
{
|
|
||||||
using (var polyline = tran.GetObject(polylineId, OpenMode.ForRead) as Polyline)
|
|
||||||
{
|
|
||||||
if (polyline == null) continue;
|
|
||||||
var explodedEntities = new DBObjectCollection();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
polyline.Explode(explodedEntities);
|
|
||||||
foreach (DBObject obj in explodedEntities)
|
|
||||||
{
|
|
||||||
if (obj is Line line)
|
|
||||||
{
|
|
||||||
allLineSegments.Add(line.Clone() as Line);
|
|
||||||
}
|
|
||||||
obj.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (System.Exception ex)
|
|
||||||
{
|
|
||||||
Debug.WriteLine($"[DEBUG] Polyline 분해 중 오류: {ex.Message}");
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
explodedEntities.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 기존 Line들을 추가
|
|
||||||
foreach (var lineId in lineIds)
|
|
||||||
{
|
|
||||||
using (var line = tran.GetObject(lineId, OpenMode.ForRead) as Line)
|
|
||||||
{
|
|
||||||
if (line != null)
|
|
||||||
{
|
|
||||||
allLineSegments.Add(line.Clone() as Line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
double stableX;
|
|
||||||
if (noteText.HorizontalMode == TextHorizontalMode.TextLeft)
|
if (noteText.HorizontalMode == TextHorizontalMode.TextLeft)
|
||||||
{
|
{
|
||||||
stableX = noteText.Position.X;
|
noteX = noteText.Position.X;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stableX = noteText.AlignmentPoint.X;
|
noteX = noteText.AlignmentPoint.X;
|
||||||
}
|
}
|
||||||
|
|
||||||
double searchY = notePos.Y - (noteHeight * 2);
|
Debug.WriteLine($"[DEBUG] 수직 Ray-Casting 시작: NOTE '{noteText.TextString}' at ({noteX:F2}, {notePos.Y:F2})");
|
||||||
double searchWidth = noteHeight * 15;
|
|
||||||
var searchLineStart = new Point3d(stableX - noteHeight * 6, searchY, 0); // 왼쪽으로 확장 (중간값)
|
|
||||||
var searchLineEnd = new Point3d(stableX + searchWidth, searchY, 0);
|
|
||||||
var searchLineEnd = new Point3d(stableX + searchWidth, searchY, 0);
|
|
||||||
|
|
||||||
Debug.WriteLine($"[DEBUG] 확장된 통합 검색 라인: ({searchLineStart.X:F2}, {searchLineStart.Y:F2}) to ({searchLineEnd.X:F2}, {searchLineEnd.Y:F2}) for NOTE at ({notePos.X:F2}, {notePos.Y:F2})");
|
// 수직 레이 캐스팅을 위한 하향 스캔
|
||||||
|
var horizontalLines = new List<(Line line, double y)>();
|
||||||
|
|
||||||
var intersectingLines = FindIntersectingLineSegments(allLineSegments, searchLineStart, searchLineEnd);
|
// 모든 라인 세그먼트를 검사하여 수직 레이와 교차하는 수평선들을 찾음
|
||||||
foreach (var startLine in intersectingLines)
|
foreach (var line in allLineSegments)
|
||||||
{
|
{
|
||||||
var rectangle = TraceRectangleFromLineSegments(allLineSegments, startLine, notePos, noteHeight, usedBoxes);
|
// 수평선인지 확인 (Y 좌표가 거의 같음)
|
||||||
if (rectangle.HasValue)
|
if (Math.Abs(line.StartPoint.Y - line.EndPoint.Y) < noteHeight * 0.1)
|
||||||
{
|
{
|
||||||
Debug.WriteLine($"[DEBUG] 교차하는 Line/Polyline 조합 사각형 발견: {rectangle.Value.minPoint} to {rectangle.Value.maxPoint}");
|
double lineY = (line.StartPoint.Y + line.EndPoint.Y) / 2;
|
||||||
return rectangle;
|
double lineMinX = Math.Min(line.StartPoint.X, line.EndPoint.X);
|
||||||
|
double lineMaxX = Math.Max(line.StartPoint.X, line.EndPoint.X);
|
||||||
|
|
||||||
|
// 수직 레이가 이 수평선과 교차하는지 확인
|
||||||
|
if (noteX >= lineMinX && noteX <= lineMaxX && lineY < notePos.Y)
|
||||||
|
{
|
||||||
|
horizontalLines.Add((line, lineY));
|
||||||
|
Debug.WriteLine($"[DEBUG] 수평선 발견: Y={lineY:F2}, X범위=({lineMinX:F2}~{lineMaxX:F2})");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Y 좌표로 정렬 (위에서 아래로)
|
||||||
|
var sortedHorizontalLines = horizontalLines
|
||||||
|
.OrderByDescending(hl => hl.y)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
Debug.WriteLine($"[DEBUG] 정렬된 수평선 개수: {sortedHorizontalLines.Count}");
|
||||||
|
|
||||||
|
// 두 번째 수평선을 콘텐츠 박스의 상단으로 식별 (첫 번째는 NOTE 자체의 경계로 가정)
|
||||||
|
if (sortedHorizontalLines.Count >= 2)
|
||||||
|
{
|
||||||
|
var topLine = sortedHorizontalLines[1].line;
|
||||||
|
Debug.WriteLine($"[DEBUG] 콘텐츠 박스 상단선 선택 (2번째): Y={sortedHorizontalLines[1].y:F2}");
|
||||||
|
|
||||||
|
// 이 상단선으로부터 박스를 추적
|
||||||
|
var rectangle = TraceBoxFromTopLine(allLineSegments, topLine, notePos, noteHeight, usedBoxes);
|
||||||
|
if (rectangle.HasValue)
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"[DEBUG] Ray-Casting으로 박스 발견 (2번째 선): {rectangle.Value.minPoint} to {rectangle.Value.maxPoint}");
|
||||||
|
return rectangle;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2번째 선으로 실패시 3번째 선 시도 (shadow effect polyline 고려)
|
||||||
|
if (sortedHorizontalLines.Count >= 3)
|
||||||
|
{
|
||||||
|
var fallbackTopLine = sortedHorizontalLines[2].line;
|
||||||
|
Debug.WriteLine($"[DEBUG] 대안 콘텐츠 박스 상단선 선택 (3번째): Y={sortedHorizontalLines[2].y:F2}");
|
||||||
|
|
||||||
|
var fallbackRectangle = TraceBoxFromTopLine(allLineSegments, fallbackTopLine, notePos, noteHeight, usedBoxes);
|
||||||
|
if (fallbackRectangle.HasValue)
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"[DEBUG] Ray-Casting으로 박스 발견 (3번째 선): {fallbackRectangle.Value.minPoint} to {fallbackRectangle.Value.maxPoint}");
|
||||||
|
return fallbackRectangle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.WriteLine($"[DEBUG] Ray-Casting으로 적절한 박스를 찾지 못함");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@@ -602,133 +656,158 @@ namespace DwgExtractorManual.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Line> FindIntersectingLineSegments(List<Line> allLineSegments, Point3d searchLineStart, Point3d searchLineEnd)
|
/// <summary>
|
||||||
{
|
/// 식별된 상단선으로부터 지능적으로 박스의 나머지 세 변을 추적합니다.
|
||||||
var intersectingLines = new List<Line>();
|
/// 작은 간격에 대해 관용적입니다.
|
||||||
foreach (var line in allLineSegments)
|
/// </summary>
|
||||||
{
|
private (Point3d minPoint, Point3d maxPoint)? TraceBoxFromTopLine(
|
||||||
if (DoLinesIntersect(searchLineStart, searchLineEnd, line.StartPoint, line.EndPoint))
|
List<Line> allLineSegments, Line topLine, Point3d notePos, double noteHeight, HashSet<(Point3d minPoint, Point3d maxPoint)> usedBoxes)
|
||||||
{
|
|
||||||
intersectingLines.Add(line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return intersectingLines;
|
|
||||||
}
|
|
||||||
|
|
||||||
private (Point3d minPoint, Point3d maxPoint)? TraceRectangleFromLineSegments(List<Line> allLineSegments, Line startLine, Point3d notePos, double noteHeight, HashSet<(Point3d minPoint, Point3d maxPoint)> usedBoxes)
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
double tolerance = noteHeight * 2.0;
|
double tolerance = noteHeight * 0.5; // 간격 허용 오차
|
||||||
var visitedLines = new HashSet<Line>();
|
|
||||||
var rectanglePoints = new List<Point3d>();
|
|
||||||
|
|
||||||
var currentPoint = startLine.StartPoint;
|
Debug.WriteLine($"[DEBUG] 박스 추적 시작: 상단선 ({topLine.StartPoint.X:F2},{topLine.StartPoint.Y:F2}) to ({topLine.EndPoint.X:F2},{topLine.EndPoint.Y:F2})");
|
||||||
var nextPoint = startLine.EndPoint;
|
|
||||||
rectanglePoints.Add(currentPoint);
|
|
||||||
rectanglePoints.Add(nextPoint);
|
|
||||||
visitedLines.Add(startLine);
|
|
||||||
|
|
||||||
for (int step = 0; step < 5; step++)
|
// 상단선의 끝점들
|
||||||
|
var topLeft = new Point3d(Math.Min(topLine.StartPoint.X, topLine.EndPoint.X), topLine.StartPoint.Y, 0);
|
||||||
|
var topRight = new Point3d(Math.Max(topLine.StartPoint.X, topLine.EndPoint.X), topLine.StartPoint.Y, 0);
|
||||||
|
|
||||||
|
// 왼쪽 수직선 찾기
|
||||||
|
Line leftLine = null;
|
||||||
|
foreach (var line in allLineSegments)
|
||||||
{
|
{
|
||||||
var findResult = FindNextConnectedLineSegment(allLineSegments, nextPoint, visitedLines, tolerance);
|
if (IsVerticalLine(line, noteHeight) &&
|
||||||
if (findResult == null) break;
|
IsLineConnectedToPoint(line, topLeft, tolerance))
|
||||||
|
|
||||||
var nextLine = findResult.Value.line;
|
|
||||||
var connectionType = findResult.Value.connectionType;
|
|
||||||
|
|
||||||
Point3d newNextPoint = (connectionType == "Start") ? nextLine.EndPoint : nextLine.StartPoint;
|
|
||||||
|
|
||||||
rectanglePoints.Add(newNextPoint);
|
|
||||||
visitedLines.Add(nextLine);
|
|
||||||
nextPoint = newNextPoint;
|
|
||||||
|
|
||||||
if (nextPoint.DistanceTo(currentPoint) < tolerance)
|
|
||||||
{
|
{
|
||||||
|
leftLine = line;
|
||||||
|
Debug.WriteLine($"[DEBUG] 왼쪽 수직선 발견: ({line.StartPoint.X:F2},{line.StartPoint.Y:F2}) to ({line.EndPoint.X:F2},{line.EndPoint.Y:F2})");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rectanglePoints.Count >= 4)
|
// 오른쪽 수직선 찾기
|
||||||
|
Line rightLine = null;
|
||||||
|
foreach (var line in allLineSegments)
|
||||||
{
|
{
|
||||||
var bounds = CalculateBounds(rectanglePoints);
|
if (IsVerticalLine(line, noteHeight) &&
|
||||||
if (bounds.HasValue && IsValidNoteBox(bounds.Value, notePos, noteHeight) && !usedBoxes.Contains(bounds.Value))
|
IsLineConnectedToPoint(line, topRight, tolerance))
|
||||||
{
|
{
|
||||||
return bounds;
|
rightLine = line;
|
||||||
|
Debug.WriteLine($"[DEBUG] 오른쪽 수직선 발견: ({line.StartPoint.X:F2},{line.StartPoint.Y:F2}) to ({line.EndPoint.X:F2},{line.EndPoint.Y:F2})");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (leftLine == null || rightLine == null)
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"[DEBUG] 수직선을 찾을 수 없음: left={leftLine != null}, right={rightLine != null}");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 하단 끝점들 계산
|
||||||
|
var bottomLeft = GetFarEndPoint(leftLine, topLeft);
|
||||||
|
var bottomRight = GetFarEndPoint(rightLine, topRight);
|
||||||
|
|
||||||
|
// 하단선 찾기
|
||||||
|
Line bottomLine = null;
|
||||||
|
double expectedBottomY = Math.Min(bottomLeft.Y, bottomRight.Y);
|
||||||
|
|
||||||
|
foreach (var line in allLineSegments)
|
||||||
|
{
|
||||||
|
if (IsHorizontalLine(line, noteHeight))
|
||||||
|
{
|
||||||
|
double lineY = (line.StartPoint.Y + line.EndPoint.Y) / 2;
|
||||||
|
if (Math.Abs(lineY - expectedBottomY) < tolerance)
|
||||||
|
{
|
||||||
|
// 하단선이 왼쪽과 오른쪽 끝점을 연결하는지 확인
|
||||||
|
var lineLeft = new Point3d(Math.Min(line.StartPoint.X, line.EndPoint.X), lineY, 0);
|
||||||
|
var lineRight = new Point3d(Math.Max(line.StartPoint.X, line.EndPoint.X), lineY, 0);
|
||||||
|
|
||||||
|
if (Math.Abs(lineLeft.X - bottomLeft.X) < tolerance &&
|
||||||
|
Math.Abs(lineRight.X - bottomRight.X) < tolerance)
|
||||||
|
{
|
||||||
|
bottomLine = line;
|
||||||
|
Debug.WriteLine($"[DEBUG] 하단선 발견: ({line.StartPoint.X:F2},{line.StartPoint.Y:F2}) to ({line.EndPoint.X:F2},{line.EndPoint.Y:F2})");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bottomLine == null)
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"[DEBUG] 하단선을 찾을 수 없음");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 최종 박스 경계 계산
|
||||||
|
var minPoint = new Point3d(
|
||||||
|
Math.Min(topLeft.X, bottomLeft.X),
|
||||||
|
Math.Min(topLeft.Y, bottomLeft.Y),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
var maxPoint = new Point3d(
|
||||||
|
Math.Max(topRight.X, bottomRight.X),
|
||||||
|
Math.Max(topLeft.Y, bottomLeft.Y),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
var result = (minPoint, maxPoint);
|
||||||
|
|
||||||
|
// 유효성 검사
|
||||||
|
if (IsValidNoteBox(result, notePos, noteHeight) && !usedBoxes.Contains(result))
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"[DEBUG] 유효한 박스 추적 완료: ({minPoint.X:F2},{minPoint.Y:F2}) to ({maxPoint.X:F2},{maxPoint.Y:F2})");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.WriteLine($"[DEBUG] 추적된 박스가 유효하지 않음");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
catch (System.Exception ex)
|
catch (System.Exception ex)
|
||||||
{
|
{
|
||||||
Debug.WriteLine($"[DEBUG] 통합 사각형 추적 중 오류: {ex.Message}");
|
Debug.WriteLine($"[DEBUG] 박스 추적 중 오류: {ex.Message}");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private (Line line, string connectionType)? FindNextConnectedLineSegment(List<Line> allLineSegments, Point3d currentPoint, HashSet<Line> visitedLines, double tolerance)
|
/// <summary>
|
||||||
|
/// 선분이 수직선인지 확인합니다.
|
||||||
|
/// </summary>
|
||||||
|
private bool IsVerticalLine(Line line, double noteHeight)
|
||||||
{
|
{
|
||||||
Line bestMatch = null;
|
return Math.Abs(line.StartPoint.X - line.EndPoint.X) < noteHeight * 0.1;
|
||||||
string bestConnectionType = null;
|
|
||||||
double minDistance = tolerance;
|
|
||||||
|
|
||||||
foreach (var line in allLineSegments)
|
|
||||||
{
|
|
||||||
if (visitedLines.Contains(line)) continue;
|
|
||||||
|
|
||||||
double distToStart = currentPoint.DistanceTo(line.StartPoint);
|
|
||||||
if (distToStart < minDistance)
|
|
||||||
{
|
|
||||||
minDistance = distToStart;
|
|
||||||
bestMatch = line;
|
|
||||||
bestConnectionType = "Start";
|
|
||||||
}
|
|
||||||
|
|
||||||
double distToEnd = currentPoint.DistanceTo(line.EndPoint);
|
|
||||||
if (distToEnd < minDistance)
|
|
||||||
{
|
|
||||||
minDistance = distToEnd;
|
|
||||||
bestMatch = line;
|
|
||||||
bestConnectionType = "End";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bestMatch != null)
|
|
||||||
{
|
|
||||||
return (bestMatch, bestConnectionType);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 수평선이 Polyline과 교차하는지 확인합니다.
|
/// 선분이 수평선인지 확인합니다.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private bool DoesLineIntersectPolyline(Point3d lineStart, Point3d lineEnd, Polyline polyline)
|
private bool IsHorizontalLine(Line line, double noteHeight)
|
||||||
{
|
{
|
||||||
try
|
return Math.Abs(line.StartPoint.Y - line.EndPoint.Y) < noteHeight * 0.1;
|
||||||
{
|
|
||||||
for (int i = 0; i < polyline.NumberOfVertices; i++)
|
|
||||||
{
|
|
||||||
int nextIndex = (i + 1) % polyline.NumberOfVertices;
|
|
||||||
var segStart = polyline.GetPoint3dAt(i);
|
|
||||||
var segEnd = polyline.GetPoint3dAt(nextIndex);
|
|
||||||
|
|
||||||
// 수평선과 폴리라인 세그먼트의 교차점 확인
|
|
||||||
if (DoLinesIntersect(lineStart, lineEnd, segStart, segEnd))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 선분이 지정된 점에 연결되어 있는지 확인합니다.
|
||||||
|
/// </summary>
|
||||||
|
private bool IsLineConnectedToPoint(Line line, Point3d point, double tolerance)
|
||||||
|
{
|
||||||
|
return point.DistanceTo(line.StartPoint) < tolerance || point.DistanceTo(line.EndPoint) < tolerance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 선분에서 지정된 점으로부터 가장 먼 끝점을 반환합니다.
|
||||||
|
/// </summary>
|
||||||
|
private Point3d GetFarEndPoint(Line line, Point3d referencePoint)
|
||||||
|
{
|
||||||
|
double distToStart = referencePoint.DistanceTo(line.StartPoint);
|
||||||
|
double distToEnd = referencePoint.DistanceTo(line.EndPoint);
|
||||||
|
|
||||||
|
return distToStart > distToEnd ? line.StartPoint : line.EndPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 두 선분이 교차하는지 확인합니다.
|
/// 두 선분이 교차하는지 확인합니다.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -755,33 +834,6 @@ namespace DwgExtractorManual.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Polyline의 경계 상자를 계산합니다.
|
|
||||||
/// </summary>
|
|
||||||
private (Point3d minPoint, Point3d maxPoint)? GetPolylineBounds(Polyline polyline)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (polyline.NumberOfVertices < 3) return null;
|
|
||||||
|
|
||||||
var vertices = new List<Point3d>();
|
|
||||||
for (int i = 0; i < polyline.NumberOfVertices; i++)
|
|
||||||
{
|
|
||||||
vertices.Add(polyline.GetPoint3dAt(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
double minX = vertices.Min(v => v.X);
|
|
||||||
double maxX = vertices.Max(v => v.X);
|
|
||||||
double minY = vertices.Min(v => v.Y);
|
|
||||||
double maxY = vertices.Max(v => v.Y);
|
|
||||||
|
|
||||||
return (new Point3d(minX, minY, 0), new Point3d(maxX, maxY, 0));
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 박스가 유효한 Note 박스인지 확인합니다.
|
/// 박스가 유효한 Note 박스인지 확인합니다.
|
||||||
|
|||||||
Reference in New Issue
Block a user