Skip to content

Commit

Permalink
Fix ellipse rotation to work correctly
Browse files Browse the repository at this point in the history
Previously, we only rotated the center of the ellipse, similar to the circle.
This commit adds a rotation field to the ellipse shape type which stores the
rotation of the ellipse in radians. And we use Cairo's rotate function when
rendering the ellipse.

Fixes #116 along with #121.
  • Loading branch information
punchagan committed Mar 11, 2024
1 parent 4703b64 commit a21d3c7
Show file tree
Hide file tree
Showing 6 changed files with 13 additions and 3 deletions.
3 changes: 2 additions & 1 deletion lib/render.ml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ let draw_circle ctx ({ c; radius; stroke; fill } : circle) =
Option.iter fill_circle fill;
Cairo.Path.clear ctx.ctx

let draw_ellipse ctx { c; rx; ry; stroke; fill } =
let draw_ellipse ctx { c; rx; ry; stroke; fill; rotation } =
let stroke_ellipse stroke =
set_color stroke;
Cairo.stroke_preserve ctx.ctx
Expand All @@ -31,6 +31,7 @@ let draw_ellipse ctx { c; rx; ry; stroke; fill } =

(* Translate and scale to create an ellipse from a circle *)
Cairo.translate ctx.ctx c.x (Float.neg c.y);
Cairo.rotate ctx.ctx rotation;
Cairo.scale ctx.ctx rx ry;
Cairo.arc ctx.ctx 0. 0. ~r:1. ~a1:0. ~a2:(2. *. Float.pi);

Expand Down
3 changes: 2 additions & 1 deletion lib/shape.ml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type ellipse = {
c : float point;
rx : float;
ry : float;
rotation : float;
stroke : color option;
fill : color option;
}
Expand Down Expand Up @@ -55,7 +56,7 @@ let rectangle ?(c = center) width height =

let ellipse ?(c = center) rx ry =
let rx, ry = (float_of_int rx, float_of_int ry) in
Ellipse { c; rx; ry; stroke = Some Color.black; fill = None }
Ellipse { c; rx; ry; stroke = Some Color.black; fill = None; rotation = 0. }

let line ?(a = center) b = Line { a; b; stroke = Color.black }

Expand Down
1 change: 1 addition & 0 deletions lib/shape.mli
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type ellipse = {
c : float point;
rx : float;
ry : float;
rotation : float;
stroke : color option;
fill : color option;
}
Expand Down
7 changes: 6 additions & 1 deletion lib/transform.ml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,12 @@ let rotate_point degrees point =
let rec rotate degrees = function
| Circle circle' -> Circle { circle' with c = rotate_point degrees circle'.c }
| Ellipse ellipse' ->
Ellipse { ellipse' with c = rotate_point degrees ellipse'.c }
Ellipse
{
ellipse' with
c = rotate_point degrees ellipse'.c;
rotation = ellipse'.rotation +. to_radians degrees;
}
| Line line' -> Line { line' with a = rotate_point degrees line'.a; b = rotate_point degrees line'.b }
| Polygon polygon' ->
Polygon
Expand Down
1 change: 1 addition & 0 deletions lib/util.ml
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,4 @@ let rec partition n ?(step = 0) lst =

(* Misc *)
let range n = List.init n Fun.id
let to_radians degrees = degrees *. Stdlib.Float.pi /. 180.
1 change: 1 addition & 0 deletions lib/util.mli
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ val ( >> ) : ('a -> 'b) -> ('b -> 'c) -> 'a -> 'c
val take : int -> 'a list -> 'a list * 'a list
val partition : int -> ?step:int -> 'a list -> 'a list list
val range : int -> int list
val to_radians : float -> float

0 comments on commit a21d3c7

Please sign in to comment.