一辆汽车离开A点直线行驶,知道A点的坐标(Ax,Ay),也能实时采集到汽车B的坐标(Bx,By),现在想使B向A行驶,我的思路是这样的,实时计算B到A点的距离,如果距离越来越小,则继续行驶,如果距离越来越大,则反方向行驶,但是这个循环算法我一直无法设计好,请问各位是否有更好的算法,如果没有,如何实现我的思路。非常感谢!

解决方案 »

  1.   

    谢谢yesvery,我的意思是我的算法如何用循环高效率的实现,希望有部分代码指导一下。我对循环和数值传递这一块总是比较头疼。
      

  2.   

    一个for等循环,比较前后两次的距离是否增大,大了,就转向,减小,就继续保持当前方向..
      

  3.   

    应该是实时按照坐标 (Bx,By)→(Ax,Ay) 确定的射线方向调整 B 的行进方向,只要 B 的速度大于 A 就能追上 B。
      

  4.   

    有Shape1,Shape2,Command1,Timer1四个控件
    其中Shape1的位置相当于你说的A,Shape2的位置相当于你说的B.
    Timer1的Interval设为100,Enabled设为False
    下述代码可演示一个减速运动,使Shape2尽快地接近Shape1,Private Sub Command1_Click()
      Timer1.Enabled = True
    End SubPrivate Sub Timer1_Timer()
      Shape2.Left = Shape2.Left - (Shape2.Left - Shape1.Left) / 10
      Shape2.Top = Shape2.Top - (Shape2.Top - Shape1.Top) / 10
    End Sub
      

  5.   

    输入是一连串的坐标,也就是
    bx(i), by(i)
    那么对其进行微分就可以速度了。
    vx(i),vy(i)
    对所有的速度进行相加,就是位移了。
      

  6.   

    感谢yesvery提供了一个很有意思的实例,不过不太实用我的应用,因为汽车是主动运动并且是正在运动的,所以首先得分析它相对于A点是如何运动的,是远离还是接近,如果是远离则需要给它发送返回指令,如果是接近,则不发送任何指令。
    而oyljerry的思路和我是完全一致的,“一个for等循环,比较前后两次的距离是否增大,大了,就转向,减小,就继续保持当前方向..”但是这个For循环如何设计,我还期待各位大侠能给我部分代码指导一下,非常感谢!
      

  7.   

    请问你是用VB编程?还是用VB进行仿真?
    如果用VB编程,循环恐怕不合适(太快了)。还是应该采用定时器较好。另外,没有必要测量距离,只要在X,Y两个方向上进行比较。
    如果Xb-Xa<0,则汽车应该往前开,如果Xb-Xa>0,则汽车应该往回开。
    Y方向也是同样道理。汽车是否回到原点,不应该用Xb-Xa=0进行判定,
    因为这样,可能使汽车在A点抖动。应该用Xb-Xa 小于 某一较小值进行判定
      
      

  8.   

    越看题目越糊涂了,既然汽车一开始就是从 A 出发的,那么经过两个时钟周期(或者说循环)就能回到 A 点:
    1)
    Bx = Ax + Vx * t
    By = Ay + Vy * t
    明显比开始时离开 A 点的距离远,反方向行驶
    2)
    Bx = Ax + Vx * t - Vx * t = Ax
    By = Ay + Vy * t - Vy * t = Ay
    马上回到 A 点这有什么好考虑的?
      

  9.   

    非常感谢几位大侠的关注,可能是我的应用在表述上面存在问题。其实想法是很简单的,就是GPS方面的类似功能,现在我的汽车在一个地方行驶,坐标是(Xb,Yb),这个坐标是不断改变的,因为汽车在不断的行驶,所以存在一个不断读取汽车坐标的问题。目的地是A(Xa,Ya),现在要使汽车往A点开,如何实现,不考虑中间的障碍物。
    我的思路是不断的取汽车的坐标值,然后不断的和A的坐标对比,比如第一次的对比值a1=Xb-Xa,第二次的对比值a2=Xb-Xa,如果a2>a1,说明越来越远,则需要反向行驶,反之则一直行驶。
    我的困难就在于Xb,Yb的值是不断变化的,如何不断记录和A点的差值,并且和上一次差值进行比较,然后作出判断该正向行驶还是反向行驶。
      

  10.   

    不对的。
    假定有一个长方形街区,东西宽>南北高*2,四个顶点为岔路口,A 在北边道路中点,B 在西南角,你的算法只会在南边道路上往返。既然有路的信息,就应该按照网络图求最短路径的方式求解。
      

  11.   

    直接怀疑我的语言表达能力了。:(
    其实我的意图很简单的,只需要实现下面的代码所表达的意思即可:
    Dim <...>
    Do While <...>
       If a>b Then
          Call Back()
       Else
          Call GoAhead()
       End If
    Loop
    只是这样的循环如何设计,我想请教各位大侠。非常感谢!
       
      

  12.   

    岔路口队列 = 搜索最短路径(B, A) 'A 点即使不是岔路口,也排在队列最后
    下个岔路口 = 岔路口队列.出列()
    While 下个岔路口 非空
        转向(下个岔路口)
        While Not 到达(下个岔路口) 
            Call GoAhead()
        Wend
        下个岔路口 = 岔路口队列.出列()
    Wend
      

  13.   


    你的车限定在一条线上行使吗?如果是,用不着 X, Y 坐标,仅仅 X 足矣:Dim Xhome As long, Xcar As Long, Distance_Last As LongPrivate Sub Timer1_Timer()
    Dim Distance_Now As Long
        Distance_Now = Abs(Xcar - Xhome)
        If Distance_Now > Distance_Last Then
            Call GoBack()
        Else
            Ball GoAhead()
        End
        Distance_Last = Distance_Now 
    End Sub
      

  14.   

    非常感谢of123 、Tiger_Zhao 两位大侠。of123 已经初步实现了我在本帖提到的意图,而ger_Zhao大侠则准确的知道了我的应用了。:)
    现在我的确需要处理一个岔路口队列的坐标文件,为XML格式储存,需要汽车根据这个文件中的坐标按照顺序行驶到终点,我本来的意图是按顺序读取这些坐标,然后根据汽车当前的坐标和读取到底坐标作对比,看了ger_Zhao大侠的代码觉得更为合理。烦请大侠继续指导一二,感激不尽!
    XML文件格式如下:
    <Point X="139" Y="59">1</Point>
    <Point X="143" Y="57">2</Point>
    <Point X="147" Y="56">3</Point>
    <Point X="151" Y="59">4</Point>
    <Point X="155" Y="59">5</Point>
    试图使汽车从坐标1点按照顺序开到坐标5,如何实现?
      

  15.   


    不写代码了,说说思路。先忘掉你的拐点坐标是什么格式保存的,记住你有 n 个坐标就是了。1 首先取第一个坐标。用你的汽车坐标比对,按上面的方法控制行驶指令。
    2 当到达第一个坐标,则取出第二个坐标,如前操作。
    3 循环,直至到达目的地。其中有些限制条件你还是没有说清楚。
    1 两个目的点之间汽车是否跟随单一的路线,还是在无障碍的大地上自由行驶?如果是后者,需要 X, Y 分别控制。
    2 在拐点处是否需要转向控制?还是汽车沿两点间固定路线自动转向?
      

  16.   

    假定点与点之间都是直线。
    下面的代码是按照 XML 节点可以无序的规则进行查找,如果保证有序可以直接顺序遍历。 
    Option ExplicitPrivate Sub Command1_Click()
        Dim xDoc As MSXML2.DOMDocument
        Dim xNode As MSXML2.IXMLDOMNode
        Dim x As Long, y As Long
        Dim i As Long
        
        Set xDoc = New MSXML2.DOMDocument
        xDoc.Load App.Path & "\Path.xml"
        
        i = 1
        Set xNode = xDoc.selectSingleNode(Replace("//Point[.=""{0}""]", "{0}", i))
        While Not xNode Is Nothing
            x = Val(xNode.selectSingleNode("@X").Text)
            y = Val(xNode.selectSingleNode("@Y").Text)
            If i > 1 Then
                Me.Line -(x, y)
            End If
            Me.Circle (x, y), 1
            
            i = i + 1
            Set xNode = xDoc.selectSingleNode(Replace("//Point[.=""{0}""]", "{0}", i))
        Wend
    End SubPrivate Sub Form_Load()
        Me.AutoRedraw = True
        Me.FillStyle = vbFSSolid
        Me.Scale (100, 0)-(200, 100)
    End Sub