简体   繁体   中英

How can I transform an ellipse to a rectangle in Java?

I am currently working on making a screensaver and I want my ellipse to slowly transform to a rectangle in java. What is the easiest way of doing that?

There are some shapes that are easy to transform into one another. For instance a square is a rectangle with equal side lengths, a circle is an ellipse with equal axes. So it is easy to transform a square into a rectangle since you can just use some drawrectangle function and adjust the parameters the whole way. Ditto for circle to ellipse.

squaretorect(double width,double height)
{
//Transform a square width * width to a rectangle width * height
int n = 100;//Number of intermediate points
int i;
double currentheight;
for(i=0;i<n;i++)
{
currentheight = width + (height-width) * i/(n-1);
drawrectangle(width,currentheight);
}
}

Transforming from a rectangle to an ellipse is harder, since in between the shape is neither a rectangle nor an ellipse. It may be that there is some more general object which can be either a rectangle, an ellipse, or something in between, but I cannot think of one.

So, the easy way is out, but there is a harder way to do it. Suppose if I divide the unit circle into N pieces and write points on an ellipse Ei and a rectangle Ri. Now as the transformation happens the points Ei move into the points Ri. A simple way to do this is to use a linear combination.

Ti = (1-v) * Ei + v * Ri

So to do the transformation we slowly increment v from 0 to 1. And we draw lines(or better yet interpolate) between the points Ti.

ellipsetorectangle(double a, double b, double w, double h)
{
 //(x/a)^2+(y/b)^2 = 1
 //Polar r = 1/sqrt(cos(phi)^2/a^2 + sin(phi)^2/b^2)

int N = 1000;
int i;
double phi; double r;
double phirect = atan(w/h);//Helps determine which of the 4 line segments we are on
ArrayList<Point> Ei;
ArrayList<Point> Ri;
for(i=0;i<N;i++)
{
//Construct ellipse
phi = 2PI * (double)i/N;
r = 1/sqrt(cos(phi)^2/a^2 + sin(phi)^2/b^2);
Ei.add(new Point(r * cos(phi),r * sin(phi));

//Construct Rectangle (It's hard)
if(phi > 2Pi - phirect || phi < phirect)
{Ri.add(new Point(w/2,w/2 * tan(phi)));}
else if(phi > phirect)
{Ri.add(new Point(h/2 * tan(phi),h/2));}
else if(phi > PI-phirect)
{Ri.add(new Point(-w/2,-w/2 * tan(phi)));}
else if(phi > PI+phirect)
{Ri.add(new Point(-h/2,-h/2 * tan(phi)));}
}

}

Arraylist<Point> Ti;
int transitionpoints = 100;
double v;
int j;
for(j=0;j<transitionpoints;j++)
{
//This outer loop represents one instance of the object. You should probably clear the picture here. This probably belongs in a separate function but it would take awhile to write it that way.
for(i=0;i<N;i++)    
{    
v = (double)1 * j/(N-1);
Ti = new Point(v * Ri.get(i).getx + (1-v) * Ei.get(i).getx,
     v * Ri.get(i).gety + (1-v) * Ei.get(i).gety);
if(i != 0)
drawline(Ti,Tiold);
Tiold = Ti;
}
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM