---
title: "some raycasting (old)"
order: 1
author:
- name: "Declan Naughton ๐งฎ๐จโ๐ป"
url: "https://calcwithdec.dev/about.html"
description: "some raycasting (old)"
format:
html:
resources:
- '../../models/raycasting/*.js'
- '../../models/raycasting/*.js.map'
- '../../models/raycasting/*.json'
---
# Raycasting engine & explainer with calculang
Or the mathematics of DOOM?
default view is looking directly at the block to the right of the player (see 'level' view below). Scrub FOV to the right to look at the long wall! Then increase player y to simulate walking along it.
Field of View (FOV) is radians. 1 Rad is ~52 degrees. 2 is ~104, so the default is a little wide FOV.
```{ojs}
viewof player_x_in = Inputs.range([3,61], {step:1, value:32, label:'player x'})
viewof player_y_in = Inputs.range([3,61], {step:1, value:32, label:'player y'})
viewof ray_angle_in_step_size = Inputs.select([0.01,0.02,0.04], {value:0.02, label: 'ray_angle_in steps'})
import {interval} from '@mootari/range-slider'
viewof fov = interval([-3.14*2, 3.14*2], {
step: 0.01,
value: [-1,1],
label: 'field of view',
})
embed(
calcuvizspec({
models: [main],
input_cursors: [{player_x_in,player_y_in}],
mark: {type:'bar', point:false},
encodings: {
//row: {name: 'formula', type:'nominal', domain: ['inverse_ray_length','negative_inverse_ray_length']},
x: {grid: false, name: 'ray_angle_in', /*sort:'descending',*/type: 'quantitative', domain: _.range(fov[0],fov[1],ray_angle_in_step_size), nice:false, ticks:2},
color: {name: 'ray_hit_color', type:'nominal', legend:false},
y: {grid: false, name: 'inverse_ray_length', type: 'quantitative'},
opacity: {name: 'inverse_ray_length', type: 'quantitative', legend:false},
},
width: 500, height:200,
spec_post_process: spec => {spec.encoding.y.scale = {domain:[0,0.3],};
spec.encoding.x.axis = {tickCount:2, grid:false}
return spec}
}),
{config: {background:'#eee'}})
```
#### Level:
```{ojs}
embed(
calcuvizspec({
models: [main],
input_cursors: [{player_x_in,player_y_in,ray_angle_in:(fov[0]+fov[1])/2}],
mark: 'rect',
encodings: {
x: {name: 'level_x_in', type:'nominal', domain: _.range(0,63.1,1)},
y: {name: 'level_y_in', type: 'nominal', domain: _.range(0,63.1,1)},
color: {name: 'value', type: 'nominal', legend:false},
row: {name: 'formula', type:'nominal', domain: ['level_plus_player_plus_ray']},
},
width: 400, height:400
}))
embed(
calcuvizspec({
models: [main],
input_cursors: [{player_x_in,player_y_in}],
mark: {type:'bar'},
encodings: {
color: {name: 'formula', type:'nominal', domain: ['inverse_ray_length','negative_inverse_ray_length']},
x: {name: 'ray_angle_in', /*sort:'descending',*/type: 'quantitative', domain: _.range(fov[0],fov[1],ray_angle_in_step_size), nice:false},
//color: {name: 'formula', type:'nominal', domain: ['ray_x','ray_y','ray_value'], legend: false},
y: {name: 'value', type: 'quantitative', format:',.1f', independent:true},
},
width: 400, height:100,
spec_post_process: spec => {spec.encoding.y.scale = {domain:[-0.3,0.3]};
spec.encoding.color.scale = {"range": ["blue","lightblue"]};
return spec}
}))
```
### Rays:
*Some views I used in development and will remove or replace soon*
```{ojs}
embed(
calcuvizspec({
models: [main],
input_cursors: [{player_x_in,player_y_in}],
mark: 'text',
encodings: {
y: {name: 'formula', type:'nominal', domain: ['ray_length']},
x: {name: 'ray_angle_in', type: 'quantitative', domain: _.range(-1,1,0.1)},
//color: {name: 'formula', type:'nominal', domain: ['ray_x','ray_y','ray_value'], legend: false},
text: {name: 'value', type: 'quantitative', format:',.1f'},
},
width: 800, height:100
}))
```
```{ojs}
embed(
calcuvizspec({
models: [main],
input_cursors: [{player_x_in,player_y_in}],
mark: 'text',
encodings: {
x: {name: 'formula', type:'nominal', domain: ['ray_x','ray_y','ray_value','ray_length']},
y: {name: 'ray_steps_in', type: 'nominal', domain: _.range(0,50,1)},
color: {name: 'formula', type:'nominal', domain: ['ray_x','ray_y','ray_value'], legend: false},
column: {name: 'ray_angle_in', type:'nominal', domain: [0,0.01,0.1,0.5,-0.4]},
text: {name: 'value', type: 'quantitative', format:',.2f'},
},
width: 100, height:500
}))
```
# Appendix
::: {.callout-tip}
You can find the calculang model source code by opening Developer Tools (Ctrl+Shift+I) and navigating to the `.cul.js` file (Ctrl+P and search `.cul.js` ).
:::
```{ojs}
import { calcuvizspec } from "@declann/little-calcu-helpers"
embed = require('vega-embed');
viewof entrypoint = Inputs.select(['models/raycasting/raycasting.cul.js'], {label:'entrypoint'})
entrypoint_no_cul_js = entrypoint.slice(0,-7)
main = require(`../../${entrypoint_no_cul_js}.js`);
introspection_fetch = await fetch(`../../${entrypoint_no_cul_js}.introspection.json`)
introspection = introspection_fetch.json({typed:true})
inputs = Object.values(introspection.cul_functions).filter(d => d.reason == 'input definition').map(d => d.name).sort()
formulae = Object.values(introspection.cul_functions).filter(d => d.reason == 'definition').map(d => d.name)
// formulae excluding pure inputs
formulae_not_inputs = Object.values(introspection.cul_functions).filter(d => d.reason == 'definition' && inputs.indexOf(d.name+'_in') == -1).map(d => d.name)
```
::: {.callout-tip}
For calculang devtools adjust *entrypoint* in [ devtools ](/pages/some-devtools.qmd) .
:::