我想将贝塞尔曲线分成两部分。例如,如果点(100,100)和(200,100)与控制点(150,150)和(175,150)之间存在贝塞尔曲线,则曲线应以两种不同颜色(例如红色和绿色)着色,一个颜色从(100,100)到(150,100)表示红色,另一种颜色从(150,100)到(200,100)表示绿色。
这是我绘制bezier样条曲线的代码:
void Form1_Paint(object sender, PaintEventArgs e)
{
Point startPoint = new Point(100, 100);
Point endPoint = new Point(200, 100);
Point ctPoint1 = new Point(150, 150);
Point ctPoint2 = new Point(175, 150);
GraphicsPath gp = new GraphicsPath();
gp.AddLine(new Point(100, 0), new Point(100, 100));
gp.AddBezier(startPoint, ctPoint1, ctPoint2, endPoint);
gp.AddLine(new Point(200, 100), new Point(200, 0));
gp.AddLine(new Point(100, 0), new Point(200, 0));
e.Graphics.FillPath(Brushes.Aqua, gp);
}
我想用两种颜色填充它,就像我上面解释的那样。
期望的结果:
我怎样才能实现这个目标
编辑:
我已经检查了一些用于分割贝塞尔曲线enter link description here的链接,但它告诉我找到曲线的中点而不是我的情景,我正在寻找绘制半贝塞尔曲线。
已知值:两点及其控制点在两点之间绘制贝塞尔曲线
预期结果:从起点到中点绘制贝塞尔曲线的一部分,从中点到终点绘制另一部分。
答案 0 :(得分:1)
如果你脑海中贝塞尔曲线的“中点”实际上是贝塞尔曲线上x = 150的点,那么仍然可以通过分析计算它。由于贝塞尔曲线仅为3阶,我们可以计算对应于中点的参数't'(例如,使用Cardano公式)。获得中点参数后,可以使用de Cateljau算法查找两条分割曲线的控制点。将两条分割曲线作为贝塞尔曲线后,可以根据需要绘制两个区域。
以下是分割曲线的结果控制点:
第一条分割曲线:(100,100)(120.196418101,120.196418101),(136.313883161,132.234930120)和(150.000000000,136.115536056)。
第二条分割曲线:(150.000000000,136.115536056),(170.196418101,141.842093918),(185.098209050,129.803581899)和(200,100)。
顺便说一句,“中点”的参数t约为0.403928。
对于具有控制点P0,P1,P2和p3的三次贝塞尔曲线,给定分裂参数t,分裂曲线的控制点计算如下(使用De Casteljau算法)
1)将Q0,Q1和Q2计算为
Q0 =(1-t)* P0 + t * P1
Q1 =(1-t)* P1 + t * P2
Q2 =(1-t)* P2 + t * P3
2)将R0和R1计算为
R0 =(1-t)* Q0 + t * Q1
R1 =(1-t)* Q1 + t * Q2
3)将S0计算为S0 =(1-t)* R0 + t * R1。这将是曲线上的分割点
4)第一个分割曲线的控制点是P0,Q0,R0和S0,第二个分割曲线的控制点是S0,R1,Q2和P3。
答案 1 :(得分:-1)
我使用了Region.Exclude
方法和GraphicsPath.GetBounds
方法
代码:
//Creating graphics path for drawing bezier spline
GraphicsPath gp = new GraphicsPath();
gp.AddLine(new Point(100, 0), new Point(100, 100));
gp.AddBezier(startPoint, ctPoint1, ctPoint2, endPoint);
gp.AddLine(new Point(200, 100), new Point(200, 0));
gp.AddLine(new Point(100, 0), new Point(200, 0));
//Dividing the path into two regions
Rectangle bounds=Rectangle.Round(gp.GetBounds());
Region left = new Region(gp);
left.Exclude(new Rectangle(bounds.Left, bounds.Top, (int)(bounds.Width / 2), bounds.Height));
Region right = new Region(gp);
right.Exclude(new Rectangle((int)(bounds.Left + bounds.Width / 2), bounds.Top, (int)(bounds.Width / 2), bounds.Height));
//Drawing divided regions
e.Graphics.FillRegion(Brushes.Black, left);
e.Graphics.FillRegion(Brushes.Aqua, right);
说明:
e.Graphics.FillRegion
方法填充贝塞尔曲线的所需部分