Re: Extents under rotation
Uli Schlachter <[email protected]>
| Newsgroups | gmane.comp.lib.cairo |
|---|---|
| Message-ID | <[email protected]> |
On 08.12.2013 16:19, Donn wrote: > On 07/12/2013 20:22, Uli Schlachter wrote: >> Uhm. So the above code should do just this, right? > Uli,thanks for your input again. > > I put together this code (in Vala) using your idea: [...] > cr.arc (0.0, 0.0, 30.0, 0, 2*Math.PI); > cr.set_source_rgb(1,1,0); > cr.fill_preserve(); > > cr.save(); > cr.identity_matrix(); > cr.path_extents(out x1, out y1, out x2, out y2); > > //Draw this device rect in green > cr.new_path(); > cr.rectangle(x1,y1,(x2-x1),(y2-y1)); > cr.set_source_rgb(0,1,0); > cr.set_line_width(3); > cr.stroke(); > > cr.restore(); > > //Go from device into user > cr.device_to_user(ref x1, ref y1); > cr.device_to_user(ref x2, ref y2); > > //Draw this user rect in white. > cr.new_path(); > cr.move_to(x1,y1); > cr.line_to(x2,y1); > cr.line_to(x2,y2); > cr.line_to(x1,y2); > cr.close_path(); > [...] That's not what I suggested. You cannot just transform the top-left and bottom-right corner of the extents and assume that the other ones can be deduced from that (this is not an axis-aligned rectangle in user space!). Attached is a working version. The diff to your version is also attached. Cheers, Uli -- cairo mailing list [email protected] http://lists.cairographics.org/mailman/listinfo/cairo
test.patch
(text/x-patch, 955 B)
--- test.orig 2013-12-08 17:36:24.634988805 +0100
+++ test.vala 2013-12-08 17:48:36.827865336 +0100
@@ -2,6 +2,12 @@
// View the img.png file after running "test"
using Cairo;
+
+void foo(ref Cairo.Context cr, double x, double y) {
+ cr.device_to_user(ref x, ref y);
+ cr.line_to(x, y);
+}
+
void main(string[] args) {
double x1;
@@ -70,16 +76,13 @@ void main(string[] args) {
cr.restore();
- //Go from device into user
- cr.device_to_user(ref x1, ref y1);
- cr.device_to_user(ref x2, ref y2);
//Draw this user rect in white.
cr.new_path();
- cr.move_to(x1,y1);
- cr.line_to(x2,y1);
- cr.line_to(x2,y2);
- cr.line_to(x1,y2);
+ foo(ref cr, x1, y1);
+ foo(ref cr, x2, y1);
+ foo(ref cr, x2, y2);
+ foo(ref cr, x1, y2);
cr.close_path();
cr.set_source_rgb(1,1,1);
test.vala
(text/x-vala, 2.5 KB)
// valac --pkg cairo test_extents_under_rotation.vala -o test
// View the img.png file after running "test"
using Cairo;
void foo(ref Cairo.Context cr, double x, double y) {
cr.device_to_user(ref x, ref y);
cr.line_to(x, y);
}
void main(string[] args) {
double x1;
double x2;
double y1;
double y2;
Cairo.ImageSurface surface = new Cairo.ImageSurface
(Cairo.Format.ARGB32, 500, 500);
Cairo.Context cr = new Cairo.Context (surface);
//centre the axes - 0,0 in middle
var matrix = Cairo.Matrix (1, 0, 0, 1, 250,250 );
matrix.scale (1, 1);
cr.transform(matrix);
cr.arc (0.0, 0.0, 30.0, 0, 2*Math.PI);
cr.set_source_rgb(1,0,0);
cr.fill_preserve();
cr.path_extents (out x1, out y1, out x2, out y2);
stdout.printf("Extents: %G|%G|%G|%G\n", x1,y1,x2,y2);
//Draw the bbox as calculated by extents
cr.rectangle(x1,y1,(x2-x1),(y2-y1));
cr.set_source_rgb(0,0,0);
cr.stroke();
//Now, rotate that circle 45 degrees (and move it over a bit)
cr.translate(90,0);
cr.rotate((Math.PI/180.0)*45); //45 degree rot
cr.arc (0.0, 0.0, 30.0, 0, 2*Math.PI);
cr.set_source_rgb(1,0,0);
cr.fill_preserve();
cr.path_extents (out x1, out y1, out x2, out y2);
stdout.printf("Extents: %G|%G|%G|%G\n", x1,y1,x2,y2);
//Draw the bbox as calculated by extents -- this is wrong.
//Why is the rect so much bigger?
//Is there any way to get the proper user-space coords?
cr.rectangle(x1,y1,(x2-x1),(y2-y1));
cr.set_source_rgb(0,0,0);
cr.stroke();
//Test Uli's idea
cr.translate(0,120);
cr.rotate((Math.PI/180.0)*67);
//Unusual rot. 45 degrees sometimes disguises things.
cr.arc (0.0, 0.0, 30.0, 0, 2*Math.PI);
cr.set_source_rgb(1,1,0);
cr.fill_preserve();
cr.save();
cr.identity_matrix();
cr.path_extents(out x1, out y1, out x2, out y2);
//Draw this device rect in green
cr.new_path();
cr.rectangle(x1,y1,(x2-x1),(y2-y1));
cr.set_source_rgb(0,1,0);
cr.set_line_width(3);
cr.stroke();
cr.restore();
//Draw this user rect in white.
cr.new_path();
foo(ref cr, x1, y1);
foo(ref cr, x2, y1);
foo(ref cr, x2, y2);
foo(ref cr, x1, y2);
cr.close_path();
cr.set_source_rgb(1,1,1);
cr.stroke();
surface.write_to_png ("img.png");
}