gpt4 book ai didi

c# - 径向 TreeMap 布局 : fix beizer curves

转载 作者:太空狗 更新时间:2023-10-29 19:46:35 27 4
gpt4 key购买 nike

我想呈现漂亮的径向树布局,但有点被弯曲的边缘绊倒了。问题是源点和目标点之间的角度不同,边缘的绘制方式也不同。提供的图片来自单个图表,因此您可以看到它们在不同边缘方向上有何不同。我认为关键在于 beizer 曲线控制点生成,我只是不明白如何修复它们。

无论边缘的方向如何,我都希望它们以相同的方式绘制。

我怎样才能像图 1 那样实现这个目标?我怎样才能像 Pic2 那样实现这一点?

喜欢这里:https://bl.ocks.org/mbostock/4063550

谢谢!

代码:

//draw using DrawingContext of the DrawingVisual

//gen 2 control points
double dx = target.X - source.X, dy = target.Y - source.Y;
var pts = new[]
{
new Point(source.X + 2*dx/3, source.Y),
new Point(target.X - dx/8, target.Y - dy/8)
};

//get geometry
var geometry = new StreamGeometry { FillRule = FillRule.EvenOdd };
using (var ctx = geometry.Open())
{
ctx.BeginFigure(START_POINT, false /* is filled */, false /* is closed */);
ctx.BezierTo(pts[0], pts[1], END_POINT, true, false);
}
geometry.Freeze();

//draw it
dc.DrawGeometry(DrawingBrush, DrawingPen, geometry);

更新 1:我使用以下公式得到了前一个顶点和源之间的角度(以弧度为单位):Math.Atan2(prev.Y - source.Y, source.X - prev.X);但我仍然得到了如图 4 所示的边缘。

更新 2branchAngle 计算的前一个顶点位置不准确,所以我决定取一个分支中所有边之间的平均角度作为 branchAngle。当一个分支的边缘在 180 度标记附近并且分支的边缘角度可能为 175、176.. -176 时,此方法会失败!我用这段代码让他们都积极:

        var angle =  Math.Atan2(point1.Y - point2.Y, point1.X - point2.X);
while (angle < 0d)
angle += Math.PI*2;

但现在角度可以是 350、359.. 2!!!很难计算平均值 :) 你能告诉我如何解决这个问题吗?

图1 Beizer curve edges - up

图2 Beizer curve edges - left

图3 enter image description here

图4 enter image description here

最佳答案

从您提供的链接中查看图表,树中的每个分支都有自己的角度,用于声明分支的控制点。此 branchAngle 与从第一个节点到前一个节点的矢量之一相同(每个分支可以依次产生多个分支)。第一个分支的角度(第一个节点=前一个节点=中心)似乎在-60°左右。

可以通过补偿树中所有分支的分支角度(0°、-90°、-180°...)来设置曲线类型。生成用于布置控制点的 controlAngle

在考虑角度的同时生成控制点:

//gen per branch
double branchAngle = 30 * Math.PI / 180; //e.g., calc vector angle here
double cosB = Math.Cos(branchAngle);
double sinB = Math.Sin(branchAngle);
//depending on the desired curve compensate -90°, -180°,...
double controlAngle = branchAngle - (90 * Math.PI / 180);
double cosA = Math.Cos(controlAngle);
double sinA = Math.Sin(controlAngle);

//gen 2 control points
//calculate dx dy after rotation with branchAngle
double dxbase = target.X - source.X, dybase = target.Y - source.Y;
double dx = dxbase*sinB - dybase*cosB
double dy = dxbase*cosB + dybase*sinB
//control points based on controlAngle
var pts = new[]
{
new Point(source.X + (2*dx/3)*cosA , source.Y + (2*dx/3)*sinA),
new Point(target.X - (dx/8)*cosA + (dy/8)*sinA, target.Y - (dx/8)*sinA - (dy/8)*cosA)
};

Branch

快速检查分支角 = 30° &补偿 = -90° ->控制角度 = -60°

关于c# - 径向 TreeMap 布局 : fix beizer curves,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39062928/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com