(* ** 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 (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 (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 (intensity, 0.0) val sgn3 = gcompare_val_val (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] *) (* ****** ****** *)