【问题标题】:MIPS: Midpoint Circle AlgorithmMIPS:中点圆算法
【发布时间】:2018-11-11 09:40:49
【问题描述】:

我正在尝试使用 MARS 在位图中绘制一个圆圈。我已经从维基百科转换了 c 公式,但是我得到的结果是错误的。我认为我的转换存在错误,但我终其一生都无法弄清楚它是什么。

#Procedure: drawCircle:
#Draw a circle in the center of the input pixel (This will be implemented using the 
#midpoint circle algorithm from https://en.wikipedia.org/wiki/Midpoint_circle_algorithm
#a0 = x0
#a1 = y0
#a2 = color
#a3 = radius
drawCircle:
    #MAKE ROOM ON STACK
    addi        $sp, $sp, -20       #Make room on stack for 1 words
    sw      $ra, 0($sp)     #Store $ra on element 0 of stack
    sw      $a0, 4($sp)     #Store $a0 on element 1 of stack
    sw      $a1, 8($sp)     #Store $a1 on element 2 of stack
    sw      $a2, 12($sp)        #Store $a1 on element 3 of stack
    sw      $a3, 16($sp)        #Store $a1 on element 4 of stack

    #VARIABLES
    move        $t0, $a0            #x0
    move        $t1, $a1            #y0
    move        $t2, $a3            #radius
    addi        $t3, $t2, -1            #x
    li      $t4, 0              #y
    li      $t5, 1              #dx
    li      $t6, 1              #dy
    li      $t7, 0              #Err

    #CALCULATE ERR (dx - (radius << 1))
    sll         $t8, $t2, 1         #Bitshift radius left 1 
    subu        $t7, $t5, $t8           #Subtract dx - shifted radius 

    #While(x >= y)
    circleLoop:
    blt         $t3, $t4, skipCircleLoop    #If x < y, skip circleLoop

    #Draw Dot (x0 + x, y0 + y)
    addu        $a0, $t0, $t3
    addu        $a1, $t1, $t4
    lw          $a2, 12($sp)
    jal         drawDot             #Jump to drawDot

        #Draw Dot (x0 + y, y0 + x)
        addu        $a0, $t0, $t4
        addu        $a1, $t1, $t3
        lw      $a2, 12($sp)
        jal     drawDot             #Jump to drawDot

        #Draw Dot (x0 - y, y0 + x)
        subu        $a0, $t0, $t4
        addu        $a1, $t1, $t3
        lw      $a2, 12($sp)
        jal     drawDot             #Jump to drawDot

        #Draw Dot (x0 - x, y0 + y)
        subu        $a0, $t0, $t3
        addu        $a1, $t1, $t4
        lw      $a2, 12($sp)
        jal     drawDot             #Jump to drawDot

        #Draw Dot (x0 - x, y0 - y)
        subu        $a0, $t0, $t3
        subu        $a1, $t1, $t4
        lw      $a2, 12($sp)
        jal     drawDot             #Jump to drawDot

        #Draw Dot (x0 - y, y0 - x)
        subu        $a0, $t0, $t4
        subu        $a1, $t1, $t3
        lw      $a2, 12($sp)
        jal     drawDot             #Jump to drawDot

        #Draw Dot (x0 + y, y0 - x)
        addu        $a0, $t0, $t4
        subu        $a1, $t1, $t3
        lw      $a2, 12($sp)
        jal     drawDot             #Jump to drawDot

        #Draw Dot (x0 + x, y0 - y)
        addu        $a0, $t0, $t3
        subu        $a1, $t1, $t4
        lw      $a2, 12($sp)
        jal     drawDot             #Jump to drawDot

    #If (err <= 0)
    bgtz        $t7, doElse
    addi        $t4, $t4, 1     #y++
    addu        $t7, $t7, $t6       #err += dy
    addi        $t6, $t6, 2     #dy += 2
    j       circleContinue      #Skip else stmt

    #Else If (err > 0)
    doElse:
    addi        $t3, $t3, -1        #x--
    addi        $t5, $t5, 2     #dx += 2
    sll     $t8, $t2, 1     #Bitshift radius left 1 
    subu        $t9, $t5, $t8       #Subtract dx - shifted radius 
    addu        $t7, $t7, $t9       #err += $t9

    circleContinue:
    #LOOP
    j       circleLoop

    #CONTINUE
    skipCircleLoop:     

    #RESTORE $RA
    lw      $ra, 0($sp)     #Restore $ra from stack
    addi        $sp, $sp, 20        #Readjust stack

我调用的所有程序都没有更改任何 t 寄存器。我得到以下值的结果:x = 10 y = 10 color = 5 radius = 10

【问题讨论】:

  • 您是否在调试器中单步执行了您的代码,以查找寄存器值与您的预期不符的位置?
  • @PeterCordes 是的,我现在还在做这件事,因为有很多价值观。到目前为止,什么都没有引起我的注意。我只是想确保我在转换中没有犯明显的错误。我注意到的一件事是第一个和第二个 drawDots 相距很远,这似乎不正确。
  • 这里有点奇怪,当绘制第一个和第二个点的坐标时,它们分别是 10, 19 和 19, 10。绘制时,一个在位图的左半边绘制,另一个在右半边绘制。
  • drawDot 代码在哪里? ......啊,你同时想通了......是的,位图的大小确实看起来不错,因为用错误的宽度大小计算目标地址将使y坐标以可预测的方式“环绕”到所有地方(就像在您期望 256x256 时绘制成 512x512 一样,每隔一条线位于图片的右半部分,而奇数行位于左侧,总图片是所需大小的一半,仅使用 512x128 区域)

标签: assembly bitmap mips32 mars-simulator


【解决方案1】:

我想我已经明白了。问题不在于转换,而在于位图的大小。似乎当位图太小时,圆圈最终会环绕。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-15
    • 1970-01-01
    相关资源
    最近更新 更多