views:

39

answers:

2

Hey, I'm trying to write a method that takes a starting Cartesian coordinate(x,y) an angle (in degrees), a length and a number of sides and draws a shape to an applet. So far this is what I have but, I cant figure out what I'm doing wrong. I plan on using line transformations for the actual angle change and that's not written in yet but the logic for drawing a line at an angle should work but isn't as far as I can tell. Could I get a couple of new eyes to look at this and tell me if I'm missing something.

public void paint(Graphics g)
{
    g.setColor(Color.BLACK);
    Point startPt = new Point(0,0);
    //Function in question  
    drawRegularPolygon(g, startPt, 5,60,50);    
}

public static void drawRegularPolygon(Graphics g, Point2D startPoint, int numOfSides, int angle, int length)
{

    Point2D current = startPoint;
    for(int i=0; i<numOfSides; i++)
    {
        drawAngularLine(g, current, angle, length);
        current = getEndPoint(current ,length,angle);
    }
}

public static void drawAngularLine(Graphics g, Point2D startPoint, int angle, int length)
{
    g.setColor(Color.BLACK);
    Point2D endPoint = getEndPoint(startPoint, length, angle);
    ((Graphics2D) g).draw(new Line2D.Double(startPoint, endPoint));
}

private static Point2D getEndPoint(Point2D p, int length, int angle)
{
    //Starting point you know (x1, x2), 
    //end point is (x1 + l * cos(ang), y1 + l * sin(ang)) 
    //where l is the length and ang is the angle.
    Point2D retVal = p; 
    double x = Math.cos(Math.toRadians(angle)*length+p.getX());
    double y = Math.sin(Math.toRadians(angle)*length+p.getY());
    retVal.setLocation(x,y);
    return retVal;
}
+1  A: 

You are drawing a line with the same start point and end point - so nothing is drawn.

Java objects are passed by reference, so:

private static Point2D getEndPoint(Point2D p, int length, int angle){
   Point2D retVal = p;
   retVal.setLocation(x,y);
   return retVal;
}

is also changing the starting point p. So it draws a line of length 1 (does it show a dot on the screen?).

Try using:

Point2D retVal = p.clone();
Peter Knego
+1  A: 

A couple things. The first is to be careful about what you're taking sin/cosine of. It's not cos(angle*length) but rather length*cos(angle).

The second point is to think about coordinate systems. It might help to do the math assuming the initial point is (0,0), and then translate to the screen coordinates. This helps avoid the confusion of the y-axis seeming to be upside-down (values increase from top to bottom).

So assuming we just want a point that's length,angle away from the origin in a standard right-handed system, we'd get:

x1 = length * cos(angle)
y1 = length * sin(angle)

But since negative-y is up, we actually want

x2 = length * cos(angle)
y2 = -length * sin(angle)

To mentally check this, picture that you're doing this math at the origin (0,0) which is in the upper left, and have an angle of 45°. If y2 were positive, we'd end up seeing an angle that looks to us like -45°.

Now translate the origin to our starting point (x_i, y_i), to get our final values:

x_f = x_i + length * cos(angle)
y_f = y_i + (-length * cos(angle)) = y_i - length * cos(angle)

Alternatively, if it makes more sense to work in a standard right-handed coordinate system, you probably could get away with doing all the math as if (0,0) were in the center, and then applying a translation and a y-axis mirror transformation, but this screen coordinate system isn't too difficult to work within once you get used to flipping the y values around.

Ben Taitelbaum