using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using Teigha.Geometry; namespace DwgExtractorManual.Models { /// /// 교차점 생성 및 셀 추출 로직을 테스트하고 디버깅하는 클래스 /// public class IntersectionTestDebugger { /// /// 간단한 테스트 테이블을 만들어서 교차점과 셀 생성을 테스트합니다. /// public static void RunIntersectionTest() { Debug.WriteLine("=== 교차점 및 셀 생성 테스트 시작 ==="); try { // 테스트용 테이블 생성 (3x4 그리드) var testSegments = CreateTestTable(); Debug.WriteLine($"테스트 선분 개수: {testSegments.Count}"); // DwgDataExtractor 인스턴스 생성 (실제 코드와 동일) var mappingData = new MappingTableData(); var fieldMapper = new FieldMapper(mappingData); var extractor = new DwgDataExtractor(fieldMapper); // 교차점 찾기 테스트 var intersections = FindTestIntersections(testSegments, extractor); Debug.WriteLine($"발견된 교차점 개수: {intersections.Count}"); // 각 교차점의 DirectionBits 출력 for (int i = 0; i < intersections.Count; i++) { var intersection = intersections[i]; Debug.WriteLine($"교차점 {i}: ({intersection.Position.X:F1}, {intersection.Position.Y:F1}) - DirectionBits: {intersection.DirectionBits} - R{intersection.Row}C{intersection.Column}"); // topLeft/bottomRight 검증 bool isTopLeft = extractor.IsValidTopLeft(intersection.DirectionBits); bool isBottomRight = extractor.IsValidBottomRight(intersection.DirectionBits); Debug.WriteLine($" IsTopLeft: {isTopLeft}, IsBottomRight: {isBottomRight}"); } Debug.WriteLine("=== 테스트 완료 ==="); } catch (Exception ex) { Debug.WriteLine($"테스트 중 오류 발생: {ex.Message}"); Debug.WriteLine(ex.StackTrace); } } /// /// 테스트용 3x4 테이블 선분들을 생성합니다. /// private static List<(Point3d start, Point3d end, bool isHorizontal)> CreateTestTable() { var segments = new List<(Point3d start, Point3d end, bool isHorizontal)>(); // 수평선들 (4개 - 0, 10, 20, 30 Y좌표) for (int i = 0; i <= 3; i++) { double y = i * 10.0; segments.Add((new Point3d(0, y, 0), new Point3d(40, y, 0), true)); } // 수직선들 (5개 - 0, 10, 20, 30, 40 X좌표) for (int i = 0; i <= 4; i++) { double x = i * 10.0; segments.Add((new Point3d(x, 0, 0), new Point3d(x, 30, 0), false)); } Debug.WriteLine($"생성된 테스트 테이블: 수평선 4개, 수직선 5개"); return segments; } /// /// 테스트 선분들로부터 교차점을 찾습니다. /// private static List FindTestIntersections(List<(Point3d start, Point3d end, bool isHorizontal)> segments, DwgDataExtractor extractor) { var intersections = new List(); double tolerance = 0.1; var horizontalSegments = segments.Where(s => s.isHorizontal).ToList(); var verticalSegments = segments.Where(s => !s.isHorizontal).ToList(); foreach (var hSeg in horizontalSegments) { foreach (var vSeg in verticalSegments) { // 교차점 계산 double intersectX = vSeg.start.X; double intersectY = hSeg.start.Y; var intersectPoint = new Point3d(intersectX, intersectY, 0); // 교차점이 두 선분의 범위 내에 있는지 확인 bool onHorizontal = intersectX >= Math.Min(hSeg.start.X, hSeg.end.X) - tolerance && intersectX <= Math.Max(hSeg.start.X, hSeg.end.X) + tolerance; bool onVertical = intersectY >= Math.Min(vSeg.start.Y, vSeg.end.Y) - tolerance && intersectY <= Math.Max(vSeg.start.Y, vSeg.end.Y) + tolerance; if (onHorizontal && onVertical) { // DirectionBits 계산 int directionBits = CalculateDirectionBits(intersectPoint, segments, tolerance); // Row, Column 계산 (1-based) int row = (int)Math.Round(intersectY / 10.0) + 1; int column = (int)Math.Round(intersectX / 10.0) + 1; var intersection = new IntersectionPoint { Position = intersectPoint, DirectionBits = directionBits, Row = row, Column = column }; intersections.Add(intersection); } } } return intersections; } /// /// 특정 점에서의 DirectionBits를 계산합니다. /// private static int CalculateDirectionBits(Point3d point, List<(Point3d start, Point3d end, bool isHorizontal)> segments, double tolerance) { int bits = 0; // Right: 1, Up: 2, Left: 4, Down: 8 foreach (var segment in segments) { if (segment.isHorizontal) { // 수평선에서 점이 선분 위에 있는지 확인 if (Math.Abs(point.Y - segment.start.Y) < tolerance && point.X >= Math.Min(segment.start.X, segment.end.X) - tolerance && point.X <= Math.Max(segment.start.X, segment.end.X) + tolerance) { // 오른쪽으로 선분이 있는지 확인 if (Math.Max(segment.start.X, segment.end.X) > point.X + tolerance) bits |= 1; // Right // 왼쪽으로 선분이 있는지 확인 if (Math.Min(segment.start.X, segment.end.X) < point.X - tolerance) bits |= 4; // Left } } else { // 수직선에서 점이 선분 위에 있는지 확인 if (Math.Abs(point.X - segment.start.X) < tolerance && point.Y >= Math.Min(segment.start.Y, segment.end.Y) - tolerance && point.Y <= Math.Max(segment.start.Y, segment.end.Y) + tolerance) { // 위쪽으로 선분이 있는지 확인 if (Math.Max(segment.start.Y, segment.end.Y) > point.Y + tolerance) bits |= 2; // Up // 아래쪽으로 선분이 있는지 확인 if (Math.Min(segment.start.Y, segment.end.Y) < point.Y - tolerance) bits |= 8; // Down } } } return bits; } /// /// 교차점들로부터 셀을 추출합니다. /// private static List ExtractTestCells(List intersections, List<(Point3d start, Point3d end, bool isHorizontal)> segments, DwgDataExtractor extractor) { var cells = new List(); double tolerance = 0.1; // topLeft 후보들을 찾아서 각각에 대해 bottomRight를 찾기 var topLeftCandidates = intersections.Where(i => extractor.IsValidTopLeft(i.DirectionBits)).ToList(); Debug.WriteLine($"TopLeft 후보 개수: {topLeftCandidates.Count}"); foreach (var topLeft in topLeftCandidates) { Debug.WriteLine($"\nTopLeft 후보 R{topLeft.Row}C{topLeft.Column} 처리 중..."); // bottomRight 찾기 (실제 코드와 동일한 방식) var bottomRight = FindBottomRightForTest(topLeft, intersections, extractor); if (bottomRight != null) { Debug.WriteLine($" BottomRight 발견: R{bottomRight.Row}C{bottomRight.Column}"); // 셀 생성 var cell = new TableCell { MinPoint = new Point3d(topLeft.Position.X, bottomRight.Position.Y, 0), MaxPoint = new Point3d(bottomRight.Position.X, topLeft.Position.Y, 0), Row = topLeft.Row, Column = topLeft.Column, CellText = $"R{topLeft.Row}C{topLeft.Column}" }; cells.Add(cell); Debug.WriteLine($" 셀 생성 완료: ({cell.MinPoint.X:F1},{cell.MinPoint.Y:F1}) to ({cell.MaxPoint.X:F1},{cell.MaxPoint.Y:F1})"); } else { Debug.WriteLine($" BottomRight을 찾지 못함"); } } return cells; } /// /// 테스트용 bottomRight 찾기 메서드 /// private static IntersectionPoint FindBottomRightForTest(IntersectionPoint topLeft, List intersections, DwgDataExtractor extractor) { // 교차점들을 Row/Column으로 딕셔너리 구성 var intersectionLookup = intersections .Where(i => i.Row > 0 && i.Column > 0) .GroupBy(i => i.Row) .ToDictionary(g => g.Key, g => g.ToDictionary(i => i.Column, i => i)); // topLeft에서 시작하여 bottomRight 찾기 int maxRow = intersectionLookup.Keys.Any() ? intersectionLookup.Keys.Max() : topLeft.Row; for (int targetRow = topLeft.Row + 1; targetRow <= maxRow + 2; targetRow++) { if (!intersectionLookup.ContainsKey(targetRow)) continue; var rowIntersections = intersectionLookup[targetRow]; var availableColumns = rowIntersections.Keys.Where(col => col >= topLeft.Column).OrderBy(col => col); foreach (int targetColumn in availableColumns) { var candidate = rowIntersections[targetColumn]; if (extractor.IsValidBottomRight(candidate.DirectionBits) || (targetRow == maxRow && targetColumn == intersectionLookup.Values.SelectMany(row => row.Keys).Max())) { return candidate; } } } return null; } } }