游戏开发论坛

 找回密码
 立即注册
搜索
查看: 7241|回复: 26

请教数学问题

[复制链接]

11

主题

145

帖子

176

积分

注册会员

Rank: 2

积分
176
发表于 2008-8-6 08:56:00 | 显示全部楼层 |阅读模式
有一个茶壶,我们假设它只在2维方向上移动与旋转,即x,z上移动。
它会向前走与转动,它会向它所面向的方向前进。
即:已知其面对角度,求其在某时间上的坐标。
我查阅了一些类似的代码,都是这样写的(使用360角度制。):
If input1.IsKeyPressed(TV_KEY_UP) = True Then  '当按上键时茶壶前进
   tea_posx = tea_posx + Cos(tea_roty) * engine1.TimeElapsed * 0.2
   tea_posz = tea_posz + Sin(tea_roty) * engine1.TimeElapsed * 0.2
   teapot1.SetPosition tea_posx, 0, tea_posz
End if
其中:tea_posx,tea_posz为茶壶的坐标,tea_roty为茶壶当前的旋转方向,engine1.timeelapsed为时间流逝。
已经尝试过将tea_roty改为弧度制,也尝试过使用C代码:
tea_posx = tea_posx + Cosf(tea_roty) * engine1->TimeElapsed * 0.2
tea_posz = tea_posz + Sinf(tea_roty) * engine1->TimeElapsed * 0.2
teapot1.SetPosition tea_posx, 0, tea_posz
结果:
茶壶并没有向着面对的方向前进,甚至当旋转角度变化时不向固定的角度前进。
希望大家能帮忙解决这个问题,我的算法有问题吗?用任何语言甚至思路回答均可,谢谢。
sf_2008868560.jpg

0

主题

386

帖子

400

积分

中级会员

Rank: 3Rank: 3

积分
400
QQ
发表于 2008-8-6 09:27:00 | 显示全部楼层

Re:请教数学问题

不知道。。我用这种代码做的不向前走,向右走。

11

主题

145

帖子

176

积分

注册会员

Rank: 2

积分
176
 楼主| 发表于 2008-8-6 09:44:00 | 显示全部楼层

Re:请教数学问题

那就正需要解决三,因为所有的动物和机械都遵从一个运动原则:向前走。螃蟹除外。

0

主题

8

帖子

8

积分

新手上路

Rank: 1

积分
8
发表于 2008-8-6 09:53:00 | 显示全部楼层

Re:请教数学问题

这样写

If input1.IsKeyPressed(TV_KEY_UP) = True Then  '当按上键时茶壶前进
   tea_posx = tea_posx + Cos(tea_roty*3.14/180) * engine1.TimeElapsed * 0.2
   tea_posz = tea_posz + Sin(tea_roty*3.14/180) * engine1.TimeElapsed * 0.2
   teapot1.SetPosition tea_posx, 0, tea_posz
End if

11

主题

145

帖子

176

积分

注册会员

Rank: 2

积分
176
 楼主| 发表于 2008-8-6 10:30:00 | 显示全部楼层

Re:请教数学问题

不对,我已经实验过用弧度了,但是仍然不正确。

0

主题

22

帖子

22

积分

注册会员

Rank: 2

积分
22
发表于 2008-8-6 13:56:00 | 显示全部楼层

Re:请教数学问题

拜托,你的路径极坐标算法是没有问题的,但是你取得角度不对,尝试
tea_posx = tea_posx + Cos(tea_roty+90) * engine1.TimeElapsed * 0.2
   tea_posz = tea_posz + Sin(tea_roty+90) * engine1.TimeElapsed * 0.2
也就是角度+或-pi/2

270

主题

6442

帖子

6446

积分

论坛元老

Rank: 8Rank: 8

积分
6446
发表于 2008-8-6 14:22:00 | 显示全部楼层

Re:请教数学问题

滴血玉玺和五星勋章3里的是不是?

11

主题

145

帖子

176

积分

注册会员

Rank: 2

积分
176
 楼主| 发表于 2008-8-6 15:56:00 | 显示全部楼层

Re:请教数学问题

你说旋转90度或者其他某个固定的度数就行了?但是根本不是这样,比如我假设茶壶嘴对准的方向为前,而茶壶不管怎么转却总是向茶壶左翼运动,那么就用你说的这个办法就解决了。但问题是我使用该公式时,茶壶的运动方向根本就不是固定向某个方向运动的,而是(假设)当我旋转56度时,茶壶向前运动;当我旋转62度时,茶壶又向左运动。

Re:请教数学问题
滴血玉玺和五星勋章3里的是不是?
后者里面那个坦克战时,坦克底座无论怎样旋转,只能向前走,对吧。
记得62下面有个例子,就是一个怪物在血地里行走的例子,无论怎样旋转,旋转完后,它总可以向停下来面对着的那个方向前进。
可惜,现在因为担心再装62可能妨碍65的运行,所以无法重装62,也就看不到那个例子的代码了,不知道那里面是不是算法也是这样的。

270

主题

6442

帖子

6446

积分

论坛元老

Rank: 8Rank: 8

积分
6446
发表于 2008-8-6 16:31:00 | 显示全部楼层

Re:请教数学问题

bc=步长,ANG2=自己的角度,ANG=场景角度,70和30场景的视角范围

If Inp.IsKeyPressed(TV_KEY_W) = True Then
MYPos.X = MYPos.X + Cos(ANG2) * TV3D.TimeElapsed * bc
MYPos.Z = MYPos.Z + Sin(ANG2) * TV3D.TimeElapsed * bc
End if

If Inp.IsKeyPressed(TV_KEY_S) = True Then
MYPos.X = MYPos.X - Cos(ANG2) * TV3D.TimeElapsed * bc
MYPos.Z = MYPos.Z - Sin(ANG2) * TV3D.TimeElapsed * bc
End If

If Inp.IsKeyPressed(TV_KEY_D) = True Then ang = ang + TV3D.TimeElapsed * 0.002
If Inp.IsKeyPressed(TV_KEY_A) = True Then ang = ang - TV3D.TimeElapsed * 0.002

X1 = MYPos.X - (Cos(ang) * 70)
Z1 = MYPos.Z - (Sin(ang) * 70)
Y1 = Land.GetHeight(X1, Z1) + 30
Scene.SetCamera X1, Y1, Z1, MYPos.X + Cos(ang), MYPos.Y, MYPos.Z + Sin(ang)

11

主题

145

帖子

176

积分

注册会员

Rank: 2

积分
176
 楼主| 发表于 2008-8-6 16:48:00 | 显示全部楼层

Re:请教数学问题

已经完全照你说的改了,但是还是不正确,这是一个普通model,里面类名称跟62略有出入。
茶壶仍在乱转。

Public engine1 As TVEngine
Public scene1 As TVScene
Public input1 As TVInputEngine
Public atmos1 As TVAtmosphere
Public fac1 As TVTextureFactory
Public mesh1 As TVMesh
Public imt1 As TVScreen2DImmediate
Public land1 As TVLandscape
Public bDoLoop As Boolean
Public sngWalk                  As Single
Public sngStrafe                As Single
Public sngAngleX                As Single
Public sngAngleY                As Single
Public me_updown                As Single
Public tea_rotx, tea_roty, tea_rotz As Single '茶壶转向
Public tea_posx, tea_posy, tea_posz As Single '茶壶位置
Public CamPos As TV_3DVECTOR
Public CamLookAt As TV_3DVECTOR

Public Function Init_Engine()
  Set engine1 = New TVEngine
  engine1.SetDebugMode False, False
  engine1.Init3DWindowed FormMove.Pic1.hWnd, True
  engine1.DisplayFPS True
  engine1.SetAngleSystem TV_ANGLE_DEGREE
  Set fac1 = New TVTextureFactory
  Set scene1 = New TVScene
  Set atmos1 = New TVAtmosphere
  Set input1 = New TVInputEngine
  Set mesh1 = New TVMesh
  Set land1 = New TVLandscape
  Set land1 = scene1.CreateLandscape("vv")
  Set imt1 = New TVScreen2DImmediate
  input1.Initialize True, True
  fac1.LoadTexture "skybox\up.jpg", "up"
  fac1.LoadTexture "skybox\dn.jpg", "down"
  fac1.LoadTexture "skybox\lf.jpg", "left"
  fac1.LoadTexture "skybox\rt.jpg", "right"
  fac1.LoadTexture "skybox\ft.jpg", "front"
  fac1.LoadTexture "skybox\bk.jpg", "back"
  atmos1.SkyBox_Enable True
  atmos1.SkyBox_SetTexture GetTex("front"), GetTex("back"), GetTex("left"), GetTex("right"), GetTex("up"), GetTex("down")

  Set mesh1 = scene1.CreateMeshBuilder("cool")
  mesh1.CreateTeapot
  mesh1.SetPosition 0, 0, 3
  mesh1.SetScale 10, 10, 10
  mesh1.SetRotation 0, 0, 0
  mesh1.SetPosition 0, 0, 0
  scene1.SetCamera 0, 0, 0, 0, 0, 3
  bDoLoop = True
End Function

Public Function Loop_Engine()
Dim i, j As Single
Do While bDoLoop
        engine1.Clear False
        scene1.RenderAllMeshes True
        land1.Render
        atmos1.SkyBox_Render
        check_input
        For i = 0 To 30
        imt1.Action_Begin2D  '网格画线
            imt1.Draw_Line3D i * 50, 0, 0, (i + 1) * 50, 0, 1000
            imt1.Draw_Line3D 0, 0, i * 50, 1000, 0, (i + 1) * 50
        imt1.Action_End2D
        Next
        engine1.RenderToScreen
        
    DoEvents
  Loop
End Function
Public Function check_input()

Dim tmpMouseX As Long, tmpMouseY As Long
Dim tmpMouseB1 As Boolean, tmpMouseB2 As Boolean, tmpMouseB3 As Boolean, tmpMouseB4 As Boolean
Dim tmpMouseScrollOld As Long, tmpMouseScrollNew As Long
tmpMouseScrollOld = tmpMouseScrollNew

input1.GetMouseState tmpMouseX, tmpMouseY, tmpMouseB1, tmpMouseB2, tmpMouseB3, tmpMouseB4, tmpMouseScrollNew

sngAngleX = sngAngleX - (tmpMouseY / 100)
sngAngleY = sngAngleY - (tmpMouseX / 100)
sngAngleX = sngAngleX - (tmpMouseY / 100)
sngAngleY = sngAngleY - (tmpMouseX / 100)
               
        If input1.IsKeyPressed(TV_KEY_ESCAPE) = True Then DoLoop = False
        
        If input1.IsKeyPressed(TV_KEY_W) = True Then
            sngWalk = 1
        ElseIf input1.IsKeyPressed(TV_KEY_S) = True Then
            sngWalk = -1
        End If

        If input1.IsKeyPressed(TV_KEY_A) = True Then
            sngStrafe = 1
        ElseIf input1.IsKeyPressed(TV_KEY_D) = True Then
            sngStrafe = -1
        End If
        If input1.IsKeyPressed(TV_KEY_C) = True Then
            me_updown = -1
        End If
       '以下为出错部分
        If input1.IsKeyPressed(TV_KEY_LEFT) = True Then
            tea_roty = tea_roty - engine1.TimeElapsed * 0.2
            mesh1.SetRotation 0, tea_roty, 0
        End If
        If input1.IsKeyPressed(TV_KEY_RIGHT) = True Then
            tea_roty = tea_roty + engine1.TimeElapsed * 0.2
            mesh1.SetRotation 0, tea_roty, 0
        End If
        If input1.IsKeyPressed(TV_KEY_UP) = True Then
            tea_posx = tea_posx + Cos(tea_roty) * engine1.TimeElapsed * 0.2
            tea_posz = tea_posz + Sin(tea_roty) * engine1.TimeElapsed * 0.2
            mesh1.SetPosition tea_posx, 0, tea_posz
        End If
        If input1.IsKeyPressed(TV_KEY_DOWN) = True Then
            tea_posx = tea_posx - Cos(tea_roty) * engine1.TimeElapsed * 0.2
            tea_posz = tea_posz - Sin(tea_roty) * engine1.TimeElapsed * 0.2
            mesh1.SetPosition tea_posx, 0, tea_posz
        End If
'以上为运算出错部分        
        If input1.IsKeyPressed(TV_KEY_ESCAPE) = True Then
            bDoLoop = False
        End If
        If input1.IsKeyPressed(TV_KEY_SPACE) = True Then
            me_updown = 1
        End If
        
        If sngAngleX > 1.3 Then sngAngleX = 1.3
        If sngAngleX < -1.3 Then sngAngleX = -1.3
        
        Select Case sngWalk
        Case Is > 0
            sngWalk = sngWalk - 0.005 * engine1.TimeElapsed
            If sngWalk < 0 Then sngWalk = 0
        Case Is < 0
            sngWalk = sngWalk + 0.005 * engine1.TimeElapsed
            If sngWalk > 0 Then sngWalk = 0
        End Select
        
        Select Case sngStrafe
        Case Is > 0
            sngStrafe = sngStrafe - 0.005 * engine1.TimeElapsed
            If sngStrafe < 0 Then sngStrafe = 0
        Case Is < 0
            sngStrafe = sngStrafe + 0.005 * engine1.TimeElapsed
            If sngStrafe > 0 Then sngStrafe = 0
        End Select
        
        CamPos.x = CamPos.x + (Cos(sngAngleY) * sngWalk / 2 * engine1.TimeElapsed) + (Cos(sngAngleY + 3.141596 / 2) * sngStrafe / 2 * engine1.TimeElapsed)
        CamPos.z = CamPos.z + (Sin(sngAngleY) * sngWalk / 2 * engine1.TimeElapsed) + (Sin(sngAngleY + 3.141596 / 2) * sngStrafe / 2 * engine1.TimeElapsed)
        CamPos.y = CamPos.y + me_updown * 10
        me_updown = 0
        CamLookAt.x = CamPos.x + Cos(sngAngleY)
        CamLookAt.y = CamPos.y + Tan(sngAngleX)
        CamLookAt.z = CamPos.z + Sin(sngAngleY)
        scene1.SetCamera CamPos.x, CamPos.y, CamPos.z, CamLookAt.x, CamLookAt.y, CamLookAt.z

End Function
Public Function Unload_Engine()
Set engine1 = Nothing
End Function
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-21 17:49

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表