diff --git a/tinker/cube b/tinker/cube index a8c9e6b..33efe4e 100755 Binary files a/tinker/cube and b/tinker/cube differ diff --git a/tinker/cube.ml b/tinker/cube.ml index 6aa4cec..93fc074 100644 --- a/tinker/cube.ml +++ b/tinker/cube.ml @@ -13,25 +13,34 @@ let project (x, y, z) = (x /. z, y /. z);; let rotate_y (x, y, z) angle = - let ox = x in - let oz = z in ( - ox *. cos(angle) -. oz *. sin(angle), + x *. cos(angle) -. z *. sin(angle), y, - ox *. sin(angle) +. oz *. cos(angle) + x *. sin(angle) +. z *. cos(angle) );; let rotate_x (x, y, z) angle = - let oy = y in - let oz = z in ( x, - oy *. cos(angle) -. oz *. sin(angle), - oy *. sin(angle) +. oz *. cos(angle) + y *. cos(angle) -. z *. sin(angle), + y *. sin(angle) +. z *. cos(angle) );; +let rotate_z (x, y, z) angle = + ( + x *. cos(angle) -. y *. sin(angle), + x *. sin(angle) +. y *. cos(angle), + z + );; + +let translate_x (x, y, z) dx = + (x +. dx, y, z);; + +let translate_y (x, y, z) dy = + (x, y +. dy, z);; + let translate_z (x, y, z) dz = - (x, y +. 0.175, z +. dz);; + (x, y, z +. dz);; (* CUBE *) let vertecies = [ @@ -70,38 +79,23 @@ let rec get_vertex v i = if i = 0 then x else get_vertex xs (i - 1);; -let draw_face (a, b, c, d) angle = - let va = (get_vertex vertecies a) in - let vb = (get_vertex vertecies b) in - let vc = (get_vertex vertecies c) in - let vd = (get_vertex vertecies d) in - - let va = rotate_y va angle in - let vb = rotate_y vb angle in - let vc = rotate_y vc angle in - let vd = rotate_y vd angle in - - let va = rotate_x va angle in - let vb = rotate_x vb angle in - let vc = rotate_x vc angle in - let vd = rotate_x vd angle in - - let va = translate_z va 1.25 in - let vb = translate_z vb 1.25 in - let vc = translate_z vc 1.25 in - let vd = translate_z vd 1.25 in +let draw_face (a, b, c, d) v angle = + let va = get_vertex v a in + let vb = get_vertex v b in + let vc = get_vertex v c in + let vd = get_vertex v d in draw_line va vb; draw_line vb vc; draw_line vc vd; draw_line vd va;; -let rec draw_cube faces angle = +let rec draw_cube faces v angle = match faces with | [] -> () | (a, b, c, d) :: fs -> - draw_face (a, b, c, d) angle; - draw_cube fs angle;; + draw_face (a, b, c, d) v angle; + draw_cube fs v angle;; (* END CUBE *) (* SPHERE *) @@ -113,7 +107,7 @@ 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 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) @@ -160,9 +154,8 @@ let rec get_nth_vert e n = 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) + if j = sl 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; @@ -172,58 +165,66 @@ let draw_sphere v st sl = let rec render_stacks j = let rec iter_stacks i e = - if i = (st - 1) then e + if i = st 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 () + if j = st + 1 then () else render_stacks (j + 1) in render_slices 0; render_stacks 0;; -let list_translate_z l = +let list_transform t l d = 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) + | x :: xs -> translate (xs) (t x d :: n) in translate l [];; (* END SPHERE *) -let rec animate angle sv = +let rec animate angle sv sqv = clear_graph (); set_color (rgb 0 0 0); - fill_rect 0 0 800 800; + fill_rect 0 0 (int_of_float window_w) (int_of_float window_h); set_color cyan; - (* draw_cube faces angle; *) + draw_cube faces sqv angle; draw_sphere sv stacks slices; Graphics.synchronize (); - animate (angle +. 0.0005) (list_translate_z (list_rotate_y (gen_sphere_vertecies 10 12 0.175) angle));; + let nsv = gen_sphere_vertecies 10 12 0.175 in + let nsv = list_transform rotate_y nsv (-1. *. angle) in + let nsv = list_transform rotate_x nsv (-1. *. angle) in + let nsv = list_transform translate_x nsv (sin angle /. -2.) in + let nsv = list_transform translate_y nsv (cos angle /. -2.) in + let nsv = list_transform translate_z nsv (1. +. sin(angle) /. 2.) in + + let nsqv = vertecies in + let nsqv = list_transform rotate_y nsqv angle in + let nsqv = list_transform rotate_x nsqv angle in + let nsqv = list_transform translate_x nsqv (sin angle) in + let nsqv = list_transform translate_y nsqv (cos angle) in + let nsqv = list_transform translate_z nsqv (2. +. (sin (-1. *. angle)) /. 2.) in + + animate (angle +. 0.0005) nsv nsqv;; let () = + let size = " " ^ (string_of_float window_w) ^ "x" ^ (string_of_float window_h) ^ "+560+140" in + Printf.printf "Size: %s\n" size; + (* open_graph size; *) open_graph " 800x800+560+140"; auto_synchronize false; - animate 0. s_vertecies; + animate 0. s_vertecies vertecies; close_graph () diff --git a/tinker/output.txt b/tinker/output.txt deleted file mode 100644 index e69de29..0000000 diff --git a/tinker/proper.txt b/tinker/proper.txt deleted file mode 100644 index eb8efda..0000000 --- a/tinker/proper.txt +++ /dev/null @@ -1,6 +0,0 @@ -(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 deleted file mode 100644 index 22fbe68..0000000 --- a/tinker/sphere.ml +++ /dev/null @@ -1,53 +0,0 @@ -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 index 39fcec1..3bd7b8a 100644 --- a/tinker/test.c +++ b/tinker/test.c @@ -20,38 +20,6 @@ void print_vertecies(VEC3 v[], size_t s) 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; diff --git a/tinker/tinker.ml b/tinker/tinker.ml index 5796762..3e66e77 100644 --- a/tinker/tinker.ml +++ b/tinker/tinker.ml @@ -2,12 +2,13 @@ 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 (slices) in + 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) @@ -16,38 +17,67 @@ let gen_sphere_vertecies st sl r = 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 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 (slices - 1) sinPhi cosPhi sv) + gen_stack (i - 1) (gen_slice (sl - 1) sinPhi cosPhi sv) in - gen_stack (stacks - 1) [];; + gen_stack (st - 1) [];; -let draw_line (x1, y1) (x2, y2) = - Printf.printf "(%f, %f) -> (%f, %f)\n" x1 y1 x2 y2 +let draw_line (x1, y1, z1) (x2, y2, z2) = + Printf.printf "(%f, %f, %f) -> (%f, %f, %f)\n" x1 y1 z1 x2 y2 z2 let draw_ellipse ev o = let f = match ev with - | [] -> (0., 0.) - | (x, y, _) :: _ -> (x, y) in + | [] -> (0., 0., 0.) + | a :: _ -> a in - let rec iter_vertex (lx, ly) v = + let rec iter_vertex l 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) + | [] -> 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.) ev in + let l = iter_vertex (0., 0., 0.) ev in - if o = 0 then draw_line f l;; + if o then draw_line f l;; let rec get_nth_vert e n = match e with - | [] -> failwith "cannot find nth element" + | [] -> 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 = 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 = 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 s_vertecies = gen_sphere_vertecies stacks slices radius;; +draw_sphere s_vertecies stacks slices;;