Skip to main content

On Sale: GamesAssetsToolsTabletopComics
Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines

cel7

A tiny grid-based game framework · By rxi

trigonometry

A topic by ThaCuber created May 21, 2024 Views: 189 Replies: 1
Viewing posts 1 to 2

here are some trig utils

(= pi 3.14159265359)
(= to_rad (fn (x) (* (/ x 180) pi ) ))
(= to_deg (fn (x) (* (/ x pi ) 180) ))

a 128 floats long sine lookup table

generated using https://github.com/ppelikan/drlut

(= sin_len 128)
(= sin_lut (list
	 0.0000000000 0.0490676743 0.0980171403 0.1467304745
	 0.1950903220 0.2429801799 0.2902846773 0.3368898534
	 0.3826834324 0.4275550934 0.4713967368 0.5141027442
	 0.5555702330 0.5956993045 0.6343932842 0.6715589548
	 0.7071067812 0.7409511254 0.7730104534 0.8032075315
	 0.8314696123 0.8577286100 0.8819212643 0.9039892931
	 0.9238795325 0.9415440652 0.9569403357 0.9700312532
	 0.9807852804 0.9891765100 0.9951847267 0.9987954562
	 1.0000000000 0.9987954562 0.9951847267 0.9891765100
	 0.9807852804 0.9700312532 0.9569403357 0.9415440652
	 0.9238795325 0.9039892931 0.8819212643 0.8577286100
	 0.8314696123 0.8032075315 0.7730104534 0.7409511254
	 0.7071067812 0.6715589548 0.6343932842 0.5956993045
	 0.5555702330 0.5141027442 0.4713967368 0.4275550934
	 0.3826834324 0.3368898534 0.2902846773 0.2429801799
	 0.1950903220 0.1467304745 0.0980171403 0.0490676743
	 0.0000000000 -0.0490676743 -0.0980171403 -0.1467304745
	-0.1950903220 -0.2429801799 -0.2902846773 -0.3368898534
	-0.3826834324 -0.4275550934 -0.4713967368 -0.5141027442
	-0.5555702330 -0.5956993045 -0.6343932842 -0.6715589548
	-0.7071067812 -0.7409511254 -0.7730104534 -0.8032075315
	-0.8314696123 -0.8577286100 -0.8819212643 -0.9039892931
	-0.9238795325 -0.9415440652 -0.9569403357 -0.9700312532
	-0.9807852804 -0.9891765100 -0.9951847267 -0.9987954562
	-1.0000000000 -0.9987954562 -0.9951847267 -0.9891765100
	-0.9807852804 -0.9700312532 -0.9569403357 -0.9415440652
	-0.9238795325 -0.9039892931 -0.8819212643 -0.8577286100
	-0.8314696123 -0.8032075315 -0.7730104534 -0.7409511254
	-0.7071067812 -0.6715589548 -0.6343932842 -0.5956993045
	-0.5555702330 -0.5141027442 -0.4713967368 -0.4275550934
	-0.3826834324 -0.3368898534 -0.2902846773 -0.2429801799
	-0.1950903220 -0.1467304745 -0.0980171403 -0.0490676743
))

high level abstractions over the LUT

(= sin (fn (x)
	(= x (floor (* (/ x pi) sin_len)))
	(= x (% (+ x sin_len) sin_len))
	(nth sin_lut x)
))

(= cos (fn (x) (sin (+ x (/ pi 4))) ))

floor and nth functions necessary to use these! either supply your own implementations (nth must be 0-indexed) or use these:

(= floor (fn (x) (- x (% x 1)) ))

(= nth (fn (l i)
	(let res nil)
	(while (<= 0 i)
		(= res (car l))
		(= l (cdr l))
		(= i (- i 1))
	)
	res
))

a (somewhat convoluted) demo program:

(= init (fn () (= time 0) ))
(= keydown (fn (k) (if (is k "escape") (quit)) ))

(= trigfn (fn (f i) (* (+ 0.5 (* 0.5 (f (* (/ i width) pi)))) height) ))
(= offset (fn (x time) (% (+ x time) width) ))

(= step (fn ()
	(fill 0 0 width height " ")
	
	(let x 0)
	(while (< x width)
		(color 0x02) (put x (trigfn sin (offset x time)) "#")
		(color 0x06) (put x (trigfn cos (offset x (* time 1.5))) "#")
		(color 0x05) (put x (trigfn sin (offset x (- 0 time))) "#")
		(= x (+ x 1))
	)
	
	(= time (+ time 1))
))

I’ve made a function, that actually calculates the sinus

(= math:sin (fn (x) (= x (% x (* math:pi 2))) (let n 1) (let q x) (let s 0) (while (< n math:sin-accuracy) (+= s q) (= q (/ (* q (* -1 (math:sqr x))) (* (+ (* 2 n) 1) (* 2 n)))) (++ n)) s))

also you have to have this defined

(= math:pi 3.141592)
(= math:sin-accuracy 12)
(= math:sqr (fn (a) (* a a)))

so cos and tan are

(= math:cos (fn (x) (= x (% x (* math:pi 2))) (* (math:sqrt (- 1 (math:sqr (math:sin x)))) (if (& (> x (/ math:pi 2)) (< x (+ (/ math:pi 2) math:pi))) -1 1))))
(= math:tan (fn (x) (= x (% x math:pi)) (/ (math:sin x) (math:cos x))))

for this you need sqrt (here is my bad algorythm)

(= math:sqrt (fn (a) (let i 0) (let ans (/ math:sqrtmaxval 2)) (let sub (/ math:sqrtmaxval 4)) (while (< i math:sqrtmaxiter) (= ans (+ ans (* sub (math:signz (- a (math:sqr ans)))))) (= sub (/ sub 2)) (++ i)) ans))
(= math:sqrtmaxiter 16)
(= math:sqrtmaxval 1024)