作画图软件时,如何能把已画好的线用鼠标击活(100分)

  • 主题发起人 主题发起人 csf
  • 开始时间 开始时间
直线:记录下两端的坐标, 在OnMouseUp事件中对所有的直线计算一遍,看它与单击点
的距离是否小于5各像素, 若是, 用定时器不停地用异或方式重画.这种方法我做过,
能成功,对于一些曲线可用类似的做法, 但是复杂多了.
 
我一般用另一个方法:

开一个与图象一样大的缓冲区,先清0,分配计数器COUNT=1.然后,每画一个对象,
同时在这个缓冲区内用COUNT值画同样的对象,当然可以加粗以方便选择了.

在WM_LBUTTONDOWN中,用鼠标的坐标读那个缓冲区,就可以判断用户要选择那个
对象了.至于选中后如何表示,可以有多种方法了,就不谈了.
 
我是这么做的,每个图元都是一个对象,直线是其中一种。
当你点中某一对象时,将这个对象设置成selected。将其属性提取出来,
包括坐标等等。
然后就可以对其进行超做了。
记得要refresh.
 
各位高手,能给我举个例子吗?你们的方法都挺不错,但我还是一个门外汉。
 
我也在做这方面的东西.
lhz的方法,在存盘后就无法再用了.
我是这样做的,分层画,分层存.但效果不好!
lizhao的方法我试一下,希望管用!
要不lhz,lizhao二位能把你们的源程序给我发一份吗?
mailto: delphi201@263.net
 
使用shape控件代替画的线
 
直线的拾取可以通过两个步骤实现.
Step1: 判断鼠标位置是否在直线所在的举行区域内, 如果在进行第二步, 否则false
Step2: 判断点到直线的距离,或者用一个近似算法判断点是否在以直线两端点为焦点
的椭圆区域内
 

lizhao的方法很好,应该对象化处理.
 
用"TLine"检索一下已答问题, 看看我的TLine控件, 本身有拾取/移动/改变顶点等
功能; 鼠标可以穿透控件
 
这是我的程序的一部分片段,现贴出来(*:此程序运行效果完全能够
满足上面大家提到的要求,(如:move,pick,drag 等)。
为了我程序本身的功能,所以还添加了如阴影效果,颜色设置等一些其他的属性。
注:由于是我从我的程序上截下来的,肯定会有语法错误。
如果有谁感兴趣可以到我的www://166.111.78.92/上下载Exe文件。

type
TLineObj=class(TSimpleObj)
private
FStartX: integer;
FStartY: integer;
FEndX: integer;
FEndY: integer;
......
constructor TLineObj.Create(StartPoint,EndPoint:TPoint);
begin

inherited Create(StartPoint,EndPoint);
ObjectType := 'Line';
FStartX:=StartPoint.x;
FStartY:=StartPoint.y;
FEndX:=EndPoint.x;
FEndY:=EndPoint.y;
end;

Procedure TLineObj.Draw(ACanvas:TCanvas);
var
AOldPen:TPen;
A,X1,Y1,X2,Y2,CX,CY:Integer;
begin
with ACanvas do
begin
Pen.Width:=BorderWidth;
if Shadow then
begin
Pen.Color:=ShadowColor;
Inc(FStartX,ShadowX);Inc(FStartY,ShadowY);
Inc(FEndX,ShadowX);Inc(FEndY,ShadowY);
MoveTo(FStartX,FStartY);
LineTo(FEndX,FEndY);
Dec(FStartX,ShadowX);Dec(FStartY,ShadowY);
Dec(FEndX,ShadowX);Dec(FEndY,ShadowY);
end;
Pen.Color:=BorderColor;
MoveTo(FStartX,FStartY);
LineTo(FEndX,FEndY);
end;
end;
Const MinSpace=8;

function TLineObj.isInBound(X,Y:integer):boolean;
var
L,L1,L2: Real;
begin
L:=Sqrt((FStartX-FEndX)*(FStartX-FEndX)
+(FStartY-FEndY)*(FStartY-FEndY));
L1:=Sqrt((FStartX-X)*(FSTartX-X)
+(FStartY-y)*(FStartY-y));
L2:=Sqrt((FEndX-X)*(FEndX-X)
+(FEndY-Y)*(FEndY-Y));
if (L1+L2-L)<MinSpace then Result :=True
else Result:= False;

end;

procedure TLineObj.Move(ADiffPoint,ANewPoint:TPoint);
var
tempWidth,tempHeight:integer;
begin
tempwidth:=FEndX-FStartx;
tempheight:=FEndY-FStartY;;

FStartX:=ANewPoint.x-ADiffPoint.x;
FStartY:=ANewPoint.y-ADiffPoint.y;
FEndX:=FStartX+tempwidth;
FEndy:=FStartY+tempheight;
end;

procedure TLineObj.Drag(APoint:TPoint;PointKind:Integer);
var
tempPoint:TPoint;
L1,L2: Real;
begin
Case PointKind of
4 :
begin
FStartX:=APoint.x;
FStartY:=APoint.y;
end;
5 :
begin
FEndX:=Apoint.x;
FEndY:=Apoint.y;
end;
end;//case
end;
 
补充:
由于我的文件是对库操作,
所以下载的Exe中有很多功能不能用。
 
能给我一份完整地Source Code吗?

E-Mail:haw_wang@263.net
 
csf: 找到我那个TLine没有?
 
我给你发一个控件,一位老兄写的,我改了一下,
希望能解决你的问题!
 
我不发了,就是那个TLine(是huizhang),不过现在我能拣一切规则图形了!
稍微改一下!
 
csf:

这个问题已经很长时间没有人参加讨论,为保持版面
整洁,节约网友时间,请提问者采取必要处理措施。
关于图形图象版管理细则,请参见<a href="http://www.gislab.ecnu.edu.cn/delphibbs/DispQ.asp?LID=111927">这个</a>问题。如两天
内提问者没有响应,我将采取强制措施。

如有管理建议,请到<a href="http://www.gislab.ecnu.edu.cn/delphibbs/DispQ.asp?LID=111927">这里</a>提出。谢谢!
 
多人接受答案了。
 

Similar threads

D
回复
0
查看
802
DelphiTeacher的专栏
D
D
回复
0
查看
747
DelphiTeacher的专栏
D
后退
顶部