J'ai un PathGeometry (polygone) construit de LineSegments sur un PathFigure et je voudrais m'assurer que c'est Convex. J'ai une méthode utilisant le CrossProduct pour déterminer si la géométrie est convexe, je supposais que je pouvais simplement retourner une liste de points qui la rende concave quand elle est fausse et supprimer ces points pour remplir le polygone mais ça ne fonctionne pas correctement.Quel est un moyen facile de remplir un PathGeometry concave pour être Convex (trouver les sommets concaves et les supprimer)?
Voici le code que j'ai:
public static bool IsConvexPolygon(this IList<Point> polygon, out List<Point> concavePoints)
{
int n = polygon.Count;
List<double> result = new List<double>();
concavePoints = new List<Point>();
for (int i = 0; i < n; i++)
{
result.Add(polygon[i].CrossProduct(polygon[i.RotateNext(n)]));
if (result.Last() < 0.0)
{
concavePoints.Add(polygon[i.RotateNext(n)]);
}
}
return (result.All(d => d >= 0.0));
}
public static double CrossProduct(this Point p1, Point p2)
{
return (p1.X * p2.Y) - (p1.Y * p2.X);
}
public static int RotateNext(this int index, int count)
{
return (index + 1) % count;
}
public static PointCollection ExtractPoints(this Geometry geometry)
{
PointCollection pc = new PointCollection();
if (geometry is LineGeometry)
{
var lg = (LineGeometry)geometry;
pc.Add(lg.StartPoint);
pc.Add(lg.EndPoint);
return pc;
}
else if (geometry is PathGeometry)
{
var pg = (PathGeometry)geometry;
if (pg.Figures.Count > 0)
{
List<Point> points;
if ((pg.Figures[0].Segments.Count > 0) && (pg.Figures[0].Segments[0] is PolyLineSegment))
points = ((PolyLineSegment)pg.Figures[0].Segments[0]).Points.ToList();
else
points = pg.Figures[0].Segments.Select(seg => (seg as LineSegment).Point).ToList();
pc.Add(pg.Figures[0].StartPoint);
foreach (Point p in points)
pc.Add(p);
return pc;
}
}
else if (geometry is RectangleGeometry)
{
var rg = (RectangleGeometry)geometry;
var rect = rg.Rect;
pc.Add(rect.TopLeft);
pc.Add(rect.TopRight);
pc.Add(rect.BottomRight);
pc.Add(rect.BottomLeft);
return pc;
}
return pc;
}
public static Geometry CreateGeometryFromPoints(this List<Point> pts)
{
if (pts.Count < 2)
return null;
PathFigure pFig = new PathFigure() { StartPoint = pts[0] };
for (int i = 1; i < pts.Count; i++)
{
pFig.Segments.Add(new LineSegment(pts[i], true));
}
pFig.IsClosed = true;
PathGeometry pg = new PathGeometry(new List<PathFigure>() { pFig });
return pg;
}
public static Path CreatePolygonFromGeometry(this Geometry geo, Brush fillBrush)
{
Path path = new Path() { Stroke = Brushes.Black, StrokeThickness = 1, Fill = fillBrush };
path.Data = geo;
return path;
}
Et voici où je faire la vérification et la correction du polygone:
List<Point> outstuff;
if (geo1.ExtractPoints().IsConvexPolygon(out outstuff) == false)
{
// Got to fill it in if it's concave
var newpts = geo1.ExtractPoints().Except(outstuff).ToList();
var z = newpts.CreateGeometryFromPoints().CreatePolygonFromGeometry(Brushes.Purple);
z.MouseRightButtonDown += delegate { canvas.Children.Remove(z); };
canvas.Children.Add(z);
}
En fin de compte, je voudrais être en mesure de faire mon Concave géométrie dans un Convex un comme celui-ci:
alt text http://i28.tinypic.com/34zhjzm.png
Alors qu'est-ce qui ne fonctionne pas? Quels résultats obtenez-vous? –