已知四个点的坐标绘制了一条Bezier曲线,请问如何判断任意一点是否在这条曲线上?如何计算这条曲线的长度?(200分)

  • 主题发起人 主题发起人 jilimi
  • 开始时间 开始时间
J

jilimi

Unregistered / Unconfirmed
GUEST, unregistred user!
我正在写一个简单的矢量图绘制软件,现在的问题是我需要根据用户的鼠标点击判断
用户是否选择了这条曲线,另外还要计算这条曲线的长度。
我想如果可用一个方程来表达Bezier曲线,应该可以解决问题,(我就是用 Y=KX+b
来判断直线的)但不知这个方程是什么,还想在此请教各位高手!
 
你可以参考一下图形学的书籍。关于bezier曲线的方程,一般的方法都是用逼近,用
折线来代替曲线。我觉得如果用方程来直接计算,不见得好。因为那样做的代价比较大,
而且也不是一个好的计算机解法。可以试试,用bezier的控制多边形来逼近该bezier曲线,
我觉得只要把控制多边形足够细化,这个方法是可行的。
 
看看我用的算法,不怎么好,反正可以用
TCurvePoint = array [1..4] of TPoint;
function PointOnCurve(const ct:TCurvePoint; pt:TPoint):Bool;
var
ps,pc:TPoint;
i,j,k,count:Integer;
t:Double;
cf:array [1..4] of TFPoint;
begin
Result:=False;
count:= 100; //改变大小可以控制精度
//采用了Casteljau算法来计算曲线上的点
for i:=1 to 4 do
begin
cf.x:=ct.x;
cf.y:=ct.y;
end;
for i:=1 to count do
begin
t:=(i-1)/count;
for j:=1 to 3 do
for k:=1 to 4-j do
begin
cf[k].x:=(1-t)*cf[k].x+t*cf[k+1].x;
cf[k].y:=(1-t)*cf[k].y+t*cf[k+1].y;
end;
pc.x:=Round(cf[1].x);
pc.y:=Round(cf[1].y);
if i=1 then ps:=Point(pc.x, pc.y);
if PointOnLine(ps,pc,pt) then Result:=True;
ps:=Point(pc.x, pc.y);
end;
end;

 
很土但很简单的一个办法:
判断鼠标点击位置的屏幕的颜色是否是你的曲线的颜色!
 
谢谢各位,我的问题已经解决了!
 
后退
顶部