102 lines
2.7 KiB
Plaintext
102 lines
2.7 KiB
Plaintext
(*
|
|
** Solution to Draw_a_sphere.dats
|
|
*)
|
|
|
|
(* ****** ****** *)
|
|
//
|
|
#include
|
|
"share/atspre_define.hats" // defines some names
|
|
#include
|
|
"share/atspre_staload.hats" // for targeting C
|
|
#include
|
|
"share/HATS/atspre_staload_libats_ML.hats" // for ...
|
|
#include
|
|
"share/HATS/atslib_staload_libats_libc.hats" // for libc
|
|
//
|
|
(* ****** ****** *)
|
|
|
|
extern
|
|
fun
|
|
Draw_a_sphere
|
|
(
|
|
R: double, k: double, ambient: double
|
|
) : void // end of [Draw_a_sphere]
|
|
|
|
(* ****** ****** *)
|
|
|
|
implement
|
|
Draw_a_sphere
|
|
(
|
|
R: double, k: double, ambient: double
|
|
) = let
|
|
fun normalize(v0: double, v1: double, v2: double): (double, double, double) = let
|
|
val len = sqrt(v0*v0+v1*v1+v2*v2)
|
|
in
|
|
(v0/len, v1/len, v2/len)
|
|
end // end of [normalize]
|
|
|
|
fun dot(v0: double, v1: double, v2: double, x0: double, x1: double, x2: double): double = let
|
|
val d = v0*x0+v1*x1+v2*x2
|
|
val sgn = gcompare_val_val<double> (d, 0.0)
|
|
in
|
|
if sgn < 0 then ~d else 0.0
|
|
end // end of [dot]
|
|
|
|
fun print_char(i: int): void =
|
|
if i = 0 then print!(".") else
|
|
if i = 1 then print!(":") else
|
|
if i = 2 then print!("!") else
|
|
if i = 3 then print!("*") else
|
|
if i = 4 then print!("o") else
|
|
if i = 5 then print!("e") else
|
|
if i = 6 then print!("&") else
|
|
if i = 7 then print!("#") else
|
|
if i = 8 then print!("%") else
|
|
if i = 9 then print!("@") else print!(" ")
|
|
|
|
val i_start = floor(~R)
|
|
val i_end = ceil(R)
|
|
val j_start = floor(~2 * R)
|
|
val j_end = ceil(2 * R)
|
|
val (l0, l1, l2) = normalize(30.0, 30.0, ~50.0)
|
|
|
|
fun loopj(j: int, j_end: int, x: double): void = let
|
|
val y = j / 2.0 + 0.5;
|
|
val sgn = gcompare_val_val<double> (x*x + y*y, R*R)
|
|
val (v0, v1, v2) = normalize(x, y, sqrt(R*R - x*x - y*y))
|
|
val b = pow(dot(l0, l1, l2, v0, v1, v2), k) + ambient
|
|
val intensity = 9.0 - 9.0*b
|
|
val sgn2 = gcompare_val_val<double> (intensity, 0.0)
|
|
val sgn3 = gcompare_val_val<double> (intensity, 9.0)
|
|
in
|
|
( if sgn > 0 then print_char(10) else
|
|
if sgn2 < 0 then print_char(0) else
|
|
if sgn3 >= 0 then print_char(8) else
|
|
print_char(g0float2int(intensity));
|
|
if j < j_end then loopj(j+1, j_end, x)
|
|
)
|
|
end // end of [loopj]
|
|
|
|
fun loopi(i: int, i_end: int, j: int, j_end: int): void = let
|
|
val x = i + 0.5
|
|
val () = loopj(j, j_end, x)
|
|
val () = println!()
|
|
in
|
|
if i < i_end then loopi(i+1, i_end, j, j_end)
|
|
end // end of [loopi]
|
|
|
|
in
|
|
loopi(g0float2int(i_start), g0float2int(i_end), g0float2int(j_start), g0float2int(j_end))
|
|
end
|
|
|
|
(* ****** ****** *)
|
|
|
|
implement
|
|
main0() = () where
|
|
{
|
|
val () = DrawSphere(20.0, 4.0, .1)
|
|
val () = DrawSphere(10.0, 2.0, .4)
|
|
} (* end of [main0] *)
|
|
|
|
(* ****** ****** *)
|