Страницы

Поиск по вопросам

понедельник, 24 февраля 2020 г.

Как найти пересечение двух фигур?

#c_sharp #wpf


В Grid есть несколько фигур (производные Shape).
Как получить пересечение двух фигур?   
    


Ответы

Ответ 1



Пересечение фигур можно получить с помощью класса CombinedGeometry. Ниже пример программы, в которой выводится пересечение разных фигур, включая линии. Пересечение вычисляется и выводится при движении мыши. Работает быстро. Для примера, между кадрами анимированного gif установлена задержка 500 миллисекунд. // Microsoft (R) Roslyn C# Compiler version 1.1.0.51204 #r "PresentationFramework" #r "WindowsBase" using System.Windows.Shapes; using System.Windows; using System.Windows.Controls; using System.Windows.Media; // находит пересечение двух фигур, включая линии/отрезки static CombinedGeometry RenderedIntersect(Visual ctx, Shape s1, Shape s2) { var p = new Pen(Brushes.Transparent, 0.01); var t1 = s1.TransformToAncestor(ctx) as Transform; var t2 = s2.TransformToAncestor(ctx) as Transform; var g1 = s1.RenderedGeometry; var g2 = s2.RenderedGeometry; if (s1 is Line) g1 = g1.GetWidenedPathGeometry(p); if (s2 is Line) g2 = g2.GetWidenedPathGeometry(p); g1.Transform = t1; g2.Transform = t2; return new CombinedGeometry(GeometryCombineMode.Intersect, g1, g2); } // UI для демонстрации использования RenderedIntersect var grid = new Grid(); grid.Children.Add(new Line { X1=50, Y1=5, X2=140, Y2=140, Stroke=Brushes.Silver }); grid.Children.Add(new Line { X1=20, Y1=110, X2=270, Y2=50, Stroke=Brushes.Silver }); grid.Children.Add(new Ellipse { Stroke=Brushes.Silver, Width=120, Height=60 }); var g = Geometry.Parse("M200.86114,56.658088 L21.55462,90.649919 114.93742,121.69634 z"); grid.Children.Add(new Path { Stroke = Brushes.Silver, Data = g }); var wnd = new Window() { Width = 300, Height = 200, Content = grid }; // функция выбора двух фигур Shape p = null; var nextPair = new Func(() => { var shapes = grid.Children.OfType(); var arr = (from s1 in shapes from s2 in shapes where s1 != s2 select new[] { s1, s2 }).ToArray(); var rnd = new Random(); return arr[rnd.Next(0, arr.Length)]; }); // выводим пересечение фигур при движении мыши var m = 0; wnd.MouseMove += (s, e) => { if (p != null) grid.Children.Remove(p); var sa = nextPair(); var g = RenderedIntersect(grid, sa[0], sa[1]); p = new Path() { Stroke = Brushes.Red, StrokeThickness = 2, Data = g }; grid.Children.Add(p); }; wnd.ShowDialog();

Комментариев нет:

Отправить комментарий