好的,所以我要在这里冒险了。您有节点(A、B、C、D),并且它们之间有线段。这可以被认为是一个 Graph(V,E),它可能比树更适合你。
现在对于 WPF:
您的 Vertex 类将具有 ObservableCollection 类型的 Edges 属性 您的 Vertex 类将具有 Point 类型的 Point 属性。您的 Edge 类将具有 ObservableCollection 类型的 Vertices 属性,该属性将为 2。
您的 ViewModel 将包含您将绑定到的所有边和所有顶点的列表。
您的视图会将您的边缘数据模板化为一条线。在 DataTemplate 中,您将钻入边缘上的两个顶点以获得线的任一端。(你可以为你的顶点使用一个小椭圆。)
现在为数学:
private static Point[] Translate(Point[] points, double tX, double tY)
{
return points.Select(p => new Point(p.X + tX, p.Y + tY)).ToArray();
}
private static Point[] Rotate(Point[] points, double theta)
{
return points.Select(p =>
new Point(p.X * Math.Cos(theta) - p.Y * Math.Sin(theta),
p.X * Math.Sin(theta) + p.Y * Math.Cos(theta)))
.ToArray();
}
public Point[] RotatePointsAroundPoint(Point[] points, Point origin, double theta)
{
var tPoints = Translate(points, -origin.X, -origin.Y);
tPoints = Rotate(tPoints, theta);
return Translate(tPoints, origin.X, origin.Y);
}
public void RotateGraph(Vertex[] vertices, Point origin, double theta)
{
var points = vertices.Select(v => v.Point).ToArray();
var tPoints = RotatePointsAroundPoint(points, origin, theta);
for(var i = 0; i < vertices.Length; i++)
vertices[i].Point = tPoints[i];
}
有了这个,您只需要确定原点和旋转度数。一旦你调用了 setter Vertex.Point
,NotifyPropertyChanged
事件就会更新View
.