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");

}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.