skip to Main Content

Function

I have this function to detect if a tetrahedron has almost zero volume, i.e. it’s flat:


import (
    "math"

    v3 "github.com/deadsy/sdfx/vec/v3"
)

// MATHEMATICA script is available here:
// https://math.stackexchange.com/a/4709610/197913
func isZeroVolume(a, b, c, d v3.Vec) (bool, float64) {
    ab := b.Sub(a)
    ac := c.Sub(a)
    ad := d.Sub(a)

    // Note that the `Norm` function of MATHEMATICA is equivalent to our `Length()` function.
    nab := ab.Length()
    ncd := ac.Sub(ad).Length()
    nbd := ab.Sub(ad).Length()
    nbc := ab.Sub(ac).Length()
    nac := ac.Length()
    nad := ad.Length()

    // Check for 0 edge lengths
    if nab == 0 || ncd == 0 ||
        nbd == 0 || nbc == 0 ||
        nac == 0 || nad == 0 {
        return true, 0
    }

    volume := 1.0 / 6.0 * math.Abs(ab.Cross(ac).Dot(ad))
    denom := (nab + ncd) * (nac + nbd) * (nad + nbc)

    // Tolerance derived from here:
    // https://math.stackexchange.com/a/4709610/197913
    tolerance := 480.0

    rho := tolerance * volume / denom

    return rho < 1, volume
}

Input

I step through the code with these four input points:

{X: -1.572793602943422, Y: -4.157202807477221, Z: 5.603983008116483}
{X: -2.45160644054413, Y: -3.4214927673339854, Z: 6.135950530673543}
{X: -2.45160644054413, Y: -3.7163730403986044, Z: 5.603983008116483}
{X: -1.572793602943422, Y: -3.5355907043553003, Z: 6.482795845717191}

Debugger

Stepping through the code by VS Code debugger indicates that the local variable have these values:

Screenshot

Question

The values shown by the debugger make no sense. How can denom and tolerance be 0? It makes no sense to me. Am I missing something?

2

Answers


  1. Chosen as BEST ANSWER

    Well, I just continued stepping through the code by the debugger and the values are now as expected. Like the constant value of tolerance:

    Screenshot

    I don't know how and why it gets corrected by just continuing the stepping...


  2. Here is a simplified version of the demo to show the issue:

     1  package main
     2  
     3  func main() {
     4      a := f(1)
     5      b := 1
     6  
     7      c := a < b
     8      _ = c
     9  }
    10  
    11  func f(i int) int {
    12      if i > 0 {
    13          return i
    14      }
    15      return -i
    16  }
    

    And here is the output of a delve debug session:

    (dlv) b 7
    Breakpoint 2 set at 0x4608de for main.main() ./main.go:7
    (dlv) c
    > main.main() ./main.go:7 (hits goroutine(1):1 total:1) (PC: 0x4608de)
         2: 
         3: func main() {
         4:     a := f(1)
         5:     b := 1
         6: 
    =>   7:     c := a < b
         8:     _ = c
         9: }
        10: 
        11: func f(i int) int {
        12:     if i > 0 {
    (dlv) locals
    a = 824633745824
    b = 824633843808
    (dlv) disass
    TEXT main.main(SB) /home/zeke/src/temp/76380802/main.go
        main.go:3   0x4608c0    493b6610            cmp rsp, qword ptr [r14+0x10]
        main.go:3   0x4608c4    7639                jbe 0x4608ff
        main.go:3   0x4608c6    4883ec28            sub rsp, 0x28
        main.go:3   0x4608ca    48896c2420          mov qword ptr [rsp+0x20], rbp
        main.go:3   0x4608cf    488d6c2420          lea rbp, ptr [rsp+0x20]
        main.go:4   0x4608d4    b801000000          mov eax, 0x1
        main.go:4   0x4608d9    e842000000          call $main.f
    =>  main.go:7   0x4608de*   4883f801            cmp rax, 0x1
        main.go:4   0x4608e2    4889442418          mov qword ptr [rsp+0x18], rax
        main.go:5   0x4608e7    48c744241001000000  mov qword ptr [rsp+0x10], 0x1
        main.go:7   0x4608f0    0f9c44240f          setl byte ptr [rsp+0xf]
        main.go:9   0x4608f5    488b6c2420          mov rbp, qword ptr [rsp+0x20]
        main.go:9   0x4608fa    4883c428            add rsp, 0x28
        main.go:9   0x4608fe    c3                  ret
        main.go:3   0x4608ff    90                  nop
        main.go:3   0x460900    e83bccffff          call $runtime.morestack_noctxt
        main.go:3   0x460905    ebb9                jmp $main.main
    

    You see that the instruction 0x4608de is picked as the breakpoint at line :7. At this point, the variables a and b haven’t got their values yet (a gets the value later at the instruction 0x4608e2, while b at 0x4608e7).

    That’s why you don’t get the correct value at first and it "fixes itself" later.

    This issue has been reported as cmd/compile: bad DWARF location for variable #58813.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search