3d TI基本光线投射(TI-83 Plus)

3d TI基本光线投射(TI-83 Plus),3d,ti-basic,3d,Ti Basic,我一直在关注这条线索: 我什么都试过了。如何在TI Basic中进行光线投射,是否可以只画一个简单的墙并四处移动?我有一个TI-83 Plus。可以用TI-83 Basic进行光线投射吗是;让我们试试看 首先,光线投射到底是什么? 光线投射是一个术语,用于描述渲染三维图形的一组算法。光线投射算法的共同点是: 从一个点向不同方向发出光线 计算与该光线相交的最近对象 渲染该对象与光线相交的部分,其位置取决于光线的方向 对于TI-83,我们将实现一个只发送水平光线的简单光线投射器。从自上而下的角度来看

我一直在关注这条线索:


我什么都试过了。如何在TI Basic中进行光线投射,是否可以只画一个简单的墙并四处移动?我有一个TI-83 Plus。

可以用TI-83 Basic进行光线投射吗;让我们试试看

首先,光线投射到底是什么? 光线投射是一个术语,用于描述渲染三维图形的一组算法。光线投射算法的共同点是:

  • 从一个点向不同方向发出光线
  • 计算与该光线相交的最近对象
  • 渲染该对象与光线相交的部分,其位置取决于光线的方向
  • 对于TI-83,我们将实现一个只发送水平光线的简单光线投射器。从自上而下的角度来看,它可能如下所示:

    当然,如果我们想要一个像样的图像,我们需要使用5条以上的光线。现在我们已经定义了要实现的内容,让我们继续了解如何实现

    我们需要跟踪哪些价值观? 这很容易。我们需要跟踪的值在光线投射算法中是正确的

    • 我们需要跟踪光线。具体来说,我们需要知道他们的方向
    • 我们需要跟踪光线的来源,或者摄像机的位置
    • 我们需要跟踪所有“对象”的位置。为了简单起见,我们将只跟踪墙
    现在,下一部分也很简单。我们如何跟踪这些价值观?因为有一束光线,我们将它们的方向存储在一个列表中,
    L₁。另一方面,由于只有一个摄像头,我们将它的位置存储在两个变量中,
    s
    T
    (因为它们正好位于TI-83键盘的X和Y上方。我们希望使用X和Y,但这些变量会被稍后使用的行操作修改)。墙壁为我们提供了更多选项,但为了简单起见,我们将存储一个表示楼层平面的矩阵。如果矩阵中的某个位置有一个非零的数字,这意味着在世界上相应的位置有一堵墙。我们会说矩阵中的每个值对应于世界上的1×1位置

    我们如何处理这些价值观? 现在,我们知道了需要存储哪些值(这些值称为我们的模型),我们需要弄清楚我们实际需要如何处理它们。换句话说,我们需要详细说明光线投射算法

    在我们做任何事情之前,我们需要为所有值设置初始状态。我们将使用
    [A]
    的内容获取地图信息。相机的起始位置是任意的,所以我们将它设置在(1.5,1.5),正好在第一个瓦片的中间。

    在讨论光线的方向之前,我们需要决定使用多少光线。理想情况下,每个像素至少使用一条光线,但TI-83的水平分辨率为96像素,使用96条光线可能会导致光线投射器太慢。相反,我们将使用24条光线,或者每4个像素使用一条光线。这应该给我们一个合理的图像质量,同时希望不是太多的TI-83处理。我们还需要选择一个视野。我们将选择96°,因为这意味着一个像素代表1°。最后,我们将说中间的光线开始指向水平线以下45°

    现在,回到算法。通过考虑一般光线投射算法如何应用于我们的模型,我们得到以下步骤:

  • 设置图形屏幕
  • S
    T
    设置为1.5
  • 获取地图的宽度和高度
  • 计算每条光线的初始方向
  • 运行时循环这些选项:
  • 对于每条射线:
  • 计算它是否与墙相交
  • 如果有,在屏幕上画一条代表墙的垂直线
  • 如果紧迫▲ 前进,;否则,如果按▼, 后退
  • 如果紧迫◀, 左转否则,如果按▶, 右转
  • 如果按CLEAR,则停止运行
  • 让我们逐一解决这些问题

    实施 1.设置图形屏幕 我们需要关闭图形轴并设置限制。我们将在第5.2.2部分中了解这些限制的原因

    AxesOff
    4 → Xmin
    24 * 4 + 3 → Xmax
    -1 → Ymin
    1 → Ymax
    
    2.将
    S
    T
    设置为1.5 简单:

    3.获取地图的宽度和高度 4.计算每条光线的初始方向 不错:

    seq((I - 12.5) * 4° + 45°, I, 1, 24) → L₁
    
    5.运行时循环这些选项: 5.1. 对于每条射线: 5.1.1. 计算它是否与墙相交 这是第一个非常棘手的部分。基本上,我们将从摄像机开始,然后沿着光线一块一块地向外移动,直到我们撞到墙或者离开地图。如果我们撞到墙,我们会将
    C
    (用于碰撞)设置为1

    在while循环中:

    • U和V表示光线跟踪的当前位置
    • 第一个If-Else块检查光线指向哪个象限。然后,基于象限,它将U和V的预期下一个值存储到P和Q中。基本上,它水平跟踪光线到下一个磁贴,并将其存储到P中,垂直跟踪光线到下一个磁贴,并将其存储到Q中
    • 下一个If-Else块确定P或Q是否是正确的预期值。无论哪一个能缩短旅行距离,都是正确的猜测。如果我们选长的,我们会跳过一块瓷砖。由于trig函数的对称性,新的U和V值可以从P和Q计算,而不考虑象限。该块中的台阶距离也会更新。稍后我们将使用距离来确定绘制线的高度
    • 最后,最后一个if语句测试当前块是否为墙。如果是,则设置C以停止光线跟踪
    如果这部分不清楚,让我知道,我可以添加一个图表

    0 → C
    S → U
    T → V
    0 → D
    While C = 0 and 1 ≤ int(U) and int(U) ≤ W and 1 ≤ int(V) and int(V) ≤ H
        L₁(I) → A
        If A > 0° :Then
            If A > 90° :Then
                -int(-U - 1) → P
                int(V + 1) → Q
            Else
                int(U + 1) → P
                int(V + 1) → Q
            End
        Else
            If A > -90° :Then
                int(U + 1) → P
                -int(-V - 1) → Q
            Else
                -int(-U - 1) → P
                -int(-V - 1) → Q
            End
        End
        If abs((P - U) / cos(A)) < abs((Q - V) / sin(A)) :Then
            D + abs((P - U) / cos(A)) → D
            V + (P - U) * tan(A) → V
            P → U
        Else
            D + abs((Q - V) / sin(A)) → D
            U + (Q - V) / tan(A) → U
            Q → V
        End
        If int(U) ≥ 1 and int(U) ≤ W and int(V) ≥ 1 and int(V) ≤ H :Then
            If [A](int(U), int(V))
            1 → C
        End
        If -int(-U + 1) ≥ 1 and -int(-U + 1) ≤ W and -int(-V + 1) ≥ 1 and -int(-V + 1) ≤ H :Then
            If [A](-int(-U + 1), -int(-V + 1))
            1 → C
        End
    End
    
    I * 4 → N
    Line(N, 1, N, -1, 0)
    Line(N + 1, 1, N + 1, -1, 0)
    Line(N + 2, 1, N + 2, -1, 0)
    Line(N + 3, 1, N + 3, -1, 0)
    If C :Then
        tan⁻¹(([A](int(U), int(V)) + [A](-int(-U + 1), -int(-V + 1))) / D) / 32° → Z
        Line(N, Z, N, -Z)
        Line(N + 1, Z, N + 1, -Z)
        Line(N + 2, Z, N + 2, -Z)
        Line(N + 3, Z, N + 3, -Z)
    End
    
    5.2. 如果紧迫▲ 前进,;否则,如果按▼, 后退 这一部分和下一部分都很简单。F是摄影机i的角度
    1 → R
    While R
        ...
    End
    
    For(I, 1, 24)
        ...
    End
    
    0 → C
    S → U
    T → V
    0 → D
    While C = 0 and 1 ≤ int(U) and int(U) ≤ W and 1 ≤ int(V) and int(V) ≤ H
        L₁(I) → A
        If A > 0° :Then
            If A > 90° :Then
                -int(-U - 1) → P
                int(V + 1) → Q
            Else
                int(U + 1) → P
                int(V + 1) → Q
            End
        Else
            If A > -90° :Then
                int(U + 1) → P
                -int(-V - 1) → Q
            Else
                -int(-U - 1) → P
                -int(-V - 1) → Q
            End
        End
        If abs((P - U) / cos(A)) < abs((Q - V) / sin(A)) :Then
            D + abs((P - U) / cos(A)) → D
            V + (P - U) * tan(A) → V
            P → U
        Else
            D + abs((Q - V) / sin(A)) → D
            U + (Q - V) / tan(A) → U
            Q → V
        End
        If int(U) ≥ 1 and int(U) ≤ W and int(V) ≥ 1 and int(V) ≤ H :Then
            If [A](int(U), int(V))
            1 → C
        End
        If -int(-U + 1) ≥ 1 and -int(-U + 1) ≤ W and -int(-V + 1) ≥ 1 and -int(-V + 1) ≤ H :Then
            If [A](-int(-U + 1), -int(-V + 1))
            1 → C
        End
    End
    
    I * 4 → N
    Line(N, 1, N, -1, 0)
    Line(N + 1, 1, N + 1, -1, 0)
    Line(N + 2, 1, N + 2, -1, 0)
    Line(N + 3, 1, N + 3, -1, 0)
    If C :Then
        tan⁻¹(([A](int(U), int(V)) + [A](-int(-U + 1), -int(-V + 1))) / D) / 32° → Z
        Line(N, Z, N, -Z)
        Line(N + 1, Z, N + 1, -Z)
        Line(N + 2, Z, N + 2, -Z)
        Line(N + 3, Z, N + 3, -Z)
    End
    
    getKey → K
    (L₁(12) + L₁(13)) / 2 → F
    If K = 25 :Then
        S + 0.1 * cos(F) → S
        T + 0.1 * sin(F) → T
    End
    If K = 34 :Then
        S - 0.1 * cos(F) → S
        T - 0.1 * sin(F) → T
    End
    
    If K = 24 :Then
        L₁ + 2° → L₁
    End
    If K = 26 :Then
        L₁ - 2° → L₁
    End
    
    If K = 45
    0 → R
    
    AxesOff
    4→Xmin
    24*4+3→Xmax
    -1→Ymin
    1→Ymax
    1.5→S
    1.5→T
    dim([A])→L₁
    L₁(1)→H
    L₁(2)→W
    seq((I-12.5)*4°+45°,I,1,24)→L₁
    1→R
    While R
    For(I,1,24)
    0→C
    S→U
    T→V
    0→D
    While C=0 and 1≤int(U) and int(U)≤W and 1≤int(V) and int(V)≤H
    L₁(I)→A
    If A>0°:Then
    If A>90°:Then
    -int(-U-1)→P
    int(V+1)→Q
    Else
    int(U+1)→P
    int(V+1)→Q
    End
    Else
    If A>-90°:Then
    int(U+1)→P
    -int(-V-1)→Q
    Else
    -int(-U-1)→P
    -int(-V-1)→Q
    End
    End
    If abs((P-U)/cos(A))<abs((Q-V)/sin(A)):Then
    D+abs((P-U)/cos(A))→D
    V+(P-U)*tan(A)→V
    P→U
    Else
    D+abs((Q-V)/sin(A))→D
    U+(Q-V)/tan(A)→U
    Q→V
    End
    If int(U)≥1 and int(U)≤W and int(V)≥1 and int(V)≤H:Then
    If [A](int(U),int(V))
    1→C
    End
    If -int(-U+1)≥1 and -int(-U+1)≤W and -int(-V+1)≥1 and -int(-V+1)≤H:Then
    If [A](-int(-U+1),-int(-V+1))
    1→C
    End
    End
    I*4→N
    Line(N,1,N,-1,0)
    Line(N+1,1,N+1,-1,0)
    Line(N+2,1,N+2,-1,0)
    Line(N+3,1,N+3,-1,0)
    If C:Then
    tan⁻¹(([A](int(U),int(V))+[A](-int(-U+1),-int(-V+1)))/D)/32°→Z
    Line(N,Z,N,-Z)
    Line(N+1,Z,N+1,-Z)
    Line(N+2,Z,N+2,-Z)
    Line(N+3,Z,N+3,-Z)
    End
    End
    getKey→K
    (L₁(12)+L₁(13))/2→F
    If K=25:Then
    S+0.1*cos(F)→S
    T+0.1*sin(F)→T
    End
    If K=34:Then
    S-0.1*cos(F)→S
    T-0.1*sin(F)→T
    End
    If K=24:Then
    L₁+2°→L₁
    End
    If K=26:Then
    L₁-2°→L₁
    End
    If K=45
    0→R
    End