判断鼠标是否在曲线上的问题,老问题,再次发问,希望各位帮忙看看,谢谢我想做的就是,当鼠标置于曲线上,既三
判断鼠标是否在曲线上的问题,老问题,再次发问,希望各位帮忙看看,谢谢
我想做的就是,当鼠标置于曲线上,既三条曲线任意之一上时,显示提示框,上面显示当前坐标及曲线的相关属性
曲线是自己做的,每条曲线对应一个数组,可以得到x-y值
现在的问题是:
如何能判断出鼠标是否在曲线上?因为要得到曲线的其他属性,所以在哪一个曲线上还是还知道的
这个问题应该是很多网友都问过的,我最近百度得到的解决方案大致如下:
1)通过去鼠标当前位置的屏幕颜色,和曲线颜色对比,一致的话,则可判定鼠标位于曲线上
--缺点是,我有可能存在颜色一样的多条曲线
2)通过当前鼠标的位置,换算为坐标轴中的X-Y值,然后跟每条曲线所对应的数组里的值比对,差值在一定范围内,则为位于曲线上
--一个曲线上上千个点,依次遍历效率太低了吧
3)将曲线变为一个封闭区域,然后判断鼠标是否在区域内
--这个方案没太弄懂怎么实现,不知道是否可行
上面是我查到的,不知道正确高效的方案是什么?希望各位指点一下
想想类似方案,Google地图导航路线上,就可以用鼠标拖动 导航点 ,我想这个实现起来比我这个更麻烦,不过这个也要先确定鼠标在 数据点 上,才可以做拖动吧,希望给位帮忙指点一下,谢谢啦
[解决办法]
一个曲线上上千个点,依次遍历效率太低了吧
不用偏历吧,折半查找不就可以了。
当然值得思考的是,这么多点的坐标值如果排序,才能最快的实现2维折半查找。
[解决办法]
方法2似乎不需要遍历吧?
曲线的坐标是存储在数组中的,这个数组中存放的坐标似乎可以有次序吧,例如按照x增加的次序存储在数组里,那么查询鼠标是否在数组中,不就不用遍历了吗?
[解决办法]
[解决办法]以曲线为中心,向两侧各扩3个点,生成很多个近似RECT ,再把RECT连成RGN,再判断光标在哪条曲线的RGN内,根据纵坐标显示值。
其实不用这么麻烦。只要根据光标的纵坐标值把每条的都显示出来就好了,显示不要重叠、易区分就行了。
[解决办法]最“快”的办法,在后台画一张一样的图,不用颜色直接用曲线的ID来描点
根据鼠标索引得到后台图像的像素值,即曲线ID
P.S.
一般图形处理类的软件在鼠标拾取时有个感应区域的说法,即使鼠标点下时差几个像素也能选到曲线
[解决办法]鼠标点扩大一个范围,如果和折线相交,就算选中了。用计算几何相关算法
[解决办法]只要根据光标的纵坐标值把每条的都显示出来就好了,显示不要重叠、易区分就行了。
----------------------------------
这样也好。
不过有一些挑剔的客户可能不喜欢。呵呵。挑剔的客户大概占总客户数量的10%。
[解决办法]不需要遍历。
只要你把数组按x或y排序,就不用遍历了,然后用对半查找就可以了。
[解决办法]如果和数组中的值一模一样就好办了,一般把鼠标正好放在曲线上很难吧,应该是接近靠近曲线时就应该算作,鼠标在曲线上了,这样,此刻鼠标所对应的值,在数组中就不存在
-------------------------------------
近似啊。
取三个曲线中与鼠标位置最近的一个作为被选中的曲线,当然这个最近的位置也需要设一个门限,小于这个门限,才认为用户选中了曲线,否则不管。
[解决办法]鼠标点扩大一个范围,如果和折线相交,就算选中了。用计算几何相关算法
-------------------------------
这个负荷也不小啊。
例如3×3范围,那么要检测9个点,对应每个曲线。
[解决办法][解决办法]我说的近似,首先查找每条曲线横坐标x与鼠标最近的数组元素,然后直接用点距离公式,求该点与鼠标点的距离,然后取三个曲线中与鼠标点最近的距离,判断这个最近的距离是否小于门限值,小于门限值,则显示对应的曲线。
计算距离也可以不用开方,直接取平方和。
那么门限可以取5×5或更多。
[解决办法]18楼的方法有趣。
[解决办法][解决办法][解决办法][解决办法][解决办法]我当初的折中方案是获得鼠标位置,以一条轴为基准计算对应的值,判断对应另一条轴上下若干个像素内组成一个范围区间,查看另一个值是否在这个区间内,其实LS这些做法都可行,就是效率不好判断,当然取色应该是最慢的,LZ可以自己测试一下。
[解决办法]一般来说,还是第三种方案!用一个region来判断
但是,第三种方案有一个缺陷,就是多条曲线符合条件的话,你没法取得最优的方案!
楼主一条直线有多少个点?
[解决办法]你可以这样设计,你的每条线里面,都有许多小的线段组成,判断鼠标点,实际上就是是取得最近的线段,当然,也就得到线了!
[解决办法]18楼的很有创意,程序也简单,楼主不妨先试试。
[解决办法]绘图肯定要用双缓冲绘图,这是基本的,不然,效果不好!
如果用rgn的方案,主要是如果有两个都符合条件,你没法判断那条是最近的!正常情况下,选离鼠标点最近的!所以,还是建议用自己的数据结构!
[解决办法]其实我说的方案在本质上与region的方案是一样的
[解决办法][解决办法][解决办法]其实处理还是比较简单的,难点在于效率,当你处理一个百万级数据时就体现出来了。
[解决办法]很好很强大
[解决办法]2)通过当前鼠标的位置,换算为坐标轴中的X-Y值,然后跟每条曲线所对应的数组里的值比对,差值在一定范围内,则为位于曲线上
--一个曲线上上千个点,依次遍历效率太低了吧
这个 哈希一下 怎么能低呢
[解决办法]上下扩三个点全都放到容器里哈希一下....
[解决办法]显然是方法2.
不用遍历,鼠标位置转换后的x,y,在内存中x的邻域(x-r,x+r)查找是否存在y(x)大于y+r且存在y(x)小于y-r。
r就是你允许的鼠标位置误差,不过是需要转换成内存中数据的坐标单位
[解决办法][解决办法][解决办法]老复杂了,阿拉不知道了
[解决办法][解决办法]提示:
对电脑而言RGB(255,0,0)、RGB(255,0,1)、……、RGB(255,0,15)是不同的十六种颜色。
对人眼而言这些都是红色。
[解决办法][解决办法]矩阵,比id图更简单,不用图形,一个可变纬度数组就可以解决
[解决办法][解决办法][解决办法]直接按照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值最近的那个
[解决办法]线点阵列
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自斟了。。
[解决办法][解决办法]算法都告诉你了啊,为啥要看代码,那个js都是混淆过的
我在79楼说的那个算法,时间空间复杂度都是O(1)的啊,而且我觉得挺好的,有啥缺点么。。。
[解决办法]看看,学习了。。。。
[解决办法]很久没在CSDN上发言了,建议如下,不知道是否适合。
用hash来存储,把曲线的 x,y 坐标组合起来存储到hash 中,牺牲内存空间换时间吧!
在鼠标事件中 将鼠标的 x,y 坐标组合起来,从hash 中找是否存在曲线点;
不知道楼主明白我的意思不?
[解决办法]当然,还有注意处理鼠标事件最好有一定的时间间隔;
如果一条曲线3000 个点,一个点两个坐标加起来如果能用9个长度的字符描述比如 233-443 ,这个作为hash 的key,任意一个非空字符,或者用来描述是某条曲线的字符作为 value,加起来一个点就占用 10 个字符长度
那么一条曲线粗略的计算就是 300000 个字符长,可以认为占用约300KB 内存,10条占用大约3M
这样算下来与动不动就占几百M的应用程序比起来,也不为过嘛!
当然还可能有其他更优秀的方法,比如把曲线作为对象来处理,直接在曲线上绑定鼠标驱动事件,当然这个要根据LZ的实际情况了;
[解决办法]C/C++ codemark