首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

判断鼠标是否在曲线上的有关问题,老有关问题,再次发问,希望各位帮忙看看,多谢

2011-12-29 
判断鼠标是否在曲线上的问题,老问题,再次发问,希望各位帮忙看看,谢谢我想做的就是,当鼠标置于曲线上,既三

判断鼠标是否在曲线上的问题,老问题,再次发问,希望各位帮忙看看,谢谢



我想做的就是,当鼠标置于曲线上,既三条曲线任意之一上时,显示提示框,上面显示当前坐标及曲线的相关属性
曲线是自己做的,每条曲线对应一个数组,可以得到x-y值

现在的问题是:
如何能判断出鼠标是否在曲线上?因为要得到曲线的其他属性,所以在哪一个曲线上还是还知道的


这个问题应该是很多网友都问过的,我最近百度得到的解决方案大致如下:
1)通过去鼠标当前位置的屏幕颜色,和曲线颜色对比,一致的话,则可判定鼠标位于曲线上
--缺点是,我有可能存在颜色一样的多条曲线

2)通过当前鼠标的位置,换算为坐标轴中的X-Y值,然后跟每条曲线所对应的数组里的值比对,差值在一定范围内,则为位于曲线上
--一个曲线上上千个点,依次遍历效率太低了吧

3)将曲线变为一个封闭区域,然后判断鼠标是否在区域内
--这个方案没太弄懂怎么实现,不知道是否可行

上面是我查到的,不知道正确高效的方案是什么?希望各位指点一下

想想类似方案,Google地图导航路线上,就可以用鼠标拖动 导航点 ,我想这个实现起来比我这个更麻烦,不过这个也要先确定鼠标在 数据点 上,才可以做拖动吧,希望给位帮忙指点一下,谢谢啦

[解决办法]
一个曲线上上千个点,依次遍历效率太低了吧

不用偏历吧,折半查找不就可以了。
当然值得思考的是,这么多点的坐标值如果排序,才能最快的实现2维折半查找。
[解决办法]
方法2似乎不需要遍历吧?

曲线的坐标是存储在数组中的,这个数组中存放的坐标似乎可以有次序吧,例如按照x增加的次序存储在数组里,那么查询鼠标是否在数组中,不就不用遍历了吗?

[解决办法]

探讨
引用:

一个曲线上上千个点,依次遍历效率太低了吧

不用偏历吧,折半查找不就可以了。
当然值得思考的是,这么多点的坐标值如果排序,才能最快的实现2维折半查找。


折半也不少吧,因为鼠标移动事件中就要判断一下,太频繁了,感觉还是不好呢

[解决办法]
以曲线为中心,向两侧各扩3个点,生成很多个近似RECT ,再把RECT连成RGN,再判断光标在哪条曲线的RGN内,根据纵坐标显示值。

其实不用这么麻烦。只要根据光标的纵坐标值把每条的都显示出来就好了,显示不要重叠、易区分就行了。
[解决办法]
最“快”的办法,在后台画一张一样的图,不用颜色直接用曲线的ID来描点
根据鼠标索引得到后台图像的像素值,即曲线ID
P.S.
一般图形处理类的软件在鼠标拾取时有个感应区域的说法,即使鼠标点下时差几个像素也能选到曲线
[解决办法]
鼠标点扩大一个范围,如果和折线相交,就算选中了。用计算几何相关算法
[解决办法]
只要根据光标的纵坐标值把每条的都显示出来就好了,显示不要重叠、易区分就行了。
----------------------------------

这样也好。
不过有一些挑剔的客户可能不喜欢。呵呵。挑剔的客户大概占总客户数量的10%。
[解决办法]
不需要遍历。
只要你把数组按x或y排序,就不用遍历了,然后用对半查找就可以了。
[解决办法]
如果和数组中的值一模一样就好办了,一般把鼠标正好放在曲线上很难吧,应该是接近靠近曲线时就应该算作,鼠标在曲线上了,这样,此刻鼠标所对应的值,在数组中就不存在
-------------------------------------
近似啊。
取三个曲线中与鼠标位置最近的一个作为被选中的曲线,当然这个最近的位置也需要设一个门限,小于这个门限,才认为用户选中了曲线,否则不管。
[解决办法]
鼠标点扩大一个范围,如果和折线相交,就算选中了。用计算几何相关算法

-------------------------------
这个负荷也不小啊。
例如3×3范围,那么要检测9个点,对应每个曲线。
[解决办法]
探讨

引用:

最“快”的办法,在后台画一张一样的图,不用颜色直接用曲线的ID来描点
根据鼠标索引得到后台图像的像素值,即曲线ID
P.S.
一般图形处理类的软件在鼠标拾取时有个感应区域的说法,即使鼠标点下时差几个像素也能选到曲线


你的意思我明白了,只是后台这种方案不知道怎么操作,可以举个例子吗?谢谢啦

[解决办法]
我说的近似,首先查找每条曲线横坐标x与鼠标最近的数组元素,然后直接用点距离公式,求该点与鼠标点的距离,然后取三个曲线中与鼠标点最近的距离,判断这个最近的距离是否小于门限值,小于门限值,则显示对应的曲线。

计算距离也可以不用开方,直接取平方和。
那么门限可以取5×5或更多。
[解决办法]
18楼的方法有趣。
[解决办法]
探讨

引用:

引用:

引用:

最“快”的办法,在后台画一张一样的图,不用颜色直接用曲线的ID来描点
根据鼠标索引得到后台图像的像素值,即曲线ID
P.S.
一般图形处理类的软件在鼠标拾取时有个感应区域的说法,即使鼠标点下时差几个像素也能选到曲线


你的意思我明白了,只是后台这种……


[解决办法]
探讨

引用:

引用:

引用:

引用:

这样就是画了两次了,如果曲线是实时的话,不知道会不会有效率影响。

[解决办法]
探讨

我说的近似,首先查找每条曲线横坐标x与鼠标最近的数组元素,然后直接用点距离公式,求该点与鼠标点的距离,然后取三个曲线中与鼠标点最近的距离,判断这个最近的距离是否小于门限值,小于门限值,则显示对应的曲线。

计算距离也可以不用开方,直接取平方和。
那么门限可以取5×5或更多。

[解决办法]
探讨

引用:

引用:

引用:

引用:

引用:

这样就是画了两次了,如果曲线是实时的话,不知道会不会有效率影响。

一般画实时曲线会用双缓冲的办法,这个地方相当于再加一个缓冲,影响不大

[解决办法]
我当初的折中方案是获得鼠标位置,以一条轴为基准计算对应的值,判断对应另一条轴上下若干个像素内组成一个范围区间,查看另一个值是否在这个区间内,其实LS这些做法都可行,就是效率不好判断,当然取色应该是最慢的,LZ可以自己测试一下。
[解决办法]
一般来说,还是第三种方案!用一个region来判断
但是,第三种方案有一个缺陷,就是多条曲线符合条件的话,你没法取得最优的方案!
楼主一条直线有多少个点?
[解决办法]
你可以这样设计,你的每条线里面,都有许多小的线段组成,判断鼠标点,实际上就是是取得最近的线段,当然,也就得到线了!
[解决办法]
18楼的很有创意,程序也简单,楼主不妨先试试。
[解决办法]
绘图肯定要用双缓冲绘图,这是基本的,不然,效果不好!
如果用rgn的方案,主要是如果有两个都符合条件,你没法判断那条是最近的!正常情况下,选离鼠标点最近的!所以,还是建议用自己的数据结构!
[解决办法]
其实我说的方案在本质上与region的方案是一样的
[解决办法]
探讨

引用:

我当初的折中方案是获得鼠标位置,以一条轴为基准计算对应的值,判断对应另一条轴上下若干个像素内组成一个范围区间,查看另一个值是否在这个区间内,其实LS这些做法都可行,就是效率不好判断,当然取色应该是最慢的,LZ可以自己测试一下。


朋友你是在OnMouseMove消息中判断的吗?

[解决办法]

[解决办法]
其实处理还是比较简单的,难点在于效率,当你处理一个百万级数据时就体现出来了。
[解决办法]
很好很强大
[解决办法]
2)通过当前鼠标的位置,换算为坐标轴中的X-Y值,然后跟每条曲线所对应的数组里的值比对,差值在一定范围内,则为位于曲线上
--一个曲线上上千个点,依次遍历效率太低了吧

这个 哈希一下 怎么能低呢
[解决办法]
上下扩三个点全都放到容器里哈希一下....
[解决办法]
显然是方法2.
不用遍历,鼠标位置转换后的x,y,在内存中x的邻域(x-r,x+r)查找是否存在y(x)大于y+r且存在y(x)小于y-r。
r就是你允许的鼠标位置误差,不过是需要转换成内存中数据的坐标单位
[解决办法]
探讨

2)通过当前鼠标的位置,换算为坐标轴中的X-Y值,然后跟每条曲线所对应的数组里的值比对,差值在一定范围内,则为位于曲线上
--一个曲线上上千个点,依次遍历效率太低了吧

这个 哈希一下 怎么能低呢

[解决办法]
探讨

显然是方法2.
不用遍历,鼠标位置转换后的x,y,在内存中x的邻域(x-r,x+r)查找是否存在y(x)大于y+r且存在y(x)小于y-r。
r就是你允许的鼠标位置误差,不过是需要转换成内存中数据的坐标单位

[解决办法]
老复杂了,阿拉不知道了
[解决办法]
探讨

2)通过当前鼠标的位置,换算为坐标轴中的X-Y值,然后跟每条曲线所对应的数组里的值比对,差值在一定范围内,则为位于曲线上


--一个曲线上上千个点,依次遍历效率太低了吧

这个 哈希一下 怎么能低呢


[解决办法]
提示:
对电脑而言RGB(255,0,0)、RGB(255,0,1)、……、RGB(255,0,15)是不同的十六种颜色。
对人眼而言这些都是红色。

[解决办法]
探讨
引用:

提示:
对电脑而言RGB(255,0,0)、RGB(255,0,1)、……、RGB(255,0,15)是不同的十六种颜色。
对人眼而言这些都是红色。


明白你的意思,跟上面取颜色,判断曲线ID的方法类似是不?

[解决办法]
矩阵,比id图更简单,不用图形,一个可变纬度数组就可以解决
[解决办法]
探讨

以曲线为中心,向两侧各扩3个点,生成很多个近似RECT ,再把RECT连成RGN,再判断光标在哪条曲线的RGN内,根据纵坐标显示值。

其实不用这么麻烦。只要根据光标的纵坐标值把每条的都显示出来就好了,显示不要重叠、易区分就行了。

[解决办法]
探讨

引用:

引用:

最“快”的办法,在后台画一张一样的图,不用颜色直接用曲线的ID来描点
根据鼠标索引得到后台图像的像素值,即曲线ID
P.S.
一般图形处理类的软件在鼠标拾取时有个感应区域的说法,即使鼠标点下时差几个像素也能选到曲线


你的意思我明白了,只是后台这种方案不知道怎么操作,可以举个例子吗?谢谢啦
……

[解决办法]
直接按照bitmap的思路来处理,放一个二维数组,里面存储信息,精度就按像素来,内存也大不到哪去,取的时候直接按当前坐标换算。
如果考虑到一个区域响应动作,则以鼠标位置向外扩展一个正方形,复杂度接近O(1)
[解决办法]

[解决办法]
图形若是自己的函数绘制的,根据窗口和鼠标的坐标,再加上你自己的函数公式,带进去计算就是了,不用遍历……

但要是你不知道图形的绘制函数,不遍历、取颜色比对还有其它方法?
[解决办法]
不知道这三条曲线是怎么样画出来的, 有没有一个公式, 通过这个公式逆向计算, 即已知道 鼠标当前坐标, (x0,y0),然后用公式带入x0逆向计算出 各条曲线的y值y1,y2,y3, 分别跟 y0比较, 重合或是相差在一定的范围内即认为是重合, 此法理想化一些了
[解决办法]
实在不行, 拼了, 看看这篇文章:http://blog.csdn.net/m2mgroup/article/details/4188553

用这个方法来搞, 效率应该不低

曲线设置一下优先级,重叠的地方按优先级来判断碰撞
[解决办法]
"我想做的就是,当鼠标置于曲线上,既三条曲线任意之一上时,显示提示框,上面显示当前坐标及曲线的相关属性 曲线是自己做的,每条曲线对应一个数组,可以得到x-y值"

>> 既然当鼠标置于曲线上, 可以显示提示框, 框里的内容必定跟 (x,y)有关, 而且读出坐标(x,y)处曲线对应的意义(比如:(m,n), 也就说明这个值是要缓存起来随时使用的), 绘图的时候, 是根据一个公式可将(m,n)计算得到 (x,y), 既然如此, 来个反向计算, 就可以了
[解决办法]
看看js的实现,http://raphaeljs.com/analytics.html
对浏览器可能有点点要求。
[解决办法]
很好,很强大。。
[解决办法]
vsdvsdvsd
[解决办法]
cvcsvcsvsc
[解决办法]
如果是我做,我就这么做:
设鼠标位置是(x,y)
取3条曲线在x的值与y的差:abs(F1(x)-y), abs(F2(x)), abs(F3(x)-y)
如果这三个值的最小值小于一定就显示信息。

我觉得比找最近点好用,用户也更习惯
[解决办法]
我当初的折中方案是获得鼠标位置,以一条轴为基准计算对应的值,判断对应另一条轴上下若干个像素内组成一个范围区间,查看另一个值是否在这个区间内,其实LS这些做法都可行,就是效率不好判断,当然取色应该是最慢的,LZ可以自己测试一下。
[解决办法]
这个就是很简单的判断
只要在矩形内,找x值最近的那个

探讨

引用:

看看js的实现,http://raphaeljs.com/analytics.html
对浏览器可能有点点要求。


对,就是这种感觉,很帅的动画啊
感觉Google地图中,导航点的拖拽,也有类似的感觉
明天看看这个js代码,能不能有点启发



[解决办法]
线点阵列
point[Z][x][y]

消息
鼠标点 x 10 y 20

遍历线
int x=0,z=0;
for(i=0;i<点Z轴的最大;i++)
if( point[i][鼠标点.x][鼠标点.y] == 鼠标点)
{
x++;
z=i;
}
三目x==2?结束:不做任何; //判断是否有线的点的重叠有则退出
}
返回 Z

如果有一万条线 只判断一万个点就行了
[解决办法]
三目判断可以放到第if判断的内部可以快一倍的速度
[解决办法]


设置一个矩阵, 假如这个图形是 10 × 10
矩阵也就是10×10

初始化矩阵,所有点为0,曲线1的所有路径点都对应矩阵,相应的矩阵点就设置为 1,依此方法,曲线2,设置为2,曲线N设置为N

鼠标在图形上得到坐标 x,y, 以这个x,y直接取矩阵相应点的值,是几就是曲线几,如果是0则表示不在曲线上

这个矩阵实现起来小的可怜,也简单的可怜,如果这个图上最多只画255条线,那用字节类型就行了,一个1024 × 1024 的图形才占用1M空间,换取来的速度是无可比拟的,如果是1024*1024的图形,需要的内存肯定就不是1M了。。。 lz自斟了。。
[解决办法]
探讨

实在不行, 拼了, 看看这篇文章:http://blog.csdn.net/m2mgroup/article/details/4188553

用这个方法来搞, 效率应该不低

曲线设置一下优先级,重叠的地方按优先级来判断碰撞

[解决办法]
算法都告诉你了啊,为啥要看代码,那个js都是混淆过的
我在79楼说的那个算法,时间空间复杂度都是O(1)的啊,而且我觉得挺好的,有啥缺点么。。。

探讨

引用:

这个就是很简单的判断
只要在矩形内,找x值最近的那个

引用:

引用:

看看js的实现,http://raphaeljs.com/analytics.html
对浏览器可能有点点要求。


对,就是这种感觉,很帅的动画啊
感觉Google地图中,导航点的拖拽,……

[解决办法]
看看,学习了。。。。
[解决办法]
很久没在CSDN上发言了,建议如下,不知道是否适合。
用hash来存储,把曲线的 x,y 坐标组合起来存储到hash 中,牺牲内存空间换时间吧!

在鼠标事件中 将鼠标的 x,y 坐标组合起来,从hash 中找是否存在曲线点;

不知道楼主明白我的意思不?
[解决办法]
当然,还有注意处理鼠标事件最好有一定的时间间隔;

如果一条曲线3000 个点,一个点两个坐标加起来如果能用9个长度的字符描述比如 233-443 ,这个作为hash 的key,任意一个非空字符,或者用来描述是某条曲线的字符作为 value,加起来一个点就占用 10 个字符长度

那么一条曲线粗略的计算就是 300000 个字符长,可以认为占用约300KB 内存,10条占用大约3M
这样算下来与动不动就占几百M的应用程序比起来,也不为过嘛!

当然还可能有其他更优秀的方法,比如把曲线作为对象来处理,直接在曲线上绑定鼠标驱动事件,当然这个要根据LZ的实际情况了;
[解决办法]
C/C++ code
mark 

热点排行