267 lines
12 KiB
C#
267 lines
12 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using Teigha.Geometry;
|
|
|
|
namespace DwgExtractorManual.Models
|
|
{
|
|
/// <summary>
|
|
/// 교차점 생성 및 셀 추출 로직을 테스트하고 디버깅하는 클래스
|
|
/// </summary>
|
|
public class IntersectionTestDebugger
|
|
{
|
|
/// <summary>
|
|
/// 간단한 테스트 테이블을 만들어서 교차점과 셀 생성을 테스트합니다.
|
|
/// </summary>
|
|
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);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 테스트용 3x4 테이블 선분들을 생성합니다.
|
|
/// </summary>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 테스트 선분들로부터 교차점을 찾습니다.
|
|
/// </summary>
|
|
private static List<IntersectionPoint> FindTestIntersections(List<(Point3d start, Point3d end, bool isHorizontal)> segments, DwgDataExtractor extractor)
|
|
{
|
|
var intersections = new List<IntersectionPoint>();
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 특정 점에서의 DirectionBits를 계산합니다.
|
|
/// </summary>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 교차점들로부터 셀을 추출합니다.
|
|
/// </summary>
|
|
private static List<TableCell> ExtractTestCells(List<IntersectionPoint> intersections,
|
|
List<(Point3d start, Point3d end, bool isHorizontal)> segments,
|
|
DwgDataExtractor extractor)
|
|
{
|
|
var cells = new List<TableCell>();
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 테스트용 bottomRight 찾기 메서드
|
|
/// </summary>
|
|
private static IntersectionPoint FindBottomRightForTest(IntersectionPoint topLeft,
|
|
List<IntersectionPoint> 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;
|
|
}
|
|
}
|
|
|
|
} |