【发布时间】:2014-09-10 06:33:20
【问题描述】:
我正在尝试创建一个如下所示的栏:
(来源:hostingpics.net)
这是一个包含由发光分隔符分隔的按钮的栏。这些按钮具有非矩形形状,所以我想“我只需放置一个透明按钮并绘制非矩形形状,我将使用路径”。
我遇到的问题是我需要根据按钮的状态(启用、禁用)为按钮着色,所以我需要每个按钮的路径来轻松更改其颜色。
所以我做了一个函数来计算 4 个点的贝塞尔曲线和一个 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;
}
此功能运行良好。
这样我就可以画出曲线了:
(来源:hostingpics.net)
所以这是非常准确的。除了按钮宽度不相等(它们应该由分隔符分隔)。所以我需要一个函数,它可以知道曲线上的点的 Y 轴值,知道它的 X 轴值。
所以知道在贝塞尔曲线上找到一个点的方程是:
(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
地点:
- Bx是曲线上点的X轴值,By是它的Y轴值;
- P1 是曲线的起点
- P2 是曲线的第一个控制点
- P3 是曲线的第二个控制点
- P4 是曲线的终点
- t 是我们要在曲线上找到的点的 0 和 1 之间的位置
我认为我可以根据 t 求解 Bx(t) 方程,因为我在运行时知道 Bx、P1、P2、P3 和 P4,只有 t 是未知的。所以我想要一个看起来像这样的方程:
t = ...
这是一个好主意,直到我想起我的数学很糟糕。我尝试了很多不起作用的东西,然后尝试在 Wolframalpha 中输入方程,这给了我一个 ~50 行不起作用的长线方程(here 如果你想看的话)(我可能在函数中重新复制它时出错了)。
无论如何,我在这里寻求帮助。谢谢你的帮助
【问题讨论】:
-
你的曲线真的是二维曲线,还是函数 y=f(x)? IE。曲线能否自行循环?
-
@dbc 曲线永远不会循环回来(它是图像中的形状,它可能会弯曲但永远不会改变它的形状)