Skip to content

Commit

Permalink
Implement Polygon type + refactored Rectangle to make use of it (#69)
Browse files Browse the repository at this point in the history
* first attempt - not working

* polygon implmentation + refactored rectangle; both working w/ examples

* removed rectangle type and refactored examples

* fixing merge issues

* Resolve conflicts after merging with master

---------

Co-authored-by: Kaustubh Maske Patil <[email protected]>
  • Loading branch information
FayCarsons and nikochiko authored Dec 13, 2023
1 parent 704c2b6 commit 91123cf
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 70 deletions.
2 changes: 1 addition & 1 deletion examples/circle_packing.ml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,6 @@ let () =
let circles = pack_circles () in
let circles = List.flatten (List.map make_concentric circles) in
List.iter
(fun ((x, y), radius) -> draw_with_color (circle ~x ~y radius))
(fun ((x, y), radius) -> draw_with_color (circle ~point:(point x y) radius))
circles;
close ()
7 changes: 6 additions & 1 deletion examples/dune
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
(executable
(name rectangle)
(modules rectangle)
(libraries graphics))
(libraries joy))

(executable
(name circle_grid)
Expand Down Expand Up @@ -98,6 +98,11 @@
(modules complex)
(libraries joy))

(executable
(name polygon)
(modules polygon)
(libraries joy))

(executable
(name circle_packing)
(modules circle_packing)
Expand Down
11 changes: 11 additions & 0 deletions examples/polygon.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
open Joy.Shape

let size = 100

let () =
init ();
let poly =
polygon [ { x = -size; y = 0 }; { x = 0; y = size }; { x = size; y = 0 } ]
in
render_shape poly;
close ()
43 changes: 7 additions & 36 deletions examples/rectangle.ml
Original file line number Diff line number Diff line change
@@ -1,39 +1,10 @@
open Graphics
open Joy.Shape

type point = { x : int; y : int }
type rectangle = { c : point; length : int; width : int }
type shape = Rectangle of rectangle

let canvas_size = (500, 500)
let canvas_mid = { x = fst canvas_size / 2; y = snd canvas_size / 2 }

let render_shape s =
match s with
| Rectangle rect ->
let x1 = rect.c.x - (rect.length / 2) in
let x2 = rect.c.x + (rect.length / 2) in
let y1 = rect.c.y - (rect.width / 2) in
let y2 = rect.c.y + (rect.width / 2) in
draw_rect x1 y1 (x2 - x1) (y2 - y1)

let rectangle ?x ?y length width =
let center =
match (x, y) with Some x, Some y -> { x; y } | _ -> canvas_mid
in
Rectangle { c = center; length; width }

let show shapes = List.iter render_shape shapes
let size = 100

let () =
open_graph
(" "
^ string_of_int (fst canvas_size)
^ "x"
^ string_of_int (snd canvas_size));
set_color black;

let rect = rectangle 200 100 in
show [ rect ];

ignore (read_line ());
close_graph ()
init ();
(* creating a rectangle from points *)
let rect = rectangle size size in
render_shape rect;
close ()
67 changes: 36 additions & 31 deletions lib/shape.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ open Graphics

type point = { x : int; y : int }
type line = { a : point; b : point }
type rectangle = { c : point; length : int; width : int }
type circle = { c : point; radius : int }
type ellipse = { c : point; rx : int; ry : int }
type polygon = point list

type shape =
| Circle of circle
| Rectangle of rectangle
| Ellipse of ellipse
| Line of line
| Polygon of polygon
| Complex of shape list

type shapes = shape list
Expand All @@ -22,24 +22,38 @@ let axes_flag = ref false
let draw_axes flag = axes_flag := flag
let draw_line x1 y1 x2 y2 = draw_poly_line [| (x1, y1); (x2, y2) |]

let bi_to_uni x y =
let nx = (x *. 0.5) +. (float_of_int !dimensions.x *. 0.5) in
let ny = (y *. 0.5) +. (float_of_int !dimensions.y *. 0.5) in
(int_of_float nx, int_of_float ny)

let denormalize point =
{ x = point.x + canvas_mid.x; y = point.y + canvas_mid.y }

let render_polygon polygon' =
let points =
Array.of_list
(List.map
(fun point ->
let { x; y } = denormalize point in
(x, y))
polygon')
in
draw_poly points

let rec render_shape s =
match s with
| Circle circle ->
draw_circle (denormalize circle.c).x (denormalize circle.c).y
circle.radius
| Rectangle rectangle ->
let c = denormalize rectangle.c in
draw_rect c.x c.y rectangle.length rectangle.width
| Ellipse ellipse ->
let c = denormalize ellipse.c in
draw_ellipse c.x c.y ellipse.rx ellipse.ry
| Line line ->
let a = denormalize line.a in
let b = denormalize line.b in
draw_line a.x a.y b.x b.y
| Polygon polygon' -> render_polygon polygon'
| Complex complex -> List.iter render_shape complex

let point x y = { x; y }
Expand All @@ -50,9 +64,14 @@ let circle ?point r =
| _ -> Circle { c = { x = 0; y = 0 }; radius = r }

let rectangle ?point length width =
match point with
| Some point -> Rectangle { c = point; length; width }
| _ -> Rectangle { c = { x = 0; y = 0 }; length; width }
let x, y = match point with Some { x; y } -> (x, y) | None -> (0, 0) in
Polygon
[
{ x; y };
{ x; y = y + length };
{ x = x + width; y = y + length };
{ x = x + width; y };
]

let ellipse ?point rx ry =
match point with
Expand All @@ -64,19 +83,15 @@ let line ?point_a point_b =
| Some point_a -> Line { a = point_a; b = point_b }
| _ -> Line { a = { x = 0; y = 0 }; b = point_b }

let polygon lst_points = Polygon lst_points

let complex shapes =
match shapes with _ :: _ -> Complex shapes | [] -> Complex []

let rec translate dx dy shape =
match shape with
| Circle circle ->
Circle { circle with c = { x = circle.c.x + dx; y = circle.c.y + dy } }
| Rectangle rectangle ->
Rectangle
{
rectangle with
c = { x = rectangle.c.x + dx; y = rectangle.c.y + dy };
}
| Ellipse ellipse ->
Ellipse
{ ellipse with c = { x = ellipse.c.x + dx; y = ellipse.c.y + dy } }
Expand All @@ -86,6 +101,11 @@ let rec translate dx dy shape =
a = { x = line.a.x + dx; y = line.a.y + dy };
b = { x = line.b.x + dx; y = line.b.y + dy };
}
| Polygon polygon' ->
polygon
(List.map
(fun { x : int; y : int } -> { x = x + dx; y = y + dy })
polygon')
| Complex shapes -> Complex (List.map (translate dx dy) shapes)

let rec scale factor s =
Expand All @@ -94,24 +114,15 @@ let rec scale factor s =
match s with
| Circle circle' ->
circle ~point:circle'.c (scale_length circle'.radius factor)
| Rectangle rectangle' ->
rectangle ~point:rectangle'.c
(scale_length rectangle'.length factor)
(scale_length rectangle'.width factor)
| Ellipse ellipse' ->
ellipse ~point:ellipse'.c
(scale_length ellipse'.rx factor)
(scale_length ellipse'.ry factor)
| Line _line' -> failwith "Not Implemented"
| Polygon _polygon' -> failwith "Scale not implemeted for polygons"
| Complex shapes -> Complex (List.map (scale factor) shapes)

let show shapes = List.iter render_shape shapes

let bi_to_uni x y =
let nx = (x *. 0.5) +. (float_of_int !dimensions.x *. 0.5) in
let ny = (y *. 0.5) +. (float_of_int !dimensions.y *. 0.5) in
(int_of_float nx, int_of_float ny)

let deg_to_rad degrees = degrees *. (Stdlib.Float.pi /. 180.)

let rot { x : int; y : int } degrees =
Expand All @@ -124,16 +135,10 @@ let rot { x : int; y : int } degrees =
let rec rotate degrees shape =
match shape with
| Circle circle -> Circle { c = rot circle.c degrees; radius = circle.radius }
| Rectangle rectangle ->
Rectangle
{
c = rot rectangle.c degrees;
length = rectangle.length;
width = rectangle.width;
}
| Ellipse ellipse ->
Ellipse { c = rot ellipse.c degrees; rx = ellipse.rx; ry = ellipse.ry }
| Line _line -> failwith "Not Implemented"
| Polygon polygon' -> polygon (List.map (fun p -> rot p degrees) polygon')
| Complex shapes -> Complex (List.map (rotate degrees) shapes)

let compose f g x = g (f x)
Expand Down
2 changes: 1 addition & 1 deletion lib/shape.mli
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
type point
type shape
type shapes = shape list
type point = { x : int; y : int }
Expand All @@ -10,6 +9,7 @@ val rectangle : ?point:point -> int -> int -> shape
val ellipse : ?point:point -> int -> int -> shape
val complex : shape list -> shape
val line : ?point_a:point -> point -> shape
val polygon : point list -> shape
val translate : int -> int -> shape -> shape
val show : shape list -> unit
val scale : float -> shape -> shape
Expand Down

0 comments on commit 91123cf

Please sign in to comment.