2016-10-28 4 views
0

Я создаю плагин autocad, который получает точки из существующей геометрии, передает его в другие окна и создает объект с той же геометрией на холсте, что и полилиния. Объект Autocad является полилинией, поэтому некоторые точки (вершины) должны быть перегружены.Полилинии, расширенные на холсте при перетаскивании с использованием PointCollection C# WPF

Points in autocad

Я собираю точки из AutoCAD, длиной вершин и преобразования, в центре объекта в реальных координатах на холсте. Затем, когда я рисую его, я получаю это:

enter image description here

Точки, которые я собираю правильны, они трансформируются simetrically. А код для рисования на холсте здесь:

private void drawOnCanvas(List<Point> points) 
    { 
     // Create a black Brush 
     SolidColorBrush blackBrush = new SolidColorBrush(); 
     blackBrush.Color = Colors.Black; 

     // Create a polyline 
     Polyline poly = new Polyline(); 
     poly.Stroke = blackBrush; 
     poly.StrokeThickness = 4; 

     // Create a collection of points for a polyline 
     PointCollection polygonPoints = new PointCollection(); 
     for (int i = 0; i < points.Count-1; i++) 
     { 
      polygonPoints.Add(points[i]); 
     } 

     // Set Polyline.Points properties 
     poly.Points = polygonPoints; 

     // Add polyline to the page 
     canvas.Children.Add(poly); 
    } 

Когда я вхожу отладчик, точки отображаются так:

enter image description here

Как вы видите, точки определяются в правильном направлении.

private void canvas_MouseMove(object sender, MouseEventArgs e) 
    { 
     Point p = Mouse.GetPosition(canvas); 
     coords.Content = p.ToString(); 
    } 

Когда я читаю координаты с mouseMove, удлиненная сторона длиннее примерно на половину длины (50/2).

Почему это происходит и как решить эту проблему?

Обновлено Решение:

for (int i = 0; i < points.Count - 1; i += 2) 
       { 
        pathGeometry = pathGeometry + "M" + points[i].X.ToString("F2") + " " + points[i].Y.ToString("F2") + " " + "L" + points[i + 1].X.ToString("F2") + " " + points[i + 1].Y.ToString("F2") + " "; 
       } 

       canvas.Children.Add(new Path { Stroke = Brushes.Brown, StrokeThickness = 3, Data = Geometry.Parse(pathGeometry) }); 

Обновлено Решение 2: (Бетер раствор)

PathFigure figures = new PathFigure(); 
figures.StartPoint = points[0]; 
points.RemoveAt(0); 
figures.Segments = new PathSegmentCollection(points.Select((p, i) => new LineSegment(p, i % 2 == 0))); 
PathGeometry pg = new PathGeometry(); 
pg.Figures.Add(figures); 
canvas.Children.Add(new Path { Stroke = Brushes.Brown, StrokeThickness = 3, Data = pg }); 
+0

двух нот. Вы можете написать 'poly.Stroke = Brushes.Black;' вместо создания нового SolidColorBrush. У PointCollection есть конструктор, который принимает аргумент 'IEnumerable ', поэтому вы можете удалить весь оператор' for' и просто написать 'poly.Points = new PointCollection (points);'. Весь метод может быть записан как 'canvas.Children.Add (новая полилиния {Stroke = Brushes.Black, StrokeThickness = 4, Points = new PointCollection (points)});' – Clemens

+0

спасибо, что указали это, но я могу ' t использовать 'Points = new PointCollection (points)', так как я набираю 1 балл меньше .. см. в моем коде 'for (int i = 0; i dodoria1992

+1

Вы можете написать 'new PointCollection (points.Take (points.Count - 1))'. 'Take' - это метод расширения в' System.Linq.Enumerable'. – Clemens

ответ

0

Я думаю, это потому, что, когда вы поворачиваете из верхней правой точки к верхней средней точке рисунок многоугольника расширяется до фактической точки, чтобы сделать своего рода острую вершину. Но я думаю, что вы рисуете в окне с осью y вниз, поэтому вам придется думать, что мой верхний правый, как нижний rignt :-) Это означает, что это короткие стороны, которые правы.

Решение состоит в том, чтобы использовать различные линии или PathGeometry:

<Path Data="M10 5 L60 5 M35 5 L35 65 M10 65 L60 65" Stroke="Black" StrokeThickness="5" /> 

Обновление:

Со ссылкой на первый рисунок выше, он фактически обращается в этой последовательности: 5-6- 4-3-1-2. (поскольку ось y направлена ​​вниз).

Если вы вставляете две фигуры внизу в холст, вы увидите разницу между рендерингом полилинии и дорожкой. Если вы измените значение 20 на другое значение в полилинии, вы увидите эффект рендеринга (для каждого проекта) полилинии - по сравнению с Path. Мои точки как в полилинии, так и в пути произвольны, вы должны использовать вместо этого свои точки ACad.

<Polyline Name="Poly" Points="10 5, 60 5, 35, 20 35, 65, 10, 65 60, 65" Stroke="Blue" StrokeThickness="5"> 
</Polyline> 

<Path Name="MyPath" Data="M10 5 L60 5 M35 5 L35 65 M10 65 L60 65" Stroke="Black" StrokeThickness="5"> 
    <Path.RenderTransform> 
    <TranslateTransform X="0" Y="100" /> 
    </Path.RenderTransform> 
</Path> 

Если вы хотите получить больше информации о пути, пожалуйста, смотрите here.

Update 2:

В коде позади может быть весьма запутанна, чтобы построить данных Пути в виде строки. Вместо этого вы можете использовать соответствующие типы:

PathFigure figures = new PathFigure(new Point(10, 5), 
    new PathSegment[] 
    { 
     new LineSegment(new Point(60,5), true), 
     new LineSegment(new Point(35,5), false), 
     new LineSegment(new Point(35,65), true), 
     new LineSegment(new Point(10,65), false), 
     new LineSegment(new Point(60,65), true), 
    }, false); 

    PathGeometry pg = new PathGeometry(); 
    pg.Figures.Add(figures); 
    MyPath.Data = pg; 

Или это может быть сделано из последовательности точек:

Point[] points = 
    { 
    new Point(60, 5), 
    new Point(35, 5), 
    new Point(35, 65), 
    new Point(10, 65), 
    new Point(60, 65), 
    }; 

    PathFigure figures = new PathFigure(); 
    figures.StartPoint = new Point(10, 5); 
    figures.Segments = new PathSegmentCollection(points.Select((p, i) => new LineSegment(p, i % 2 == 0))); 
    PathGeometry pg = new PathGeometry(); 
    pg.Figures.Add(figures); 
    MyPath.Data = pg; 

выше делает то же самое, как Data-строки в MyPath.

В обоих случаях вам необходимо знать, какой тип формы точки представляют собой, таким образом Вы можете установить isStroked соответственно, или, возможно, использовать другие типы segmens как дуг и т.д.

+0

На самом деле, я не понимаю, как это сделать .. можно ли объяснить более подробную информацию о данных пути? – dodoria1992

+0

@ dodoria1992: Смотрите мое обновление выше. –

+0

спасибо .. теперь я замечаю разницу ... просто нужно выяснить, как преобразовать точки в точки пути. – dodoria1992