直线算法(50分)

  • 主题发起人 主题发起人 Another_eYes
  • 开始时间 开始时间
A

Another_eYes

Unregistered / Unconfirmed
GUEST, unregistred user!
画一条通过屏幕上两点的直线的最优算法.
 
what's your mean?
不是有直接画直线的函数吗?
 
不明白 :-(
 
也就是lineto的具体算法
 
Hehe, eYes就这样给大家送分?

这里是我以前做的经典的BreshamLine算法和自己的改进PegasusLine
当然常言道:没有最好只有更好,比如就可以从两边一齐划,可以减少
接近一半的计算, eYes如有兴趣可以继续改进

Procedure BreshamLine( X0,Y0,X1,Y1:Integer; Color:Word );
Var
deltaX,deltaY:Integer;
dir,delta:LongInt;
e:Integer;
X,Y:Integer;
Begin
deltaX:=Abs(X1-X0); deltaY:=Abs(Y1-Y0);
If ( deltaX > deltaY ) Then
Begin
Y:=Y0;X:=X0;
e:=2*deltaY-deltaX;
If X1>X0 Then dir:=1 Else dir:=-1;
If Y1>Y0 THen delta:=1 Else delta:=-1;
While (X<>X1) Do
Begin
putpixel(X,Y,Color);
If e>0 Then
Begin
Inc(Y,delta);
Inc(e,2*(deltaY-deltaX));
End
Else Inc(e,2*deltaY);
Inc(X,dir);
End
End
Else
Begin
Y:=Y0;X:=X0;
e:=2*deltaX-deltaY;
If Y1>Y0 Then dir:=1 Else dir:=-1;
If X1>X0 THen delta:=1 Else delta:=-1;
While (Y<>Y1) Do
Begin
putpixel(X,Y,Color);
If e>0 Then
Begin
Inc(X,delta);
Inc(e,2*(deltaX-deltaY));
End
Else Inc(e,2*deltaX);
Inc(Y,dir);
End
End


End;

Procedure PegasusLine( X0,Y0,X1,Y1:Integer; Color:Word );
Var
X, Y, dX, dY, sgn_dX, sgn_dY:Integer;
EXdy, EYdx :LongInt;
Temp1, Temp2, Temp3 :LongInt;
Begin
X:=X0; Y:=Y0; dX:=X1-X0; dY:=Y1-Y0;
If (dX>0)
Then sgn_dX:=1
Else sgn_dX:=-1;
If (dY>0)
Then sgn_dY:=1
Else sgn_dY:=-1;
dX:=dX*sgn_dY;
dY:=dY*sgn_dX;
EXdy:=0; EYdx:=0;
Repeat
PutPixel(X,Y,Color);
Temp1:=Abs(EXdy+dX-EYdx);
Temp2:=Abs(EYdx+dY-EXdy);
Temp3:=Abs(EYdx+dY-EXdy-dX);
If Temp1<Temp2
Then
Begin
Inc(Y,sgn_dY); Inc(EXdy,dX);
If Temp1>Temp3 Then
Begin
Inc(X,sgn_dX); Inc(EYdx,dY);
End
End
Else
Begin
Inc(X,sgn_dx); Inc(EYdx,dY);
If Temp2>Temp3 Then
Begin
Inc(Y,sgn_dY); Inc(EXdy,dX);
End
End
Until (X=X1) and (Y=Y1);
End;

 
pega, 多谢多谢.
能者多劳, 另搭一道题(分先欠着):
文字放大的算法(所有笔画原地变胖, 不是stretch).

eYes只想到一个笨算法:

for 半径 := 1 to 放大倍数 do
相同文字在原文字周围绕行360度, 记录下新的图形

可有更好的算法?
 
这种放大算法可行吗?

这样放大后大概所有文字都成一块黑黑的东东了 :)

好的放大效果只能从矢量字体上面来,如果没有矢量字体,
就只能用stretch了.
 
lhz, 黑黑的一块没关系. 我要的就是这黑黑的一块呀(做mask用)
 
原地变胖?

图像算法中好像有一个叫做膨胀的算法就是干这种事情的,等我明天搬好宿舍把我的图像算法书找出来
 
//haha
我整想说膨胀来着.
那种东东叫做形态学,玄乎乎的.

膨胀算法其实很简单:如果某个象素是白象素(假设黑底白字),
就把这个象素周围3X3的区域都填成白象素.

相对应的腐蚀算法就困难一点了.(我也不会,不过有师兄的
source code用 :)
 
wo, lhz是专家,那么就能者多劳,我也在这里学一些,:)

BTW, 上次那个Switch的问题是不是就是因为Switch不适于做广播?
 
专家不敢当, 只是混碗饭吃 :)

关于那个Switch,估计我要换100M的共享式HUB了:(
反正对client/server来说,Switch的价值已经大打
折扣.将来瘦客户机发展起来,昂贵的Switch估计就
要提出市场了.
 
lhz, 3*3不够. 超过10的话边界就起棱角了.另有什么高招吗?
我原来想过用region. 生成原图的region. 然后取得region的数据, 一个一个放大其中的rect
(用roundrect放大), 再生成新图. 不过效率是否太低?
(bitmap->region->rects->bitmap)
 
//haha
3X3不够,可以多来几次嘛,多来几次就大了.每
次都可以扩大一圈.当然可以用更大的MASK,如
5X5,7X7,但这样效果不好,在转角处会出现方块.
多来几次3X3就要好一些,边缘会圆滑一点点.
 
那效率还没我的region效率高呢
 
pega, lhz, menxin诸位大狭, 关于第二题可有什么好的建议没?
有的话我再开一题. 没有的话我也就不花那分数了.
本题50归pega了.
 
我建议先用取边界的算法,然后对边界各点运用lhz的膨胀算法,再继续扩大
或者直接用10x10的圆形覆盖原先的点应该不错,:)
 
多人接受答案了。
 
接受了?
10x10的圆形覆盖原来的点应该既快又圆滑吧?

对了,应该是是直径为11的圆形
 
后退
顶部