我想用vb做一程序,用户在窗体上画线,用算法判断用户画的是不是圆。
这个好像在掌握模糊数学。哪位朋友做过

解决方案 »

  1.   

    我不是高手,我想表达一下自己的想法
    如果窗体上只有一个图形的话,
    你可以先取图形最左一个点的坐标和
    最右一个点的坐标
    或是最上一点的坐标和最下一个点的坐标
    然后算出圆心,半径,得到圆的公式
    用一个循环检查用户的图形是不是
    都在路径上.
    for x=minx to maxx
      y= expression(x)
      if point(x,y)<>form1.backcolor then
         msgbox "不是圆"  '假定图形颜色不等于背景颜色,如果等于我暂时就不知道了
         exit for 
      end if 
    next x
      

  2.   

    to  zhj11226
    你的那个方法好傻。
    不能纠错,如果我画的圆不太正规呢?
      

  3.   

    不正规也好说
    可以设置一个精度值,用它来控制采样率
    也就是精度越高,采样越多.以及目标点周围的差值越小
    当然总要有一种办法输入倒数组zhj11226的办法也是可以的
    ===============================
    用户画出的图形===>数组存储A()
    模板模型==>缩放变形===>数组存储B()
    对A进行采样===>分析差值是否在误差范围之内====>与B()进行比较
    判定是否为模板图形
    ===============================
    理论上 没有什么难度,可能实践上比较费时
      

  4.   

    to aabiao
    最好用模糊数学解决。
      

  5.   

    很难的问题。
    通过mousemove事件采样(X,Y)
    不过mousemove事件,鼠标动得太快就没法采样了。然后通过算法判断定期时间内的采样结果。
    最好有算法先做一个平滑一下(忘了叫什么了。)
    应该还有回溯算法。
    做好了发给我研究研究好吗??
    [email protected]
      

  6.   

    有道理是有道理,但实现的时候比较困难啊,实现获得标准圆的切线斜率的列表简单,获得用户画图时的切线也简单,比较复杂的是比较的算法和用户画图的切线斜率变化,前者要考虑在比较时应该是和标准圆的切线列表进行可仿佛的比较,比如,标准圆的切线列表采样了100个,那么比较到第100个时应该能够接着去比较第1个;用户画图的切线斜率变化,需要考虑与标准圆的切线斜率列表比较时,一是要有连续性,二是在保证连续的情况下,还要考虑因为绘图不准确产生的斜率的跳跃,即,比如对用户绘图当前点p1和上一次采样的点p0计算斜率并和标准圆的切线斜率列表比较后,发现和列表中的k和k+n(有两个是因为圆的斜率变化是周期性的)这两个相近,那么意味着下次采样的p2和当前的p1的切线应该在k+m或k-m或k+n+m或k+n-m上,m为切线变化的合理范围.还有就是是否需要考虑绘图采样的噪声问题,即对一些毛刺怎么处理,毛刺的处理就比较麻烦了,因为你必须跟踪一定长度的用户绘图才能够确定是否是毛刺.
    没有为你具体解决什么,不过你提的问题倒是挺有意思,有时间回家帮你实现看看,不过可别指望我啊,估计一般情况下我是没太多时间,也不知道能不能替你解决.
      

  7.   

    不过mousemove事件,鼠标动得太快就没法采样了。
    ------------------------------------------
    不是没法采样,而是根本没有这个时间精度内的鼠标消息。楼主的问题就是我当时研究手势操作时遇到的最大问题。用了一些函数拟合的知识就基本解决了。
    楼主知道如何识别一个平面内的线么?用类似的方法,改变坐标系,使得线能代圆(好像是叫反演吧?数学没学好,记不得),然后再利用识别线的方法就可以了。
    这不是什么好方法,运算很慢。不过应该就是正规的方法,因为记得当时有个游戏叫《黑与白》里面有手势识别,运算速度和我的算法差不多……不过也许人家用的是更复杂的方法也说不定。
      

  8.   

    用户是怎么画图的?如果是按鼠标轨迹来画出的非矢量图形,我觉得判断它是不是一个圆没有多大意义。不知道楼主是否用过AutoCAD,在AutoCAD中的,画圆、圆弧、直线、多义线等,都有不同的命令,你可以建一个用户操作记录:在什么座标?画了什么图形?如果要判断经过某个座标的是什么图形,对比操作记录就知道了,这样做还可以实现无限次undo和redo。
      

  9.   

    to junwhj
    用户就是在窗体上托动一下就要进行判断.
      

  10.   

    这个问题难,我想是否能简便的解决,谈谈我的思路:假设画圆,或类圆,用户的鼠标移动将会形成多边形(n>=3)计算出该多边型落点是否在 两同心圆内,以及各个同心圆的半径(半径差可成为参数)
    通过同心圆可以进行预判断通过移动轨迹,计算移动曲线的曲率(参数)检查曲率,曲率变化,曲率变动范围, 与圆的大小几个参数的相互关系不知道可不可行
      

  11.   

    to cxyOOOO
    好深奥,听不懂。
      

  12.   

    cxyOOOO就是我的思路,基本上是差不多的
    就是运算很庞大
      

  13.   

    是的, 在原理上与AresChen(AresChen) 和  CCL(VB卡尔)
    是共通的,
    在实现上可能有所不同.但我还没想好如何实现, :)
      

  14.   

    使用曲率,就修正了AresChen(AresChen)斜率变化复杂的问题,
    并且,可能使计算方便,
    曲率变化也提供了重新定位用户操作起始点,减少了计算数据量研究的重点在,如何计算曲率,以及曲率变化与轨迹之间的联系
      

  15.   

    ? 请详述一般而言
    K曲率
    K的平均值
    K同心圆(小)> K用户 > K同心圆(大) > 直线(0)
      

  16.   

    to  cxyOOOO
    不好意思,我也说不上来。我也是听我同事说的。
      

  17.   

    关于曲线曲率(或曲率半径)的计算公式可见如下
    http://college.chinaschool.net/math/gaoshu_hotel/zsd/n3/z5/z5.htm我想,问题基本上可以如此解决了但要注意的是,在两个同心圆中,可能存在着如同橄榄一样的类椭圆,
    在该圆上的某一处曲线的曲率可能会明显不符我上贴中的公式,
    而用户鼠标移动又不可能非常近似于圆,因此要加入一些特殊处理另外,对用户鼠标移动的坐标还应该跟时间联系,
    如GetTickCount或QueryPerformanceCounter
      

  18.   

    比较复杂不如请 cxyOOOO写出一个vb代码,这样大家都可以学习了。
      

  19.   

    http://media.cs.tsinghua.edu.cn/~ahz/digitalimageprocess/chapter16/chapt16_ahz.htm这篇文章已经讲的很清楚了,谁能把他转换成代码?
      

  20.   

    明白了
    哪有画圆的!
    一般都是 按下鼠标右键 上下  左右  左右左 右左右 松开鼠标
    比如MyIE   很简单的问题,非得画圆圈干什么?
    或者建立一个纵横比率,就算用户画的事菱形也算画圆,然后是顺时针 逆时针的事情
    ================================================
    你想的过于复杂了!
    完全没有必要!
    一开始我还以为跟人工智能有关的问题,吓坏我了
      

  21.   

    to CCL提供思路就可以,或者有现在的算法可以借鉴
      

  22.   

    to seraph2
    比较图片是不行的,如果我画的图形大一些呢?
      

  23.   

    我看还是使用 Shape 控件画图吧.
    我以前做过的一个电教画板就是使用SHAPE1是.思路是这样的.
    1.在窗体上放一个SHAPE 控件,假定SHAPE名称为:DRAWSHP,将其INDEX值设置为0.将其Visible设为FALSE.
    2.通过动态加载 DRAWSHP 控件,设置其VISIBLE和SHAPE属性,达到画图目的.
    3.但是,SHAPE本身不支持事件,所以,你单击SHAPE控件时,实质上是单击SHAPE的父容器,我们必须要通过其它的方式来找到该点的SHAPE.那么,通过什么方式呢?很简单,就是在FORM_MOUSEDOWN 事件中搜索窗体的所有控件,判断其类型是否是SHAPE.然后,判断单击点(X,Y)是否在 L,T,L+W,T+H 范围内即可.(别担心电脑的速度,就算是有一万个SHAPE,它也是在1/1000秒内完成)
    查找SHAPE控件,参考下面程序:
    Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
            Dim ConObj As Object
            For Each ConObj In Form1.Controls
                If UCase$(TypeName(ConObj)) = "SHAPE" Then
                   If UCase$(ConObj.Name) = "DRAWSHP" Then
                      If Y > ConObj.Top And Y < ConObj.Height And X > ConObj.Left And X < ConObj.Left + ConObj.Width Then
                         'ConObj 是 你要找的SHAPE控件........................
                         '可以在此根据控件的SHAPE属性判断其图形类型 
                      End If
                   End If
                End If
            Next
    End Sub
      

  24.   

    更正:
                      If Y > ConObj.Top And Y < ConObj.Height And X > ConObj.Left And X < ConObj.Left + ConObj.Width Then
                         'ConObj 是 你要找的SHAPE控件........................
                         '可以在此根据控件的SHAPE属性判断其图形类型 
                         EXIT SUB  '********************
                      End If