我正在尝试创建一个看起来像这样的栏:
http://img4.hostingpics.net/pics/530160commandBar.png
这是一个包含由发光分隔符分隔的按钮的栏。那些按钮有一个非矩形的形状,所以我想“我只是放一个透明的按钮,并绘制非矩形的形状,我将使用一个路径”。
我遇到的问题是我需要根据状态(启用,禁用)为按钮着色,因此我需要每个按钮的路径来轻松更改颜色。
所以我做了一个函数来计算4个点的Bézier曲线和一个T值,它代表曲线上0到1之间的点(0是曲线的起点,1是终点,0.5是曲线中间的点。)
public static Point CalculateBezierPoint(double t, Point p1, Point p2, Point p3, Point p4) {
Point p = new Point();
double tPower3 = t * t * t;
double tPower2 = t * t;
double oneMinusT = 1 - t;
double oneMinusTPower3 = oneMinusT * oneMinusT*oneMinusT;
double oneMinusTPower2 = oneMinusT * oneMinusT;
p.X = oneMinusTPower3 * p1.X + (3 * oneMinusTPower2 * t * p2.X) + (3 * oneMinusT * tPower2 * p3.X) + tPower3 * p4.X;
p.Y = oneMinusTPower3 * p1.Y + (3 * oneMinusTPower2 * t * p2.Y) + (3 * oneMinusT * tPower2 * p3.Y) + tPower3 * p4.Y;
return p;
}
此功能运作良好。
所以我可以绘制曲线:
http://img4.hostingpics.net/pics/417674myCommandBar1.png
所以这很准确。除了按钮宽度不相等(它们应该由分隔符分隔)。所以我需要的是一个函数,可以在知道X轴值的情况下找到曲线上点的Y轴值。
因此知道在Bézier曲线上找到一个点的等式是:
(x坐标)
Bx(t)=(1-t)^ 3 * P1.x + 3 *(1-t)^ 2 * t * P2.X + 3 *(1-t)* t ^ 2 * P3。 X + t ^ 3 * P4.X
(y坐标)
By(t)=(1-t)^ 3 * P1.Y + 3 *(1-t)^ 2 * t * P2.Y + 3 *(1-t)* t ^ 2 * P3。 Y + t ^ 3 * P4.Y
其中:
我认为我可以根据t解析Bx(t)方程,因为我在运行时知道Bx,P1,P2,P3和P4,只有t是未知的。所以我想要一个看起来像这样的等式:
t = ...
这是一个好主意,直到我记得我在数学方面很糟糕。我尝试了许多不起作用的东西,然后尝试在Wolframalpha中输入等式,这给了我一个〜50长线方程式无法工作(here如果你想看到它()我可能在错误中重复了它。)
无论如何,我在这里寻求帮助。谢谢你的帮助
答案 0 :(得分:0)
那么,如果你的曲线实际上是一个函数y = f(x),为什么不用那种方式来表示,X只是一个线性参数?
/// <summary>
/// Calculate a bezier height Y of a parameter in the range [start..end]
/// </summary>
public static double CalculateBezierHeightInInterval(double start, double end, double param, double y1, double y2, double y3, double y4)
{
return CalculateBezierHeight((param - start) / (end - start), y1, y2, y3, y4);
}
/// <summary>
/// Calculate a bezier height Y of a parameter in the range [0..1]
/// </summary>
public static double CalculateBezierHeight(double t, double y1, double y2, double y3, double y4)
{
double tPower3 = t * t * t;
double tPower2 = t * t;
double oneMinusT = 1 - t;
double oneMinusTPower3 = oneMinusT * oneMinusT * oneMinusT;
double oneMinusTPower2 = oneMinusT * oneMinusT;
double Y = oneMinusTPower3 * y1 + (3 * oneMinusTPower2 * t * y2) + (3 * oneMinusT * tPower2 * y3) + tPower3 * y4;
return Y;
}
在此公式中,您不再需要求解X,因为X是Y的输入。另一方面,假设样本高度以均匀的X间隔出现,这对您来说可能是不合适的。
如果您需要通过控制控制点的X位置来获得额外的形状控制,可以使用此处的方法:y coordinate for a given x cubic bezier