请教三个球在容器内运动的程序?!(2)

liusahara 2011-06-27 05:41:51
接《请教三个球在容器内运动的程序?!》
Private Sub Form1_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.DoubleClick
Dim i As Long
While (True)
For ilal = 0 To 2
Call MyMove(lal(ilal), dx(ilal), dy(ilal))
Next
End While
End Sub
Function MyMove(ByVal label As Label, ByVal movex As Long, ByVal movey As Long) As Long
Dim point(2) As Point
Dim i As Long
Dim hitwallretn As Long
point = GetAllYX()
For idxdy = 0 To 2
If Not NoHitBall(label, point(i)) Then
MoveAfterHitBall(label, point(idxdy), movex, movey, dx(idxdy), dy(idxdy))
End If
hitwallretn = HitWall(label)
If hitwallretn <> 0 Then
MoveAfterHitWall(hitwallretn)
End If
Next
lal(ilal).Left += movex
lal(ilal).Top += movey
Return 0
End Function
Function MoveAfterHitBall(ByVal lal As Label, ByVal pint As Point, ByVal dlx As Long, ByVal dly As Long, ByVal dpx As Long, ByVal dpy As Long) As Long
Dim dz As Long, dtan As Long, dpz As Long
Dim slal As Long, spint As Long
Dim tlalx As Long, tlaly As Long
Dim tpintx As Long, tpinty As Long
Dim nlalx As Long, nlaly As Long
Dim npintx As Long, npinty As Long
Dim angle2 As Long, angle1 As Long, angle3 As Long
Dim angle2l As Long, angle1l As Long, angle3l As Long
angle2 = PI / 2 - Math.Atan(dpz) - Math.Atan(dtan)
angle1 = Math.Atan(dpz)
angle3 = Math.Atan(dtan)
angle1l = Math.Atan(dz)
angle2l = Math.Atan(dz) + Math.Atan(dtan)
angle3l = angle3
slal = Math.Sqrt(dlx ^ 2 + dly ^ 2)
spint = Math.Sqrt(dpx ^ 2 + dpy ^ 2)
If dpy <> 0 Then
dpz = dpx / dpy
End If
If dly <> 0 Then
dz = dlx / dly
End If

If (lal.Left + 25 - pint.X) <> 0 Then
dtan = ((lal.Top + 25 - pint.Y) / (lal.Left + 25 - pint.X))
End If
tpintx = Math.Cos(angle3) * (Math.Cos(angle2) * spint)
tpinty = Math.Sin(angle3) * (Math.Cos(angle2) * spint)
npintx = Math.Cos(PI / 2 - angle3) * (Math.Sin(angle2) * spint)
npinty = Math.Sin(PI / 2 - angle3) * (Math.Sin(angle2) * spint)
tlalx = Math.Cos(angle3l) * (Math.Cos(angle2) * slal)
tlaly = Math.Sin(angle3l) * (Math.Cos(angle2) * slal)
nlalx = Math.Cos(PI / 2 - angle3l) * (Math.Sin(angle2) * slal)
nlaly = Math.Sin(PI / 2 - angle3l) * (Math.Sin(angle2) * slal)
dx(ilal) = nlalx + tpintx
dy(ilal) = nlaly + tpinty
dx(idxdy) = npintx + tlalx
dy(idxdy) = npinty + tlaly
Return 0
End Function
Function MoveAfterHitWall(ByVal wall As Long) As Long
If wall = 1 Or wall = 2 Then
dy(ilal) = -dy(ilal)
ElseIf wall = 3 Or wall = 4 Then
dx(ilal) = -dx(ilal)
End If
Return 0
End Function
Function GetAllYX() As Point()
Dim yx(2) As Point
Dim x(2) As Long
Dim y(2) As Long
x(0) = Label1.Left + 25
y(0) = Label1.Top + 25
x(1) = Label2.Left + 25
y(1) = Label2.Top + 25
x(2) = Label3.Left + 25
y(2) = Label3.Top + 25
yx(0) = New Point(x(0), y(0))
yx(1) = New Point(x(1), y(1))
yx(2) = New Point(x(2), y(2))
GetAllYX = yx
End Function
Function HitWall(ByVal lal As Label) As Long '返回1,撞上了top;返回2,bottom;返回3,left;返回4,right;返回0,为安全状态
If lal.Left <= 0 Then
Return 3
ElseIf lal.Top <= 0 Then
Return 1
ElseIf (lal.Left + 50) >= Me.Width Then
Return 4
ElseIf (lal.Top + 50) >= Me.Height Then
Return 2
Else
Return 0
End If
End Function
Function NoHitBall(ByVal lal As Label, ByVal point1 As Point) As Boolean
Dim point2 As Point
point2 = New Point(lal.Left + 25, lal.Top + 25)
If DistanceTwoDot(point1, point2) > 50 Or DistanceTwoDot(point1, point2) = 0 Then
NoHitBall = True
Else
NoHitBall = False
End If
End Function
Function DistanceTwoDot(ByVal point1 As Point, ByVal point2 As Point) As Long
Dim distance As Long
distance = Math.Sqrt((point1.X - point2.X) ^ 2 + (point1.Y - point2.Y) ^ 2)
DistanceTwoDot = distance
End Function

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
lal(0) = Label1
lal(1) = Label2
lal(2) = Label3
Dim Rnd As New Random()
Dim i As Long
For i = 0 To 2
dx(i) = Rnd.Next(3)
dy(i) = Rnd.Next(3)
Next
Me.Width = 500
Me.Height = 500
dx = -1
dy = -2
dx1 = -2
dy1 = -1

End Sub

Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles button1.Click
Timer1.Interval = 1
Timer1.Enabled = True

End Sub
:
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
point(0) = New Point(Label1.Left + 25, Label1.Top + 25)
point(1) = New Point(Label2.Left + 25, Label2.Top + 25)
distance = Math.Sqrt((point(0).X - point(1).X) ^ 2 + (point(0).Y - point(1).Y) ^ 2)
If distance <= 50 Then
'Label2.Left -= dx1
'Label2.Top -= dy1
If dy1 <> 0 Then
dpz = dx1 / dy1
End If
If dx <> 0 Then
dz = dy / dx
End If
If (point(0).X - point(1).X) <> 0 Then
dtan = ((point(0).Y - point(1).Y) / (point(0).X - point(1).X))
End If
angle2 = PI / 2 - Math.Atan(dpz) - Math.Atan(dtan)
angle1 = Math.Atan(dpz)
angle3 = Math.Atan(dtan)
angle1l = Math.Atan(dz)
angle2l = Math.Atan(dz) + Math.Atan(dtan)
angle3l = angle3
slal = Math.Sqrt(dx ^ 2 + dy ^ 2)
spint = Math.Sqrt(dx1 ^ 2 + dy1 ^ 2)
tpintx = Math.Cos(angle3) * (Math.Cos(angle2) * spint)
tpinty = Math.Sin(angle3) * (Math.Cos(angle2) * spint)
npintx = Math.Cos(PI / 2 - angle3) * (Math.Sin(angle2) * spint)
npinty = Math.Sin(PI / 2 - angle3) * (Math.Sin(angle2) * spint)
tlalx = Math.Cos(angle3l) * (Math.Cos(angle2) * slal)
tlaly = Math.Sin(angle3l) * (Math.Cos(angle2) * slal)
nlalx = Math.Cos(PI / 2 - angle3l) * (Math.Sin(angle2) * slal)
nlaly = Math.Sin(PI / 2 - angle3l) * (Math.Sin(angle2) * slal)
dx = nlalx + tpintx
dy = nlaly + tpinty
dx1 = npintx + tlalx
dy1 = npinty + tlaly
End If

If Label1.Left <= 0 Then
Label1.Left = 0
dx = -dx
ElseIf Label1.Top <= 0 Then
Label1.Top = 0
dy = -dy
ElseIf (Label1.Left + 50) >= 500 Then
Label1.Left = 450
dx = -dx
ElseIf (Label1.Top + 50) >= 500 Then
Label1.Top = 450
dy = -dy
End If
Label1.Left += dx
Label1.Top += dy
If distance <= 50 Then
'Label1.Left -= dx
'Label1.Top -= dy
If dy1 <> 0 Then
dpz = dx1 / dy1
End If
If dx <> 0 Then
dz = dy / dx
End If
If (point(0).X - point(1).X) <> 0 Then
dtan = ((point(0).Y - point(1).Y) / (point(0).X - point(1).X))
End If
angle2 = PI / 2 - Math.Atan(dpz) - Math.Atan(dtan)
angle1 = Math.Atan(dpz)
angle3 = Math.Atan(dtan)
angle1l = Math.Atan(dz)
angle2l = Math.Atan(dz) + Math.Atan(dtan)
angle3l = angle3
slal = Math.Sqrt(dx ^ 2 + dy ^ 2)
spint = Math.Sqrt(dx1 ^ 2 + dy1 ^ 2)
tpintx = Math.Cos(angle3) * (Math.Cos(angle2) * spint)
tpinty = Math.Sin(angle3) * (Math.Cos(angle2) * spint)
npintx = Math.Cos(PI / 2 - angle3) * (Math.Sin(angle2) * spint)
npinty = Math.Sin(PI / 2 - angle3) * (Math.Sin(angle2) * spint)
tlalx = Math.Cos(angle3l) * (Math.Cos(angle2) * slal)
tlaly = Math.Sin(angle3l) * (Math.Cos(angle2) * slal)
nlalx = Math.Cos(PI / 2 - angle3l) * (Math.Sin(angle2) * slal)
nlaly = Math.Sin(PI / 2 - angle3l) * (Math.Sin(angle2) * slal)
dx = nlalx + tpintx
dy = nlaly + tpinty
dx1 = npintx + tlalx
dy1 = npinty + tlaly
End If

If Label2.Left <= 0 Then
Label2.Left = 0
dx1 = -dx1
ElseIf Label2.Top <= 0 Then
Label2.Top = 0
dy1 = -dy1
ElseIf (Label2.Left + 50) >= 500 Then
Label2.Left = 450
dx1 = -dx1
ElseIf (Label2.Top + 50) >= 500 Then
Label2.Top = 450
dy1 = -dy1
End If
Label2.Left += dx1
Label2.Top += dy1
End Sub
End Class
...全文
74 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
yanlongwuhui 2011-06-30
  • 打赏
  • 举报
回复
测试下效果不就知道函数设计的有没有问题了嘛
yanlongwuhui 2011-06-29
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 liusahara 的回复:]
关于球与球碰撞的模拟,涉及动量守恒,动能守恒,向量计算等问题。实现代码在下面的函数中:
Function MoveAfterHitBall(ByVal lal As Label, ByVal pint As Point, ByVal dlx As Long, ByVal dly As Long, ByVal dpx As Long, ByVal dpy As Long) As Long
……
[/Quote]
是考虑到涉及的因素函数不知道怎么写呢,还是函数中有错误?
liusahara 2011-06-29
  • 打赏
  • 举报
回复
//label是一个球,pint参数是另外一个球的球心坐标,dlx是label球的在x轴上的速度,dly是label球的
//在y轴上的速度,dpx是pint球的在x轴上的速度,dpy是pint球的在x轴上的速度
Function MoveAfterHitBall(ByVal lal As Label, ByVal pint As Point, ByVal dlx As Long, ByVal dly As Long, ByVal dpx As Long, ByVal dpy As Long) As Long
Dim dz As Long, dtan As Long, dpz As Long
Dim slal As Long, spint As Long //slal是球label的速度的大小,spint是球pint的速度大小
Dim tlalx As Long, tlaly As Long
Dim tpintx As Long, tpinty As Long //t是两球心的连线上的向量,tpintx为球pint在t向量方向上的速度分量
Dim nlalx As Long, nlaly As Long //nlalx为球label在n向量方向上的速度分量。
Dim npintx As Long, npinty As Long //n是与t向量垂直方向上的向量,npintx为球pint在n向量方向上的速度分量
Dim angle2 As Long, angle1 As Long, angle3 As Long //球pint的三个角
Dim angle2l As Long, angle1l As Long, angle3l As Long //球label的三个角
If dpy <> 0 Then
dpz = dpx / dpy
End If
If dly <> 0 Then
dz = dlx / dly
End If

If (lal.Left + 25 - pint.X) <> 0 Then
dtan = ((lal.Top + 25 - pint.Y) / (lal.Left + 25 - pint.X))
End If
angle2 = PI / 2 - Math.Atan(dpz) - Math.Atan(dtan)
angle1 = Math.Atan(dpz)
angle3 = Math.Atan(dtan)
angle1l = Math.Atan(dz)
angle2l = Math.Atan(dz) + Math.Atan(dtan)
angle3l = angle3
slal = Math.Sqrt(dlx ^ 2 + dly ^ 2)
spint = Math.Sqrt(dpx ^ 2 + dpy ^ 2)
tpintx = Math.Cos(angle3) * (Math.Cos(angle2) * spint)
tpinty = Math.Sin(angle3) * (Math.Cos(angle2) * spint)
npintx = Math.Cos(PI / 2 - angle3) * (Math.Sin(angle2) * spint)
npinty = Math.Sin(PI / 2 - angle3) * (Math.Sin(angle2) * spint)
tlalx = Math.Cos(angle3l) * (Math.Cos(angle2) * slal)
tlaly = Math.Sin(angle3l) * (Math.Cos(angle2) * slal)
nlalx = Math.Cos(PI / 2 - angle3l) * (Math.Sin(angle2) * slal)
nlaly = Math.Sin(PI / 2 - angle3l) * (Math.Sin(angle2) * slal)
dx(ilal) = nlalx + tpintx
dy(ilal) = nlaly + tpinty
dx(idxdy) = npintx + tlalx
dy(idxdy) = npinty + tlaly
Return 0
End Function
liusahara 2011-06-29
  • 打赏
  • 举报
回复
关于球与球碰撞的模拟,涉及动量守恒,动能守恒,向量计算等问题。实现代码在下面的函数中:
Function MoveAfterHitBall(ByVal lal As Label, ByVal pint As Point, ByVal dlx As Long, ByVal dly As Long, ByVal dpx As Long, ByVal dpy As Long) As Long
Dim dz As Long, dtan As Long, dpz As Long
Dim slal As Long, spint As Long
Dim tlalx As Long, tlaly As Long
Dim tpintx As Long, tpinty As Long
Dim nlalx As Long, nlaly As Long
Dim npintx As Long, npinty As Long
Dim angle2 As Long, angle1 As Long, angle3 As Long
Dim angle2l As Long, angle1l As Long, angle3l As Long
angle2 = PI / 2 - Math.Atan(dpz) - Math.Atan(dtan)
angle1 = Math.Atan(dpz)
angle3 = Math.Atan(dtan)
angle1l = Math.Atan(dz)
angle2l = Math.Atan(dz) + Math.Atan(dtan)
angle3l = angle3
slal = Math.Sqrt(dlx ^ 2 + dly ^ 2)
spint = Math.Sqrt(dpx ^ 2 + dpy ^ 2)
If dpy <> 0 Then
dpz = dpx / dpy
End If
If dly <> 0 Then
dz = dlx / dly
End If

If (lal.Left + 25 - pint.X) <> 0 Then
dtan = ((lal.Top + 25 - pint.Y) / (lal.Left + 25 - pint.X))
End If
tpintx = Math.Cos(angle3) * (Math.Cos(angle2) * spint)
tpinty = Math.Sin(angle3) * (Math.Cos(angle2) * spint)
npintx = Math.Cos(PI / 2 - angle3) * (Math.Sin(angle2) * spint)
npinty = Math.Sin(PI / 2 - angle3) * (Math.Sin(angle2) * spint)
tlalx = Math.Cos(angle3l) * (Math.Cos(angle2) * slal)
tlaly = Math.Sin(angle3l) * (Math.Cos(angle2) * slal)
nlalx = Math.Cos(PI / 2 - angle3l) * (Math.Sin(angle2) * slal)
nlaly = Math.Sin(PI / 2 - angle3l) * (Math.Sin(angle2) * slal)
dx(ilal) = nlalx + tpintx
dy(ilal) = nlaly + tpinty
dx(idxdy) = npintx + tlalx
dy(idxdy) = npinty + tlaly
Return 0
End Function
运行的时候有问题,不晓得哪里出问题了,计算有问题?
liusahara 2011-06-29
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 yanlongwuhui 的回复:]
引用 2 楼 liusahara 的回复:
关于球与球碰撞的模拟,涉及动量守恒,动能守恒,向量计算等问题。实现代码在下面的函数中:
Function MoveAfterHitBall(ByVal lal As Label, ByVal pint As Point, ByVal dlx As Long, ByVal dly As Long, ByVal dpx As Long, ByVal dp……
[/Quote]

函数写了,两个球质量相等,相撞后在t向量上的速度交换,也实现了,但是运行时有问题,不知道向量的方向搞清楚了不
cosmo_sei 2011-06-28
  • 打赏
  • 举报
回复
接上上一个帖子代码还是不完全的。
最关键的问题是:问题不突出,若不细细研读每一行代码,我甚至不知道这是在干啥。
如果能够缩小问题的范围请将其指出来并缩短代码的长度,建议这么做。

16,556

社区成员

发帖
与我相关
我的任务
社区描述
VB技术相关讨论,主要为经典vb,即VB6.0
社区管理员
  • VB.NET
  • 水哥阿乐
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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