jiricodes

jiricodes

The Ray Tracer Challenge: Capped cone normal vector (page 190)

Hi @jamis,
I’m not sure if this has been discussed elsewhere, so apologies for a potential duplicate.

I refer to cone normal calculation at page 190, where author states "

Lastly, for the normal vector, compute the end cap normals just as you did for the cylinder, but …"

This unfortunately doesn’t work since the code for cylinder cap normal assumes constant diameter of 1.0. Instead one should calculate an actual distance from y axis (including sqrt) and check it against the currently considered y limit’s absolute value.

Pseudo codes and tests

Assumed original pseudo-code (combining cylinder and cone):

function local_normal_at(cone, point)
    #part from the cylinder caps check
    dist = point.x ^ 2 + point.z ^ 2
    # if squared distance is < 1.0 then distance is also < 1.0 therefore we don't need sqrt here
    if dist < 1 and point.y >= cone.maximum - EPSILON
         return vector(0, 1, 0)
    else if dist < 1 and point.y <= cone.minimum + EPSILON
       return vector(0, -1, 0)
    else
        y = sqrt(point.x ^ 2 + point.z ^ 2)
       if point.y > 0.0
           y = -y
       return (point.x, y, point.z)

Test that fails with above example:

Scenario Outline: Computing the normal vector on a capped cone
    Given shape = cone()
    And shape.minimum = -1
    And shape.maximum = 2
    And p  = point(1.5, 2, 0.0)
    When n = local_normal_at(shape, p)
    Then n = point(0, 1, 0)

This test assumes a point that should be located at the upper cone cap with distance from y axis larger than 1.0. In this case we expect the cap’s (plane) normal to be returned.\

With the above pseudocode, we get instead vector(1.5, -1.5, 0)

Pseudocode of a proposed fix:

function local_normal_at(cone, point)
    #calculate distance from y axis,
    dist = sqrt(point.x ^ 2 + point.z ^ 2)
    if dist < cone.maximum and point.y >= cone.maximum - EPSILON
         return vector(0, 1, 0)
    else if dist < cone.minimum and point.y <= cone.minimum + EPSILON
       return vector(0, -1, 0)
    else
        # note that y calculation is same as dist, we can potentially reuse the value here
        y = sqrt(point.x ^ 2 + point.z ^ 2)
       if point.y > 0.0
           y = -y
       return (point.x, y, point.z)

Where Next?

Popular Pragmatic Bookshelf topics Top

jimschubert
In Chapter 3, the source for index introduces Config on page 31, followed by more code including tests; Config isn’t introduced until pag...
New
Mmm
Hi, build fails on: bracket-lib = “~0.8.1” when running on Mac Mini M1 Rust version 1.5.0: Compiling winit v0.22.2 error[E0308]: mi...
New
curtosis
Running mix deps.get in the sensor_hub directory fails with the following error: ** (Mix) No SSH public keys found in ~/.ssh. An ssh aut...
New
nicoatridge
Hi, I have just acquired Michael Fazio’s “Kotlin and Android Development” to learn about game programming for Android. I have a game in p...
New
brunogirin
When trying to run tox in parallel as explained on page 151, I got the following error: tox: error: argument -p/–parallel: expected one...
New
rainforest
Hi, I’ve got a question about the implementation of PubSub when using a Phoenix.Socket.Transport behaviour rather than channels. Before ...
New
andreheijstek
After running /bin/setup, the first error was: The foreman' command exists in these Ruby versions: That was easy to fix: gem install fore...
New
Keton
When running the program in chapter 8, “Implementing Combat”, the printout Health before attack was never printed so I assumed something ...
New
bjnord
Hello @herbert ! Trying to get the very first “Hello, Bracket Terminal!" example to run (p. 53). I develop on an Amazon EC2 instance runn...
New
gorkaio
root_layout: {PentoWeb.LayoutView, :root}, This results in the following following error: no “root” html template defined for PentoWeb...
New

Other popular topics Top

PragmaticBookshelf
Andy and Dave wrote this influential, classic book to help their clients create better software and rediscover the joy of coding. Almost ...
New
PragmaticBookshelf
Design and develop sophisticated 2D games that are as much fun to make as they are to play. From particle effects and pathfinding to soci...
New
PragmaticBookshelf
Build highly interactive applications without ever leaving Elixir, the way the experts do. Let LiveView take care of performance, scalabi...
New
rustkas
Intensively researching Erlang books and additional resources on it, I have found that the topic of using Regular Expressions is either c...
New
AstonJ
If you get Can't find emacs in your PATH when trying to install Doom Emacs on your Mac you… just… need to install Emacs first! :lol: bre...
New
husaindevelop
Inside our android webview app, we are trying to paste the copied content from another app eg (notes) using navigator.clipboard.readtext ...
New
First poster: AstonJ
Jan | Rethink the Computer. Jan turns your computer into an AI machine by running LLMs locally on your computer. It’s a privacy-focus, l...
New
NewsBot
Node.js v22.14.0 has been released. Link: Release 2025-02-11, Version 22.14.0 'Jod' (LTS), @aduh95 · nodejs/node · GitHub
New
PragmaticBookshelf
Fight complexity and reclaim the original spirit of agility by learning to simplify how you develop software. The result: a more humane a...
New
xiji2646-netizen
Woke up to this today: Claude Code’s complete source code exposed via npm source map. Not a snippet. All 512,000 lines. 1,900 TypeScript ...
New

Sub Categories: