如何通过交叉线段分割Pathgeometry多边形
-
12-09-2020 - |
题
我有一个我从一堆亚莱门店建造的路面测量学,我想将其分成两个分析术语,除以几何形状中间交叉的线。这是我的意思这幅画:
http://i30.tinypic.com/2noyvm.png
我可以通过LineSegments并创建一个简单行对象数组(简单对象W / A点,Point2属性,使其代表一行)。但是,我需要以某种方式确定哪条线在交叉线的一端,哪条线在交叉线的另一端...
解决方案
嗯,那很有趣,这是我所做的(老实说,如果这是一个更有效的方式,那么如果这是“正确”的方式)。
- 创建一个移动几何形状的变换,使分隔线位于y轴上。
- 在几何中的每行 - 如果x <0它在左边,如果x> 0它在右侧,如果线路交叉y轴将其划分为两行。
- 使用从步骤1的变换的逆转录和从它们重建几何图形的逆之间转换两条线。
这是一种分体式方法,它采用几何和由两个点定义的线路,并返回两个几何形状:
private void SplitGeometry(Geometry geo, Point pt1, Point pt2, out PathGeometry leftGeo, out PathGeometry rightGeo)
{
double c = 360.0 + 90.0 - (180.0 / Math.PI * Math.Atan2(pt2.Y - pt1.Y, pt2.X - pt1.X));
var t = new TransformGroup();
t.Children.Add(new TranslateTransform(-pt1.X, -pt1.Y));
t.Children.Add(new RotateTransform(c));
var i = t.Inverse;
leftGeo = new PathGeometry();
rightGeo = new PathGeometry();
foreach (var figure in geo.GetFlattenedPathGeometry().Figures)
{
var left = new List<Point>();
var right = new List<Point>();
var lastPt = t.Transform(figure.StartPoint);
foreach (PolyLineSegment segment in figure.Segments)
{
foreach (var currentPtOrig in segment.Points)
{
var currentPt = t.Transform(currentPtOrig);
ProcessLine(lastPt, currentPt, left, right);
lastPt = currentPt;
}
}
ProcessFigure(left, i, leftGeo);
ProcessFigure(right, i, rightGeo);
}
}
private void ProcessFigure(List<Point> points, GeneralTransform transform, PathGeometry geometry)
{
if (points.Count == 0) return;
var result = new PolyLineSegment();
var prev = points[0];
for (int i = 1; i < points.Count; ++i)
{
var current = points[i];
if (current == prev) continue;
result.Points.Add(transform.Transform(current));
prev = current;
}
if (result.Points.Count == 0) return;
geometry.Figures.Add(new PathFigure(transform.Transform(points[0]), new PathSegment[] { result }, true));
}
private void ProcessLine(Point pt1, Point pt2, List<Point> left, List<Point> right)
{
if (pt1.X >= 0 && pt2.X >= 0)
{
right.Add(pt1);
right.Add(pt2);
}
else if (pt1.X < 0 && pt2.X < 0)
{
left.Add(pt1);
left.Add(pt2);
}
else if (pt1.X < 0)
{
double c = (Math.Abs(pt1.X) * Math.Abs(pt2.Y - pt1.Y)) / Math.Abs(pt2.X - pt1.X);
double y = pt1.Y + c * Math.Sign(pt2.Y - pt1.Y);
var p = new Point(0, y);
left.Add(pt1);
left.Add(p);
right.Add(p);
right.Add(pt2);
}
else
{
double c = (Math.Abs(pt1.X) * Math.Abs(pt2.Y - pt1.Y)) / Math.Abs(pt2.X - pt1.X);
double y = pt1.Y + c * Math.Sign(pt2.Y - pt1.Y);
var p = new Point(0, y);
right.Add(pt1);
right.Add(p);
left.Add(p);
left.Add(pt2);
}
}
.其他提示
弄清楚哪条线在交叉线的哪一侧是计算相对于交叉线的线端点的确定性的符号。阳性是一方,负是另一方。
如果您希望有更复杂的十字路口,例如,在线段内的内部,则需要构建双向边缘和顶点的图形,并计算交叉线和每个多边形边缘的交叉点。然后,您将线路与边缘相交的顶点并回溯图表,根据您的指示边构建多边形,按照您遵循另一个。
如果您正在寻找此实现,请签出 net拓扑套件,其中主要用于GIS,也可用于这样的一般计算 - 几何问题。
不隶属于 StackOverflow