diff --git a/tinker/cube b/tinker/cube index a2f69fb..a8c9e6b 100755 Binary files a/tinker/cube and b/tinker/cube differ diff --git a/tinker/cube.ml b/tinker/cube.ml index fe0e324..6aa4cec 100644 --- a/tinker/cube.ml +++ b/tinker/cube.ml @@ -31,7 +31,7 @@ let rotate_x (x, y, z) angle = );; let translate_z (x, y, z) dz = - (x, y, z +. dz);; + (x, y +. 0.175, z +. dz);; (* CUBE *) let vertecies = [ @@ -52,9 +52,16 @@ let faces = [ (2, 3, 7, 6) (* bottom *) ];; -let draw_line (x1, y1) (x2, y2) = +let draw_line va vb = + let va = project va in + let vb = project vb in + + let (x1, y1) = screen_space va in + let (x2, y2) = screen_space vb in + moveto x1 y1; - lineto x2 y2;; + lineto x2 y2; + ();; let rec get_vertex v i = match v with @@ -84,29 +91,120 @@ let draw_face (a, b, c, d) angle = let vc = translate_z vc 1.25 in let vd = translate_z vd 1.25 in - let va = project va in - let vb = project vb in - let vc = project vc in - let vd = project vd in - - let va = screen_space va in - let vb = screen_space vb in - let vc = screen_space vc in - let vd = screen_space vd in - draw_line va vb; draw_line vb vc; draw_line vc vd; draw_line vd va;; -let rec iter_faces faces angle = +let rec draw_cube faces angle = match faces with | [] -> () | (a, b, c, d) :: fs -> draw_face (a, b, c, d) angle; - iter_faces fs angle;; + draw_cube fs angle;; +(* END CUBE *) -let rec spin_cube angle = +(* SPHERE *) +let stacks = 10;; +let slices = 12;; +let radius = 0.175;; + +let gen_sphere_vertecies st sl r = + let rec gen_slice j sp cp sv = + if j = -1 then sv + else + let theta = 2. *. 3.1415926 *. float_of_int j /. float_of_int (sl) in + let sinTheta = sin theta in + let cosTheta = cos theta in + gen_slice (j - 1) sp cp ((r *. cosTheta *. sp, r *. cp, r *. sinTheta *. sp) :: sv) + in + + let rec gen_stack i sv = + if i = -1 then sv + else + let phi = 3.1415926 *. float_of_int i /. float_of_int (st - 1) in + let sinPhi = sin phi in + let cosPhi = cos phi in + gen_stack (i - 1) (gen_slice (sl - 1) sinPhi cosPhi sv) + in + + gen_stack (st - 1) [];; + +let s_vertecies = gen_sphere_vertecies stacks slices radius;; + +let draw_ellipse ev o = + let f = match ev with + | [] -> (0., 0., 0.) + | a :: _ -> a in + + let rec iter_vertex l v = + match v with + | [] -> l + | [a] -> draw_line a l; a + | [a; b] -> draw_line a b; b + | a :: b :: vs -> + draw_line a b; + iter_vertex b (b :: vs) + in + let l = iter_vertex (0., 0., 0.) ev in + + if o then draw_line f l;; + +let rec get_nth_vert e n = + match e with + | [] -> failwith "cannot find nth vertex" + | x :: xs -> + if n = 0 then x + else get_nth_vert xs (n - 1);; + +let draw_sphere v st sl = + let rec render_slices i = + let rec iter_slices j e = + if j = (sl - 1) then e + else + iter_slices (j + 1) (get_nth_vert v (i * sl + j) :: e) + in + let e = iter_slices 0 [] in + draw_ellipse e true; + if i = st - 1 then () + else render_slices (i + 1) + in + + let rec render_stacks j = + let rec iter_stacks i e = + if i = (st - 1) then e + else iter_stacks (i + 1) (get_nth_vert v (i * sl + j) :: e) + in + let e = iter_stacks 0 [] in + draw_ellipse e false; + if j = sl - 1 then () + else render_stacks (j + 1) + in + + render_slices 0; + render_stacks 0;; + +let list_translate_z l = + let rec translate r n = + match r with + | [] -> n + | x :: xs -> translate (xs) (translate_z x 1. :: n) + in + + translate l [];; + +let list_rotate_y l angle = + let rec translate r n = + match r with + | [] -> n + | x :: xs -> translate (xs) (rotate_y x angle :: n) + in + + translate l [];; + +(* END SPHERE *) + +let rec animate angle sv = clear_graph (); set_color (rgb 0 0 0); @@ -114,17 +212,18 @@ let rec spin_cube angle = set_color cyan; - iter_faces faces angle; + (* draw_cube faces angle; *) + draw_sphere sv stacks slices; Graphics.synchronize (); - spin_cube (angle +. 0.000075);; + animate (angle +. 0.0005) (list_translate_z (list_rotate_y (gen_sphere_vertecies 10 12 0.175) angle));; let () = open_graph " 800x800+560+140"; auto_synchronize false; - spin_cube 0. 100; + animate 0. s_vertecies; close_graph () diff --git a/tinker/output.txt b/tinker/output.txt new file mode 100644 index 0000000..e69de29 diff --git a/tinker/proper.txt b/tinker/proper.txt new file mode 100644 index 0000000..eb8efda --- /dev/null +++ b/tinker/proper.txt @@ -0,0 +1,6 @@ +(0.000000, 0.050000, 0.000000) +(-0.000000, 0.050000, 0.000000) +(-0.000000, 0.050000, -0.000000) +(-0.000000, -0.050000, -0.000000) +(0.000000, -0.050000, -0.000000) +(0.000000, -0.050000, 0.000000) diff --git a/tinker/sphere.ml b/tinker/sphere.ml new file mode 100644 index 0000000..22fbe68 --- /dev/null +++ b/tinker/sphere.ml @@ -0,0 +1,53 @@ +let stacks = 10;; +let slices = 12;; +let radius = 0.175;; + +let gen_sphere_vertecies st sl r = + let rec gen_slice j sp cp sv = + if j = -1 then sv + else + let theta = 2. *. 3.1415926 *. float_of_int j /. float_of_int (sl) in + let sinTheta = sin theta in + let cosTheta = cos theta in + gen_slice (j - 1) sp cp ((r *. cosTheta *. sp, r *. cp, r *. sinTheta *. sp) :: sv) + in + + let rec gen_stack i sv = + if i = -1 then sv + else + let phi = 3.1415926 *. float_of_int i /. float_of_int (st - 1) in + let sinPhi = sin phi in + let cosPhi = cos phi in + gen_stack (i - 1) (gen_slice (sl - 1) sinPhi cosPhi sv) + in + + gen_stack (st - 1) [];; + +let reverse_tr l = + let rec reverse_tr' acc l = + match l with + | [] -> acc + | x :: xs -> reverse_tr' (x :: acc) xs + in + reverse_tr' [] l;; + +let write_string_list_to_file filename (lines : string list) : unit = + Out_channel.with_open_text filename (fun oc -> + List.iter (Printf.fprintf oc "%s\n") lines + );; + +let convert_to_string l = + let rec convert r n = + match r with + | [] -> reverse_tr n + | (x, y, z) :: xs -> + let s = Printf.sprintf "(%f, %f, %f)" x y z in + convert xs (s :: n) + in + convert l [];; + +let () = + let vertecies = gen_sphere_vertecies 10 12 0.175 in + let file_path = "output.txt" in + write_string_list_to_file file_path (convert_to_string vertecies); + Printf.printf "Successfully wrote list to %s\n" file_path diff --git a/tinker/test.c b/tinker/test.c new file mode 100644 index 0000000..39fcec1 --- /dev/null +++ b/tinker/test.c @@ -0,0 +1,91 @@ +#include +#include +#include + +// validating the vertecies generated by tinker.ml are correct + +typedef struct VEC3 { + float x; + float y; + float z; +} VEC3; + +void print_vertecies(VEC3 v[], size_t s) +{ + printf("["); + for (int i = 0; i < s; i++) + { + printf("(%f, %f, %f)\n", v[i].x, v[i].y, v[i].z); + } + printf("]"); +} + +VEC3 *gen_sphere_vertecies(int stacks, int slices, float r) +{ + // Generate sphere vectors + VEC3 *sphere_vertecies = malloc(stacks * slices * sizeof(VEC3)); + + for (int i = 0; i < stacks; i++) + { + // Phi (angle of latitude, ranges from 0 to PI) + float phi = M_PI * (float)i / (float)(stacks - 1); + float sinPhi = sin(phi); + float cosPhi = cos(phi); + + for (int j = 0; j < slices; j++) + { + // Theta (angle of longitude, ranges from 0 to 2*PI) + float theta = 2.f * M_PI * (float)j / (float)slices; + float sinTheta = sin(theta); + float cosTheta = cos(theta); + + // Convert spherical coordinates to Cartesian (x, y, z) + // The choice of axis mapping may vary. Here Y is vertical. + sphere_vertecies[i * slices + j] = (VEC3){ + .x = r * cosTheta * sinPhi, + .y = r * cosPhi, + .z = r * sinTheta * sinPhi, + }; + } + } + + return sphere_vertecies; +} + +int main(void) +{ + int stacks = 10; + int slices = 12; + float r = 0.175; + + // Generate sphere vectors + VEC3 sphere_vertecies[stacks * slices]; + + for (int i = 0; i < stacks; i++) + { + // Phi (angle of latitude, ranges from 0 to PI) + float phi = M_PI * (float)i / (float)(stacks - 1); + float sinPhi = sin(phi); + float cosPhi = cos(phi); + + for (int j = 0; j < slices; j++) + { + // Theta (angle of longitude, ranges from 0 to 2*PI) + float theta = 2.f * M_PI * (float)j / (float)slices; + float sinTheta = sin(theta); + float cosTheta = cos(theta); + + // Convert spherical coordinates to Cartesian (x, y, z) + // The choice of axis mapping may vary. Here Y is vertical. + sphere_vertecies[i * slices + j] = (VEC3){ + .x = r * cosTheta * sinPhi, + .y = r * cosPhi, + .z = r * sinTheta * sinPhi, + }; + } + } + + print_vertecies(sphere_vertecies, stacks * slices); + + return 0; +} diff --git a/tinker/test.o b/tinker/test.o new file mode 100755 index 0000000..8c993c1 Binary files /dev/null and b/tinker/test.o differ diff --git a/tinker/tinker.ml b/tinker/tinker.ml new file mode 100644 index 0000000..5796762 --- /dev/null +++ b/tinker/tinker.ml @@ -0,0 +1,53 @@ +(*** testing stuff ***) + +let stacks = 10;; +let slices = 12;; + +let gen_sphere_vertecies st sl r = + let rec gen_slice j sp cp sv = + if j = -1 then sv + else + let theta = 2. *. 3.1415926 *. float_of_int j /. float_of_int (slices) in + let sinTheta = sin theta in + let cosTheta = cos theta in + gen_slice (j - 1) sp cp ((r *. cosTheta *. sp, r *. cp, r *. sinTheta *. sp) :: sv) + in + + let rec gen_stack i sv = + if i = -1 then sv + else + let phi = 3.1415926 *. float_of_int i /. float_of_int (stacks - i) in + let sinPhi = sin phi in + let cosPhi = cos phi in + gen_stack (i - 1) (gen_slice (slices - 1) sinPhi cosPhi sv) + in + + gen_stack (stacks - 1) [];; + +let draw_line (x1, y1) (x2, y2) = + Printf.printf "(%f, %f) -> (%f, %f)\n" x1 y1 x2 y2 + +let draw_ellipse ev o = + let f = match ev with + | [] -> (0., 0.) + | (x, y, _) :: _ -> (x, y) in + + let rec iter_vertex (lx, ly) v = + match v with + | [] -> (lx, ly) + | [(x, y, _)] -> draw_line (x, y) (lx, ly); (x, y) + | [(x1, y1, _); (x2, y2, _)] -> draw_line (x1, y1) (x2, y2); (x2, y2) + | (x1, y1, _) :: (x2, y2, _) :: vs -> + draw_line (x1, y1) (x2, y2); + iter_vertex (x2, y2) ((x2, y2, 0.) :: vs) + in + let l = iter_vertex (0., 0.) ev in + + if o = 0 then draw_line f l;; + +let rec get_nth_vert e n = + match e with + | [] -> failwith "cannot find nth element" + | x :: xs -> + if n = 0 then x + else get_nth_vert xs (n - 1);;