怎样用异或方式在canvas上画一条白色线,然后在擦除它?(30分)

  • 主题发起人 主题发起人 SYT
  • 开始时间 开始时间
S

SYT

Unregistered / Unconfirmed
GUEST, unregistred user!
各位朋友:
我用下列语句
Pen.color:=clWhite;
pen.mode:=pmXor;
MoveTo(20,20);
LineTo(200,200);
在画布上不能画出一条白色的直线,不知何原因,
改用
Pen.color:=clWhite;
pen.mode:=pmCopy;
MoveTo(20,20);
LineTo(200,200);
虽然可以画出一条白色线,但又无法将其擦除
请问哪位朋友知道怎样用什么方法将canvas上的一条白色线擦除并不留痕迹?


 
在用底色为颜色将原直线再画一次,不就擦掉了吗!
 
要想使用异或的方式来实现划上然后又擦除,必须保证一点,那就是,
底色是黑的,原因是这样的,如果不是黑的,画上的颜色就不是要得到的颜色,
黑色对应的二进制数各位全是0,这样异或的时候,才能保证,
最终得到的是你想要画的颜色,因为1 xor 0=1,0 xor 0=0,
10101010 xor 00000000=10101010,而10101010 xor 10000000=00101010,
就不是你想画的颜色了.在你的例子中,用xor已经画了一条线,但由于进行异或
的时候颜色发生了变化,你看不见白色的线,用异或的方法是完全可行的

 
To lczhuohuo:
你好!谢谢你解答我的问题,你的思路很新颖。有没有什么办法保证在底色不为
黑色的情况下用异或方式画出一条白色线来?于是我根据你的思路有做了如下的设想
假如背景色为clTeal,这样
Pen.color:=(clWhite XOR clTeal); //得到一种中间色
pen.mode:=pmXor;
MoveTo(20,20);
LineTo(200,200);
之后画出的线应为白色,通过试验结果不是为白色,这是何原因?
 
即使可以也不太通用吧? 如果底色是图片呢?

你干脆自己先保存背景,画线之后在重新draw背景.
 
那是什么颜色?
 
什么"什么颜色"?
 
cAkk:
假如底色不是图片,而是窗体的背景色即form1.color的颜色,可否
满足我的要求.
SYT
 
你保存背景的时候,管他是图片还是不是图片,有什么区别吗?
 
我的意思是你得到了什么颜色,
因为我没办法自己试,我的电脑不能在上网的时候
打开delphi 5
 
我为什么要得到颜色?????????? 我得到颜色干什么???????
莫名其妙!!!
 
要得到颜色,可用canvas.pixel[x,y],根据线长度设一数组保存即可。
 
在画线之前要保存该线所占屏幕的背景是行不通的,我的这副矢量图有数千
条线,因为每条线都有可能被选中而变成高亮,然后在擦除所选对象的可能,因此
就需要保存每条线的背景,这需要多大的内存开销啊!

不知大家有没有用过AutoCAD 14这种软件,该软件可以在屏幕上画出各种
颜色的直线,点击或拖拉即可选中,按下删除键后,所选中的线条就会立刻消失
即擦除,请问这种功能我可否在Delphi的Canvas中实现它.

 
To lczhuohuo:
你好!
假如背景色为clTeal,这样
Pen.color:=(clWhite XOR clTeal); //得到一种中间色
pen.mode:=pmXor;
MoveTo(20,20);
LineTo(200,200);
之后画出的线应为白色,通过试验结果不是为白色,是一条其他颜色的线。
有办法帮我解决这个问题吗?

 
我想通了,xor是不满足交换率的。
你可以这样,首先得到背景颜色,然后直接用背景颜色xor一下,
就得到了黑色,接着再画你想要的颜色。例如:
procedure TForm1.Button1Click(Sender: TObject);
begin
Canvas.Pen.Color:=clTeal ;
Canvas.Pen.Mode:=pmXor;
Canvas.Pen.Width:=10;
Canvas.MoveTo(100,100);
Canvas.LineTo(200,200);
Canvas.Pen.Color:=clWhite;
Canvas.MoveTo(100,100);
Canvas.LineTo(200,200);
end;
对不起,匆忙写的,没有整理,见笑了。
但是要擦去的时候,又要麻烦了!:(你就必须要记得原来的颜色了,
于是乎。。。。这基本上没有什么意义,
AutoCAD不同,它使用画图命令来描述一幅图,删除某一条线,相当于
倒退一个命令,它记得所有的画图命令,这就是CAD的特点了
 
for i=1 to 3000
begin
y=sin(i/180*3.14)*100;
a[i,y] = canvas.pixels[i,y] ;
canvas.pixels[i,y] = clWhite;
end;

这里画了一条白的正玄曲线,要恢复:

for i=1 to 3000
begin
y=sin(i/180*3.14)*100;
a[i,y] = canvas.pixels[i,y];
canvas.pixels[i,y] = a[i,y];
end;


用 xor 不能得到全白的线,因背景不一定是全黑。
 
sorry To that :

要恢复:

for i=1 to 3000
begin
y=sin(i/180*3.14)*100;
canvas.pixels[i,y] = a[i,y];
end;
 
wjs的方法还是不满足SYT的要求,试想若在白线上再画一白线的话,当删除前一白线时,则后一白线则变为其它颜色。而且还占用大量内存。

其实,SYT所处理的是矢量图,想实现类似AutoCAD的功能。

因此解决SYT问题的最好办法就是向AutoCAD学习,创建各种图元类,如点、直线、
圆等,纪录每步绘图数据,绘新图元时直接用pmCopy方式即可,删除时遍历已绘
图元,清画布,重新绘制先前图元即可。

这种方法,即使对于含有数千条线的图形,速度也是很快。
 
你可以试一下
Pen.color:=clWhite;

pen.mode:=pmnotXor;

MoveTo(20,20);
LineTo(200,200);
然后在加一句
Lineto(20,20);
 
我有一个办法行得通先放一个IMAGE为CLIENT属性
然后用FORM。CANVAS画线当然这条线是显示在IMAGE前
这时如果用FORM1。REFRESH可以擦除所有的FORM上的线
建议先用链表保存操作的每个步骤到时动态拆消一个步骤
重画就可以达到要求了。这当然是笨办法,希望哪位高手
有更好的办法。

 
后退
顶部