2
$\begingroup$

i'am a junior in computer graphics , currently i learn how to draw ellipses with rotation .

when i preform rotation with 90deg or 180deg nothing unusual happened , but when i try to rotate with any other value the result will be like this :

enter image description here

here's a pseudo-code of what iam doing , i didn't put the original function because it's huge .

function draw_circle( x_origin , y_origin , width , height ){

// go in scan-line order and try to find intercept x,y around the ellipse
   for( y = 0 ; y <= height ; y++ ){   

       for( x = width  ; x >= 0; x-- ){

            // when we find point x , y
            if( ( x*x / width ) + ( y*y / height  ) <= 1 ){

                  // rotate a copy of x,y
                  rotate_z( x , y , by_angle );

                  // draw the rotate x,y copy
                  set_pixle( x_origin + x , y_origin + y );
                   
                  /*
                     then preform reflection in the other side 
                     of the ellipse 
                  */
            }

       }
   }
}
$\endgroup$
4
  • 1
    $\begingroup$ Welcome to computer graphics stack exchange. To help you find out how to fix the eclipse rotation bug, we need more information about how you have implemented it. An idial way to help us helping you is to provide some code and tell us, what you have tried so far. Otherwise we only can guess. $\endgroup$
    – Thomas
    Apr 9 at 4:53
  • $\begingroup$ hello @Thomas , and thanks for the comment , i didn't put the original function because it's huge but i put a pseudo-code instead :) $\endgroup$
    – 0x00001F
    Apr 9 at 8:25
  • 1
    $\begingroup$ Not enough info. $\endgroup$
    – joojaa
    Apr 9 at 18:25
  • $\begingroup$ hi @joojaa what's missing , i can add it . $\endgroup$
    – 0x00001F
    Apr 11 at 21:14

2 Answers 2

3
$\begingroup$

The guilty is the post-rotation after you have generated points of the un-rotated ellipse. Because rotation on a raster does not preserve the density of the pixels.

A solution is to work directly with the equation of the rotated ellipse, of the (centered) form

$$px^2+2qxy+ry^2=1.$$

You can obtain it by plugging $u=x\cos\theta-y\sin\theta,v=x\sin\theta+y\cos\theta$ in

$$\frac{u^2}{a^2}+\frac{v^2}{b^2}=1.$$


Note that your computation is fairly heavy because you try all pixels, i.e. $w\cdot h$ of them, which can be a lot.

You can reduce the number of computations by

  • looping on $y$,

  • for a given value of $y$, solving the quadratic equation $px^2+2qxy+ry^2-1=0$ for $x$

  • when the slope of the curve becomes less than $1$ (so that a row will contain several pixels of the outline), switching to a loop on $x$, computing the corresponding $y$.

The switching points occur when the slope is $\pm1$, or

$$|px+qy|=|qx+ry|.$$


Yet a faster method is by using an outline-following algorithm on the digital domain

$$px^2+2qxy+ry^2\le1.$$

https://www.imageprocessingplace.com/downloads_V3/root_downloads/tutorials/contour_tracing_Abeer_George_Ghuneim/alg.html

$\endgroup$
3
  • 1
    $\begingroup$ hi Yves Daoust , thank you for the explanation and the notes , i want to give you +1 but i can't :( $\endgroup$
    – 0x00001F
    Apr 11 at 21:07
  • 1
    $\begingroup$ @0x00001F: don't worry, I am not after "points". $\endgroup$
    – user1703
    Apr 12 at 6:31
  • 2
    $\begingroup$ But you deserve them, so I will +1 your answer on behalf of @0x00001F $\endgroup$
    – higuaro
    Apr 13 at 2:06
1
$\begingroup$

I think you should transform your coordinates before checking if they touch the boundary. You seem to use a scatter approach and every pixel that touch the non-transformed ellipse will land on only one pixel. Because the number of pixels that touch the boundary are "uniform" along curves that correspond to a rotated pixel grid, you will get holes and clusters which you can see in your zoomed in example.

$\endgroup$
2
  • 1
    $\begingroup$ hi @Mathis thank you for the answer <3 $\endgroup$
    – 0x00001F
    Apr 11 at 20:54
  • 1
    $\begingroup$ i want to give +1 but i can't for now :( $\endgroup$
    – 0x00001F
    Apr 11 at 21:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.