views:

272

answers:

6

Hello there. I'm a first year programmer. I'm trying to create a squircle. (square with round corners).

So far i have managed to get. I have been given the constants of a,b and r. If anyone could help i would be really thankful. I'm a total noob to this. So be nice :)

package squircle;

import java.awt.*;
import javax.swing.*;
import java.lang.Math;

public class Main extends javax.swing.JApplet {

  public void paint(Graphics g){

   // (x-a)^4  +  (y-b)^4  = r^4

   //    y =   quadroot( r^4 - (x-a)^4  + b)     
   // x values must fall within   a-r < x < a+r

    int[] xPoints = new int[200];
    int[] yPoints = new int[200];
    int[] mypoints = new int[200];

    for(int c = 0; c <200; c++){

       int a = 100;
       int r = 100;
       int b = 100;
       double x = c ;


       double temp = (r*r*r*r);
       double temp2 = x-a;
       double temp3 = ((temp2)*(temp2)*(temp2)*(temp2));
       double temp6 = Math.sqrt(temp-temp3);
       double y = (Math.sqrt(temp6) + b );
       double z = (y*-1)+300;

       mypoints[c]=(int)z;

    // if (c>100){
    //     y = y*1;
    // }
    // else if(c<100){
    //     y = y*1;
    // }

       xPoints[c]=(int)x;
       yPoints[c]=(int)y;


    // change the equation to find x co-ordinates 
    // change it to find y co-ordinates. 

    // r is the minor radius     
    // (a,b) is the location of the centre

    // a = 100
    // b = 100
    // r = 100
    // x value must fall within  0 or 200

    }

    g.drawPolygon(xPoints, yPoints, xPoints.length);
    g.drawPolygon(xPoints, (mypoints), xPoints.length);
  }
}
+4  A: 

Is it homework or is there some other reason why you're not using Graphics#drawRoundRect()?

jarnbjo
+1 for stating the obvious :)
javamonkey79
I must use the formula. I cannot use drawroundrect(). I need to store the numbers calculated in two different arrays. x and y.
Will
I'm not really sure if it is so obvious. Is he trying to draw a squircle or a square with round corners? These are two different shapes and drawRoundRect cannot be used to draw a squircle. Perhaps I should try to understand the question better the next time and ignore it if it doesn't make sense.
jarnbjo
I'm trying to draw a Squircle.
Will
Then why did you ask for a square with round corners?
jarnbjo
Meh, who cares - he said it in the title. See: http://en.wikipedia.org/wiki/Squircle
javamonkey79
Yeah i did put it in bracket. Just so people know what i'm talking about
Will
+4  A: 

If you are submitting this as homework there are some elements of style that may help you. What are the roles of 200, 100 and 300? These are "magic constants" which should be avoided. Are they related or is it just chance that they have these values? Suggest you use symbols such as:

int NPOINTS = 200;

or

double radius = 100.0

That would reveal whether the 300 was actually the value you want. I haven't checked.

Personally I wouldn't write

y*-1

but

-y

as it's too easy to mistype the former.

I would also print out the 200 points as floats and see if you can tell by eye where the error is. It's highly likely that the spurious lines are either drawn at the start or end of the calculation - it's easy to make "end-effect" errors where exactly one point is omitted or calculated twice.

Also it's cheap to experiment. Try iterating c from 0 to 100. or 0 to 10, or 0 to 198 or 1 to 200. Does your spurious line/triangle always occur?

UPDATE Here is what I think is wrong and how to tackle it. You have made a very natural graphics error and a fence-post error (http://en.wikipedia.org/wiki/Off-by-one%5Ferror) and it's hard to detect what is wrong because your variable names are poorly chosen.

What is mypoints? I believe it is the bottom half of the squircle - if you had called it bottomHalf then those replying woulod have spotted the problem quicker :-).

Your graphics problem is that you are drawing TWO HALF-squircles. Your are drawing CLOSED curves - when you get to the last point (c==199) the polygon is closed by drawing back to c==0. That makes a D-shape. You have TWO D-shapes, one with the bulge UP and one DOWN. Each has a horizontal line closing the polygon.

Your fence-post error is that you are drawing points from 0 to 199. For the half-squircle you want to draw from 0 to 200. That's 201 points! The loss of one point means that you have a very slightly sloping line. The bottom lines slopes in tghe opposite direction from the top. That gives you a very then wedge shape, which you refer to as a triangle. I'm guessing that your triangle is not actually closed but like a slice from a pie but very then/sharp.

(The code below could be prettier and more compact. However it is often useful to break symmetrical problems into quadrants or octants. It would also be interesting to use an anngle to sweep out the polygon).

You actually want ONE polygon. The code should be something like:

int NQUADRANT = 100;
int NPOINTS = 4*NQUADRANT ; // closed polygon
double[] xpoints = new double[NPOINTS];
double[] ypoints = new double[NPOINTS];

Your squircle is at 100, 100 with radius 100. I have chosen different values here to emphasize they aren't related. By using symbolic names you can easily vary them.

double xcenter = 500.0;
double ycentre = 200.0;
double radius = 100.;

double deltax = radius/(double) NQUADRANT;
// let's assume squircle is centered on 0,0 and add offsets later
// this code is NOT complete or correct but should show the way
// I might have time later
for (int i = 0; i < NPOINTS; i++) {

if (i < NQUADRANT) {
    double x0 = -radius + i* deltax;
    double y0 = fourthRoot(radius, x0);
    x[i] = x0+xcenter;
    y[i] = y0+ycenter;

}else if (i < 2*NQUADRANT) {
    double x0 = (i-NQUADRANT)* deltax;
    double y0 = fourthRoot(radius, x0);
    x[i] = x0+xcenter;
    y[i] = y0+ycenter;
}else if (i < 3*NQUADRANT) {
    double x0 = (i-2*NQUADRANT)* deltax;
    double y0 = -fourthRoot(radius, x0);
    x[i] = x0+xcenter;
    y[i] = y0+ycenter;
}else {
    double x0 = -radius + (i-3*NQUADRANT)* deltax;
    double y0 = -fourthRoot(radius, x0);
    x[i] = x0+xcenter;
    y[i] = y0+ycenter;
}

}
// draw single polygon

private double fourthRoot(double radius, double x) {
    return Math.sqrt(Math.sqrt(radius*radius*radius*radius - x*x*x*x));
}
peter.murray.rust
A: 

Hello,

I know Will and have been trying to help him with it, but I'm not a Java (or desktop at all) person, and I don't have time to set up the SDK/NetBeans/Swing.

I got thrown by the squircle/square rectangle catch first too, but mainly because I have never seen or heard of a squircle.

When this code is run, the squircle is generated but it looks as if there is a triangle intersecting this. My guess at the reason is that it's not drawing some of the points? Whether this is the case, and the reason for it are a mystery, as maths is also not one of my talents.

Richard

Richard John
A: 

There is a javascript version here. You can view the source and "compare notes" to potentially see what you are doing wrong.

javamonkey79
A: 

Ok, upon further investigation here is why you are getting the "triangle intersecting it". When you drawPolygon the points are drawn and the last point connects the first point, closing the points and making the polygon. Since you draw one half it is drawn (then connected to itself) and then the same happens for the other side.

As a test of this change your last couple lines to this:

  for( int i = 0; i < yPoints.length; i++ ) {
   g.drawString( "*", xPoints[ i ], yPoints[ i ] );
  }

  for( int i = 0; i < mypoints.length; i++ ) {
   g.drawString( "*", xPoints[ i ], mypoints[ i ] );
  }

//  g.drawPolygon( xPoints, yPoints, xPoints.length );
//  g.drawPolygon( xPoints, ( mypoints ), xPoints.length );

It is a little crude, but I think you'll get the point. There are lots of solutions out there, personally I would try using an array of the Point class and then sort it when done, but I don't know the specifics of what you can and can not do.

javamonkey79
A: 

Wow, are you guys overthinking this, or what! Why not just use drawLine() four times to draw the straight parts of the rectangle and then use drawArc() to draw the rounded corners?

Bartek Tatkowski
Actually, never mind. I apparently don't know the difference between a squircle and a rectangle with rounded corners.
Bartek Tatkowski