如何选中一条直线?

hebuliyan 2003-04-23 11:32:12
小弟在做一个画笔程序,需要可以将画好的直线删除,移动,缩放等等。
大家看看我得思路有什么问题:
1、每画好一条直线,当mouseup时,将其两个端点坐标记入一个二维数组,比如第
一条直线坐标记为a[1][1],a[1][2],第二条直线记为a[2][1],a[2][2]。
2、当我的鼠标点在直线上时,此直线处于选中状态,判断mousedown的坐标是在直线
中部,还是在两个端点。若是中部,那么将作的是删除或移动,在直线两端加上
两个小方框,;若是端点,那么将是作缩放(就是一个端点不动,选(点击)中的
端点随着鼠标的移动而移动),只在一个端点加一个小方框。
3、当删除时,在坐标数组中找出此直线的端点坐标,在此两点再画一条直线,异或
掉原来的。
4、当移动时,记录mouseup时的坐标差,在坐标数组中找出此直线的端点坐标,先在
原位置画线,加上坐标差后再画一条。
5、当缩放时,若点击的为终点ep(画线代码见后),则按程序中的画线方法再画一
次;若点击的是起点sp,则要先将sp、ep对调,再画线。由于两点画线的函数用
的次数太多,我想做成一个子程序随时调用。
整个程序和word中的画图功能基本相同。
问题是:
1、如何将我画好的线标号,使line1对应a[1][1]、a[1][2],line2对应a[2][1]、a
[2][2]?
2、如何判断我的点击是否在直线上,就是:点(x,y)是否在(x1,y1)、(x2,y2)这条
直线上(实际上是在这条直线的周围一个小区域内就行)?



附:画直线部分的代码(我的程序要比这要复杂,要有水平线,竖直线等,这是其中比较关键的部分代码)
bool IsDraw=false;
TPoint ep,sp;
void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y)
{
if(Button==mbLeft)
{
IsDraw=true;
sp=ep=Point(X,Y);
Canvas->Pen->Width=2;
Canvas->Pen->Color=clRed ^ ColorToRGB(Color);
Canvas->Pen->Mode=pmXor;
Canvas->PenPos=sp;
Canvas->LineTo(ep.x,ep.y);
}
}
void __fastcall TForm1::FormMouseMove(TObject *Sender, TShiftState Shift,
int X, int Y)
{
if(IsDraw==true)
{
Canvas->PenPos=sp;
Canvas->LineTo(ep.x,ep.y);
ep=Point(X,Y);
Canvas->PenPos=sp;
Canvas->LineTo(ep.x,ep.y);
}
}
void __fastcall TForm1::FormMouseUp(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y)
{
if(IsDraw==true)
IsDraw=false;

}

...全文
247 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
yesry 2003-05-06
  • 打赏
  • 举报
回复
收录维需求分析。
cache2002 2003-05-06
  • 打赏
  • 举报
回复
2。你是每画一条线就保存两个点,如果是一条曲线要走很多转折点时,你这样用二维数组是不是没有必要,你要画上线后,是不是图就直接保存,数据也要保存,以后调用图的时候是整个背景图,不用再重新调用数据或计算了,还有就是你的数据是存于文件吗,还是要存于数据库中,染然我想数据库可能没必要,但如果有很多图时怎么记载数据呀,
3。你在重新画线时,也就是缩放时,是不是定时扫描移动位置,然后异或掉以前的直线,异或是怎么实现的呢,
4。你的画板有没有放大缩小功能,放大或缩小时,很大了是不是不清晰了,也就是说,你不是比例放大的吧,或许你没有考虑这部分功能,如果要考虑应该怎么做呢,
请多多指教,大家一同学习:)
cache2002 2003-05-06
  • 打赏
  • 举报
回复
想提几个问题:
1。你的画图背景是什么控件呀,可不可以加一个背景图或在背景图上直接画,这样的话,你就得用IMAGE,是不是这样?
2。你是每画一条线就保存两个点,如果是一条曲线要走很多转折点时,你这样用二维数组是不是没有必要,你要画上线后,是不是图就直接保存,数据也要保存,以后调用图的时候是整个背景图,不用再重新调用数据或计算了,还有就是你的数据是存于文件吗,还是要存于数据库中,染然我想数据库可能没必要,但如果有很
Yongzhang 2003-04-28
  • 打赏
  • 举报
回复
选择直线时的思路如下:
MouseDown时,提供一个坐标值,然后以此坐标和记录的坐标数组进行计算,如果到那条直线的距离最小,比如5pixel就重画此直线

—————————————————————————————————
┏━★━━◆━━★━┓
♂欢|◢CSDN◣|使♂        ▲自由保存帖子,浏览,关注检测
┃迎|◥论坛助手◤|用┃        ▲完善的CSDN客户端工具
┗━☆━━◇━━━☆┛       ▲自动添加签名......

让你更快,更爽,更方便地上CSDN...
http://www.csdn.net/expert/topic/573/573604.xml
http://www.chinaok.net/csdn/csdn.zip
快速开发平台 2003-04-25
  • 打赏
  • 举报
回复
通常,对于这些功能Windows系统是有现存的功能直接提供的,你可以发一个消息给这个对象即可。
meCAD 2003-04-25
  • 打赏
  • 举报
回复
刷新时?什么刷新时啊?这段函数用来判断现有的数据库里面是否有对应的
afei2002 2003-04-24
  • 打赏
  • 举报
回复
meCAD(狂学C++中,宣告彻底失恋) ,刷新时有点问题吧
meCAD 2003-04-23
  • 打赏
  • 举报
回复
给一段判断老鼠是否落在某条直线上的代码.
bool PickLine(LINENODE *linenode)
{
bool returncode = false;
double x = PrePoint.x-linnode->Start.x;
double y = PrePoint.y-linnode->Start.y;

double a = linenode->End.x-linenode->Start.x;
double b = linenode->End.y-linenode->Start.y;
double c = sqrt(a*a+b*b);

double sin = b/c;
double cos = a/c;

double chg_x = x*cos+y*sin;
double chg_y = -x*sin+y*cos;

if(fabs(chg_y)<5.0 && (chg_x>=0 && chg_x<=c))
returncode = true;

return returncode;
}


直线:
struct LINNODE
{
BYTE bType; //绘图单元的类型
int bDo;
//该记录的状态:比如 bDo>0 不显示此单元 =1 显示. =2被选择. =3移动等..
int Index; //图元索引
POINT Start; //直线的起点.
POINT End; //直线的终点.
LINENODE() //直线图元的初始化函数
{
bType = LINE; //
bDo = 1;
};
};
如果该直线图元被选中的则函数返回true,否则返回false;,其中.参数linenode为检索出的直线图元数据指针, PrePoint 为上次老鼠单击的位置

13,873

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧