도면에서 표 추출
This commit is contained in:
109
Views/TableCellVisualizationWindow.xaml
Normal file
109
Views/TableCellVisualizationWindow.xaml
Normal file
@@ -0,0 +1,109 @@
|
||||
<Window x:Class="DwgExtractorManual.Views.TableCellVisualizationWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="clr-namespace:DwgExtractorManual.Controls"
|
||||
Title="테이블 셀 시각화" Height="800" Width="1200"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
MinHeight="600" MinWidth="800">
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 헤더 -->
|
||||
<Border Grid.Row="0" Background="#34495E" Padding="15">
|
||||
<StackPanel>
|
||||
<TextBlock Text="테이블 셀 시각화"
|
||||
FontSize="20" FontWeight="Bold"
|
||||
Foreground="White" HorizontalAlignment="Center"/>
|
||||
<TextBlock Text="추출된 테이블 셀들의 경계를 시각적으로 확인할 수 있습니다"
|
||||
FontSize="12" Foreground="LightGray"
|
||||
HorizontalAlignment="Center" Margin="0,5,0,0"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- 메인 영역 -->
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="250"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- 좌측 패널: 파일 목록 및 설정 -->
|
||||
<Border Grid.Column="0" Background="#ECF0F1" BorderBrush="#BDC3C7" BorderThickness="0,0,1,0">
|
||||
<StackPanel Margin="10">
|
||||
<TextBlock Text="파일 목록" FontWeight="Bold" FontSize="14" Margin="0,0,0,10"/>
|
||||
|
||||
<ListBox x:Name="lstFiles" Height="200"
|
||||
SelectionChanged="LstFiles_SelectionChanged"
|
||||
Background="White" BorderBrush="#BDC3C7">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding FileName}" FontWeight="Bold" FontSize="12"/>
|
||||
<TextBlock Text="{Binding NoteText}" FontSize="10" Foreground="Gray" TextTrimming="CharacterEllipsis"/>
|
||||
<TextBlock FontSize="10" Foreground="DarkBlue">
|
||||
<Run Text="셀: "/>
|
||||
<Run Text="{Binding Path=Cells.Count, Mode=OneWay}"/>
|
||||
<Run Text="개"/>
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
|
||||
<Separator Margin="0,10"/>
|
||||
|
||||
<TextBlock Text="표시 옵션" FontWeight="Bold" FontSize="14" Margin="0,0,0,10"/>
|
||||
|
||||
<CheckBox x:Name="chkShowCells" Content="셀 경계 표시 (기존)" IsChecked="False"
|
||||
Checked="RefreshVisualization" Unchecked="RefreshVisualization"/>
|
||||
<CheckBox x:Name="chkShowCellBoundaries" Content="정확한 셀 경계 표시" IsChecked="True" Margin="0,5,0,0"
|
||||
Checked="RefreshVisualization" Unchecked="RefreshVisualization"/>
|
||||
<CheckBox x:Name="chkShowSegments" Content="선분 표시" IsChecked="True" Margin="0,5,0,0"
|
||||
Checked="RefreshVisualization" Unchecked="RefreshVisualization"/>
|
||||
<CheckBox x:Name="chkShowTexts" Content="텍스트 표시" IsChecked="True" Margin="0,5,0,0"
|
||||
Checked="RefreshVisualization" Unchecked="RefreshVisualization"/>
|
||||
<CheckBox x:Name="chkShowIntersections" Content="교차점 표시" IsChecked="True" Margin="0,5,0,0"
|
||||
Checked="RefreshVisualization" Unchecked="RefreshVisualization"/>
|
||||
<CheckBox x:Name="chkShowDiagonals" Content="셀 대각선 표시" IsChecked="True" Margin="0,5,0,0"
|
||||
Checked="RefreshVisualization" Unchecked="RefreshVisualization"/>
|
||||
<CheckBox x:Name="chkShowNoteBounds" Content="Note 경계 표시" IsChecked="False" Margin="0,5,0,0"
|
||||
Checked="RefreshVisualization" Unchecked="RefreshVisualization"/>
|
||||
|
||||
<Separator Margin="0,10"/>
|
||||
|
||||
<TextBlock Text="확대/축소" FontWeight="Bold" FontSize="14" Margin="0,0,0,10"/>
|
||||
<Button x:Name="btnZoomFit" Content="초기화 (마우스 우클릭)" Click="BtnZoomFit_Click" Margin="0,2"/>
|
||||
|
||||
<Separator Margin="0,10"/>
|
||||
|
||||
<TextBlock x:Name="txtInfo" Text="파일을 선택하세요" FontSize="11"
|
||||
Foreground="DarkGray" TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- 우측 패널: 시각화 영역 -->
|
||||
<Border Grid.Column="1" Background="White">
|
||||
<controls:ZoomBorder x:Name="svViewer" ClipToBounds="True">
|
||||
<Canvas x:Name="cnvVisualization" Background="White"
|
||||
Width="800" Height="600"
|
||||
MouseMove="CnvVisualization_MouseMove"/>
|
||||
</controls:ZoomBorder>
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
<!-- 상태바 -->
|
||||
<StatusBar Grid.Row="2" Background="#95A5A6">
|
||||
<StatusBarItem>
|
||||
<TextBlock x:Name="txtStatus" Text="준비됨"/>
|
||||
</StatusBarItem>
|
||||
<StatusBarItem HorizontalAlignment="Right">
|
||||
<TextBlock x:Name="txtMousePos" Text="마우스: (0, 0)"/>
|
||||
</StatusBarItem>
|
||||
</StatusBar>
|
||||
</Grid>
|
||||
</Window>
|
||||
493
Views/TableCellVisualizationWindow.xaml.cs
Normal file
493
Views/TableCellVisualizationWindow.xaml.cs
Normal file
@@ -0,0 +1,493 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Shapes;
|
||||
using DwgExtractorManual.Models;
|
||||
using Brushes = System.Windows.Media.Brushes;
|
||||
using MouseEventArgs = System.Windows.Input.MouseEventArgs;
|
||||
using Point = System.Windows.Point;
|
||||
using Rectangle = System.Windows.Shapes.Rectangle;
|
||||
|
||||
namespace DwgExtractorManual.Views
|
||||
{
|
||||
public partial class TableCellVisualizationWindow : Window
|
||||
{
|
||||
private List<TableCellVisualizationData> _visualizationData;
|
||||
private TableCellVisualizationData? _currentData;
|
||||
private double _scale = 1.0;
|
||||
private const double MARGIN = 50;
|
||||
|
||||
public TableCellVisualizationWindow(List<TableCellVisualizationData> visualizationData)
|
||||
{
|
||||
InitializeComponent();
|
||||
_visualizationData = visualizationData;
|
||||
LoadFileList();
|
||||
}
|
||||
|
||||
private void LoadFileList()
|
||||
{
|
||||
lstFiles.ItemsSource = _visualizationData;
|
||||
if (_visualizationData.Count > 0)
|
||||
{
|
||||
lstFiles.SelectedIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void LstFiles_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (lstFiles.SelectedItem is TableCellVisualizationData selectedData)
|
||||
{
|
||||
_currentData = selectedData;
|
||||
RefreshVisualization();
|
||||
UpdateInfo();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateInfo()
|
||||
{
|
||||
if (_currentData == null)
|
||||
{
|
||||
txtInfo.Text = "파일을 선택하세요";
|
||||
txtStatus.Text = "준비됨";
|
||||
return;
|
||||
}
|
||||
|
||||
txtInfo.Text = $"파일: {_currentData.FileName}\n" +
|
||||
$"Note: {_currentData.NoteText}\n" +
|
||||
$"셀 수: {_currentData.Cells.Count}\n" +
|
||||
$"선분 수: {_currentData.TableSegments.Count}\n" +
|
||||
$"텍스트 수: {_currentData.TextEntities.Count}\n" +
|
||||
$"교차점 수: {_currentData.IntersectionPoints.Count}\n" +
|
||||
$"대각선 수: {_currentData.DiagonalLines.Count}";
|
||||
|
||||
txtStatus.Text = $"{_currentData.FileName} - 셀 {_currentData.Cells.Count}개";
|
||||
}
|
||||
|
||||
private void RefreshVisualization()
|
||||
{
|
||||
if (_currentData == null) return;
|
||||
|
||||
cnvVisualization.Children.Clear();
|
||||
|
||||
// 좌표계 변환 계산
|
||||
var bounds = CalculateBounds();
|
||||
if (bounds == null) return;
|
||||
|
||||
var (minX, minY, maxX, maxY) = bounds.Value;
|
||||
var dataWidth = maxX - minX;
|
||||
var dataHeight = maxY - minY;
|
||||
|
||||
// 캔버스 크기 설정 (여백 포함)
|
||||
var canvasWidth = cnvVisualization.Width;
|
||||
var canvasHeight = cnvVisualization.Height;
|
||||
|
||||
// 스케일 계산 (데이터가 캔버스에 맞도록)
|
||||
var scaleX = (canvasWidth - 2 * MARGIN) / dataWidth;
|
||||
var scaleY = (canvasHeight - 2 * MARGIN) / dataHeight;
|
||||
_scale = Math.Min(scaleX, scaleY) * 0.9; // 여유분 10%
|
||||
|
||||
// Note 경계 표시
|
||||
if (chkShowNoteBounds.IsChecked == true)
|
||||
{
|
||||
DrawNoteBounds(minX, minY, maxX, maxY);
|
||||
}
|
||||
|
||||
// 선분 표시
|
||||
if (chkShowSegments.IsChecked == true)
|
||||
{
|
||||
DrawSegments();
|
||||
}
|
||||
|
||||
// 셀 경계 표시 (기존)
|
||||
if (chkShowCells.IsChecked == true)
|
||||
{
|
||||
DrawCells();
|
||||
}
|
||||
|
||||
// 정확한 셀 경계 표시 (새로운)
|
||||
if (chkShowCellBoundaries.IsChecked == true)
|
||||
{
|
||||
DrawCellBoundaries();
|
||||
}
|
||||
|
||||
// 텍스트 표시
|
||||
if (chkShowTexts.IsChecked == true)
|
||||
{
|
||||
DrawTexts();
|
||||
}
|
||||
|
||||
// 교차점 표시
|
||||
if (chkShowIntersections.IsChecked == true)
|
||||
{
|
||||
DrawIntersections();
|
||||
}
|
||||
|
||||
// 대각선 표시 (셀 디버깅용)
|
||||
if (chkShowDiagonals.IsChecked == true)
|
||||
{
|
||||
DrawDiagonals();
|
||||
}
|
||||
}
|
||||
|
||||
private (double minX, double minY, double maxX, double maxY)? CalculateBounds()
|
||||
{
|
||||
if (_currentData == null || _currentData.Cells.Count == 0) return null;
|
||||
|
||||
var minX = _currentData.Cells.Min(c => c.MinX);
|
||||
var minY = _currentData.Cells.Min(c => c.MinY);
|
||||
var maxX = _currentData.Cells.Max(c => c.MaxX);
|
||||
var maxY = _currentData.Cells.Max(c => c.MaxY);
|
||||
|
||||
// 선분도 고려
|
||||
if (_currentData.TableSegments.Count > 0)
|
||||
{
|
||||
minX = Math.Min(minX, _currentData.TableSegments.Min(s => Math.Min(s.StartX, s.EndX)));
|
||||
minY = Math.Min(minY, _currentData.TableSegments.Min(s => Math.Min(s.StartY, s.EndY)));
|
||||
maxX = Math.Max(maxX, _currentData.TableSegments.Max(s => Math.Max(s.StartX, s.EndX)));
|
||||
maxY = Math.Max(maxY, _currentData.TableSegments.Max(s => Math.Max(s.StartY, s.EndY)));
|
||||
}
|
||||
|
||||
// 교차점도 고려
|
||||
if (_currentData.IntersectionPoints.Count > 0)
|
||||
{
|
||||
minX = Math.Min(minX, _currentData.IntersectionPoints.Min(i => i.X));
|
||||
minY = Math.Min(minY, _currentData.IntersectionPoints.Min(i => i.Y));
|
||||
maxX = Math.Max(maxX, _currentData.IntersectionPoints.Max(i => i.X));
|
||||
maxY = Math.Max(maxY, _currentData.IntersectionPoints.Max(i => i.Y));
|
||||
}
|
||||
|
||||
// 대각선도 고려
|
||||
if (_currentData.DiagonalLines.Count > 0)
|
||||
{
|
||||
minX = Math.Min(minX, _currentData.DiagonalLines.Min(d => Math.Min(d.StartX, d.EndX)));
|
||||
minY = Math.Min(minY, _currentData.DiagonalLines.Min(d => Math.Min(d.StartY, d.EndY)));
|
||||
maxX = Math.Max(maxX, _currentData.DiagonalLines.Max(d => Math.Max(d.StartX, d.EndX)));
|
||||
maxY = Math.Max(maxY, _currentData.DiagonalLines.Max(d => Math.Max(d.StartY, d.EndY)));
|
||||
}
|
||||
|
||||
// 정확한 셀 경계도 고려
|
||||
if (_currentData.CellBoundaries != null && _currentData.CellBoundaries.Count > 0)
|
||||
{
|
||||
var allCellX = _currentData.CellBoundaries.SelectMany(cb => new[] { cb.TopLeftX, cb.TopRightX, cb.BottomLeftX, cb.BottomRightX });
|
||||
var allCellY = _currentData.CellBoundaries.SelectMany(cb => new[] { cb.TopLeftY, cb.TopRightY, cb.BottomLeftY, cb.BottomRightY });
|
||||
|
||||
minX = Math.Min(minX, allCellX.Min());
|
||||
minY = Math.Min(minY, allCellY.Min());
|
||||
maxX = Math.Max(maxX, allCellX.Max());
|
||||
maxY = Math.Max(maxY, allCellY.Max());
|
||||
}
|
||||
|
||||
return (minX, minY, maxX, maxY);
|
||||
}
|
||||
|
||||
private Point TransformPoint(double x, double y)
|
||||
{
|
||||
var bounds = CalculateBounds();
|
||||
if (bounds == null) return new Point(0, 0);
|
||||
|
||||
var (minX, minY, maxX, maxY) = bounds.Value;
|
||||
|
||||
// CAD 좌표계 -> WPF 좌표계 변환 (Y축 뒤집기)
|
||||
var transformedX = (x - minX) * _scale + MARGIN;
|
||||
var transformedY = cnvVisualization.Height - ((y - minY) * _scale + MARGIN);
|
||||
|
||||
return new Point(transformedX, transformedY);
|
||||
}
|
||||
|
||||
private void DrawNoteBounds(double minX, double minY, double maxX, double maxY)
|
||||
{
|
||||
var topLeft = TransformPoint(minX, maxY);
|
||||
var bottomRight = TransformPoint(maxX, minY);
|
||||
|
||||
var rect = new Rectangle
|
||||
{
|
||||
Width = bottomRight.X - topLeft.X,
|
||||
Height = bottomRight.Y - topLeft.Y,
|
||||
Stroke = Brushes.Red,
|
||||
StrokeThickness = 2,
|
||||
StrokeDashArray = new DoubleCollection { 5, 5 },
|
||||
Fill = null
|
||||
};
|
||||
|
||||
Canvas.SetLeft(rect, topLeft.X);
|
||||
Canvas.SetTop(rect, topLeft.Y);
|
||||
cnvVisualization.Children.Add(rect);
|
||||
}
|
||||
|
||||
private void DrawSegments()
|
||||
{
|
||||
if (_currentData == null) return;
|
||||
foreach (var segment in _currentData.TableSegments)
|
||||
{
|
||||
var startPoint = TransformPoint(segment.StartX, segment.StartY);
|
||||
var endPoint = TransformPoint(segment.EndX, segment.EndY);
|
||||
|
||||
var line = new Line
|
||||
{
|
||||
X1 = startPoint.X,
|
||||
Y1 = startPoint.Y,
|
||||
X2 = endPoint.X,
|
||||
Y2 = endPoint.Y,
|
||||
Stroke = segment.IsHorizontal ? Brushes.Blue : Brushes.Green,
|
||||
StrokeThickness = 1
|
||||
};
|
||||
|
||||
cnvVisualization.Children.Add(line);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawCells()
|
||||
{
|
||||
if (_currentData == null) return;
|
||||
var colors = new[] { Brushes.Red, Brushes.Blue, Brushes.Green, Brushes.Purple, Brushes.Orange };
|
||||
|
||||
for (int i = 0; i < _currentData.Cells.Count; i++)
|
||||
{
|
||||
var cell = _currentData.Cells[i];
|
||||
var topLeft = TransformPoint(cell.MinX, cell.MaxY);
|
||||
var bottomRight = TransformPoint(cell.MaxX, cell.MinY);
|
||||
|
||||
var rect = new Rectangle
|
||||
{
|
||||
Width = bottomRight.X - topLeft.X,
|
||||
Height = bottomRight.Y - topLeft.Y,
|
||||
Stroke = colors[i % colors.Length],
|
||||
StrokeThickness = 2,
|
||||
Fill = null
|
||||
};
|
||||
|
||||
Canvas.SetLeft(rect, topLeft.X);
|
||||
Canvas.SetTop(rect, topLeft.Y);
|
||||
cnvVisualization.Children.Add(rect);
|
||||
|
||||
// 셀 번호 표시
|
||||
var label = new TextBlock
|
||||
{
|
||||
Text = $"R{cell.Row}C{cell.Column}", // 이미 1-based 인덱싱 적용됨
|
||||
FontSize = 8, // 폰트 크기 조정
|
||||
Foreground = colors[i % colors.Length],
|
||||
FontWeight = FontWeights.Bold
|
||||
};
|
||||
|
||||
Canvas.SetLeft(label, topLeft.X + 2); // 좌상단에 위치 + 약간의 패딩
|
||||
Canvas.SetTop(label, topLeft.Y + 2); // 좌상단에 위치 + 약간의 패딩
|
||||
cnvVisualization.Children.Add(label);
|
||||
|
||||
// 셀 텍스트 표시
|
||||
if (!string.IsNullOrEmpty(cell.Text))
|
||||
{
|
||||
var textLabel = new TextBlock
|
||||
{
|
||||
Text = cell.Text,
|
||||
FontSize = 8,
|
||||
Foreground = Brushes.Black,
|
||||
Background = Brushes.LightYellow
|
||||
};
|
||||
|
||||
// 셀 텍스트는 셀 중앙에 표시
|
||||
var centerPoint = TransformPoint(cell.CenterX, cell.CenterY);
|
||||
Canvas.SetLeft(textLabel, centerPoint.X - (textLabel.ActualWidth / 2)); // 텍스트 중앙 정렬
|
||||
Canvas.SetTop(textLabel, centerPoint.Y - (textLabel.ActualHeight / 2)); // 텍스트 중앙 정렬
|
||||
cnvVisualization.Children.Add(textLabel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawCellBoundaries()
|
||||
{
|
||||
if (_currentData == null || _currentData.CellBoundaries == null) return;
|
||||
|
||||
for (int i = 0; i < _currentData.CellBoundaries.Count; i++)
|
||||
{
|
||||
var cellBoundary = _currentData.CellBoundaries[i];
|
||||
|
||||
// 4개 모서리 좌표 변환
|
||||
var topLeft = TransformPoint(cellBoundary.TopLeftX, cellBoundary.TopLeftY);
|
||||
var topRight = TransformPoint(cellBoundary.TopRightX, cellBoundary.TopRightY);
|
||||
var bottomLeft = TransformPoint(cellBoundary.BottomLeftX, cellBoundary.BottomLeftY);
|
||||
var bottomRight = TransformPoint(cellBoundary.BottomRightX, cellBoundary.BottomRightY);
|
||||
|
||||
// 셀 경계를 Path로 그리기 (정확한 4개 모서리 연결)
|
||||
var pathGeometry = new PathGeometry();
|
||||
var pathFigure = new PathFigure();
|
||||
pathFigure.StartPoint = topLeft;
|
||||
pathFigure.Segments.Add(new LineSegment(topRight, true));
|
||||
pathFigure.Segments.Add(new LineSegment(bottomRight, true));
|
||||
pathFigure.Segments.Add(new LineSegment(bottomLeft, true));
|
||||
pathFigure.IsClosed = true;
|
||||
pathGeometry.Figures.Add(pathFigure);
|
||||
|
||||
var path = new Path
|
||||
{
|
||||
Data = pathGeometry,
|
||||
Stroke = Brushes.DarkBlue,
|
||||
StrokeThickness = 3,
|
||||
Fill = null
|
||||
};
|
||||
|
||||
cnvVisualization.Children.Add(path);
|
||||
|
||||
// 라벨 표시 (셀 중앙)
|
||||
if (!string.IsNullOrEmpty(cellBoundary.Label))
|
||||
{
|
||||
var centerX = (topLeft.X + bottomRight.X) / 2;
|
||||
var centerY = (topLeft.Y + bottomRight.Y) / 2;
|
||||
|
||||
var label = new TextBlock
|
||||
{
|
||||
Text = cellBoundary.Label,
|
||||
FontSize = 10,
|
||||
Foreground = Brushes.DarkBlue,
|
||||
FontWeight = FontWeights.Bold,
|
||||
Background = Brushes.LightCyan
|
||||
};
|
||||
|
||||
Canvas.SetLeft(label, centerX - 15); // 대략적인 중앙 정렬
|
||||
Canvas.SetTop(label, centerY - 6);
|
||||
cnvVisualization.Children.Add(label);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawTexts()
|
||||
{
|
||||
if (_currentData == null) return;
|
||||
foreach (var text in _currentData.TextEntities)
|
||||
{
|
||||
var point = TransformPoint(text.X, text.Y);
|
||||
|
||||
var textBlock = new TextBlock
|
||||
{
|
||||
Text = text.Text,
|
||||
FontSize = 9,
|
||||
Foreground = text.IsInTable ? Brushes.DarkBlue : Brushes.Gray
|
||||
};
|
||||
|
||||
Canvas.SetLeft(textBlock, point.X);
|
||||
Canvas.SetTop(textBlock, point.Y);
|
||||
cnvVisualization.Children.Add(textBlock);
|
||||
|
||||
// 텍스트 위치 점 표시
|
||||
var dot = new Ellipse
|
||||
{
|
||||
Width = 3,
|
||||
Height = 3,
|
||||
Fill = text.IsInTable ? Brushes.Blue : Brushes.Gray
|
||||
};
|
||||
|
||||
Canvas.SetLeft(dot, point.X - 1.5);
|
||||
Canvas.SetTop(dot, point.Y - 1.5);
|
||||
cnvVisualization.Children.Add(dot);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawIntersections()
|
||||
{
|
||||
if (_currentData == null) return;
|
||||
foreach (var intersection in _currentData.IntersectionPoints)
|
||||
{
|
||||
var point = TransformPoint(intersection.X, intersection.Y);
|
||||
|
||||
// 교차점 원 표시
|
||||
var circle = new Ellipse
|
||||
{
|
||||
Width = 8,
|
||||
Height = 8,
|
||||
Fill = GetIntersectionColor(intersection),
|
||||
Stroke = Brushes.Black,
|
||||
StrokeThickness = 1
|
||||
};
|
||||
|
||||
Canvas.SetLeft(circle, point.X - 4);
|
||||
Canvas.SetTop(circle, point.Y - 4);
|
||||
cnvVisualization.Children.Add(circle);
|
||||
|
||||
// 교차점 타입 숫자 표시 (우측에)
|
||||
var numberLabel = new TextBlock
|
||||
{
|
||||
Text = intersection.DirectionBits.ToString(),
|
||||
FontSize = 12,
|
||||
FontWeight = FontWeights.Bold,
|
||||
Foreground = Brushes.Black,
|
||||
Background = Brushes.Yellow,
|
||||
Padding = new Thickness(2)
|
||||
};
|
||||
|
||||
Canvas.SetLeft(numberLabel, point.X + 8); // 교차점 우측에 표시
|
||||
Canvas.SetTop(numberLabel, point.Y - 6); // 약간 위쪽으로 조정
|
||||
cnvVisualization.Children.Add(numberLabel);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawDiagonals()
|
||||
{
|
||||
if (_currentData == null) return;
|
||||
foreach (var diagonal in _currentData.DiagonalLines)
|
||||
{
|
||||
var startPoint = TransformPoint(diagonal.StartX, diagonal.StartY);
|
||||
var endPoint = TransformPoint(diagonal.EndX, diagonal.EndY);
|
||||
|
||||
// 대각선 표시
|
||||
var line = new Line
|
||||
{
|
||||
X1 = startPoint.X,
|
||||
Y1 = startPoint.Y,
|
||||
X2 = endPoint.X,
|
||||
Y2 = endPoint.Y,
|
||||
Stroke = Brushes.Green,
|
||||
StrokeThickness = 2,
|
||||
StrokeDashArray = new DoubleCollection { 5, 3 } // 점선으로 표시
|
||||
};
|
||||
cnvVisualization.Children.Add(line);
|
||||
|
||||
// 대각선 중앙에 라벨 표시
|
||||
if (!string.IsNullOrEmpty(diagonal.Label))
|
||||
{
|
||||
var centerX = (startPoint.X + endPoint.X) / 2;
|
||||
var centerY = (startPoint.Y + endPoint.Y) / 2;
|
||||
|
||||
var label = new TextBlock
|
||||
{
|
||||
Text = diagonal.Label,
|
||||
FontSize = 9,
|
||||
FontWeight = FontWeights.Bold,
|
||||
Foreground = Brushes.Green,
|
||||
Background = Brushes.White
|
||||
};
|
||||
Canvas.SetLeft(label, centerX - 20); // 중앙에서 약간 왼쪽으로
|
||||
Canvas.SetTop(label, centerY - 10); // 중앙에서 약간 위쪽으로
|
||||
cnvVisualization.Children.Add(label);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private System.Windows.Media.Brush GetIntersectionColor(IntersectionInfo intersection)
|
||||
{
|
||||
if (intersection.IsTopLeft && intersection.IsBottomRight)
|
||||
return Brushes.Purple; // 둘 다 가능
|
||||
else if (intersection.IsTopLeft)
|
||||
return Brushes.Green; // topLeft 후보
|
||||
else if (intersection.IsBottomRight)
|
||||
return Brushes.Blue; // bottomRight 후보
|
||||
else
|
||||
return Brushes.Red; // 기타
|
||||
}
|
||||
|
||||
private void RefreshVisualization(object sender, RoutedEventArgs e)
|
||||
{
|
||||
RefreshVisualization();
|
||||
}
|
||||
|
||||
private void BtnZoomFit_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
svViewer.Reset();
|
||||
}
|
||||
|
||||
private void CnvVisualization_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
var pos = e.GetPosition(cnvVisualization);
|
||||
txtMousePos.Text = $"마우스: ({pos.X:F0}, {pos.Y:F0})";
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user