0

This is partially a math question and partially a java implementation question.

I am trying to paint a triangle using the fillPolygon(Polygon p) method in Java Graphics.

Have an class, Triangle.java which extends Polygon and takes two parameters: Point location and int height. The purpose of the height parameter is to easily size the height of the triangle then calculate the side lengths by solving a 30, 60, 90 triangle.

public class Triangle extends Polygon {

    private final static int numberOfSides = 3;

    // Class creates a polygon for use in fillPolygon() method call in
    // Piece.java
    public Triangle(Point p, int height) {

        // Pass in the hieght of the desired triangle and the side lengths will
        // be calculated by solving a 30, 60, 90 triangle
        super(new int[] { p.x,
                (p.x + ((int) ((2 * height) / Math.sqrt(3.0)) / 2)),
                p.x + (int) ((2 * height) / Math.sqrt(3.0)) }, new int[] {
                (p.y + (int) ((2 * height) / Math.sqrt(3.0))), p.y,
                (p.y + (int) ((2 * height) / Math.sqrt(3.0))) }, numberOfSides);
    }

What I need to be able to do is create a method for a concentric triangle regardless of the size or location of the triangle. Obviously the vertecies of the inner triangle have to be equidistant from the all vertices of the outer triangle (particularly easy if the outer triangle is equilateral). The gap between the triangles is irrelevant as I hope that can be passed in as a parameter.

Like I said this is mostly a math question, though I haven't found an equation for general equidistance with concentric triangles.

Thanks for your help in advanced.

EDIT: I solved this issue. I had to rework how I approached the Triangle (used Path2D.Double instead of Polygon for better accuracy), but it worked out. This is how I did it:

With the advice from @ajb I calculated the Circumcenter of an equilateral triangle (which is the same as the other centroids) and then calculated coordinates of the Triangle for use with Path2D.Double:

public class Triangle extends Path2D.Double {

private double[] xCoordinates, yCoordinates, innerXCoordinates,
        innerYCoordinates;
private Point location;
private double height, circumcenterRadius, sideLength;

public Triangle(Point p, double h) {

    if (p != null && h > 0) {
        this.location = p;
        this.height = h;

        this.circumcenterRadius = (2.0 / 3.0) * (this.height);
        this.sideLength = (2 * this.height)/Math.sqrt(3.0);
    }

    // Set values for the x coordiantes using location and height
    this.xCoordinates = new double[] { p.x,
            p.x + sideLength/ 2,
            p.x + sideLength };

    // Set values for the x coordinates using location and height
    this.yCoordinates = new double[] { p.y + this.height, p.y,
            p.y + this.height };
}

Then using the correct coordinates, iterate through then and add them to the Path:

 public void constructPath() {
    // Sets the path to the first coordinates of the triangle (bottom left).
    this.moveTo(this.xCoordinates[0], this.yCoordinates[0]);

    // Iterates through the coordinates and adds them to the path
    for (int i = 1; i < this.xCoordinates.length; i++) {
        this.lineTo(this.xCoordinates[i], this.yCoordinates[i]);
    }

    // Closes the path and compeletes the Polygona
    this.closePath();
}

I then created a method which will takes the desired difference in Circumcenter Radii (to determine how much to downscale the circumscribed triangle). Using that, I calculated the x and y offset in order to reposition the inner triangle so that it will be correctly inscribed inside of the outer triangle

public Path2D constructInscribedTriangle(double radiusDifference) {

    // Calculate the new circumcenterRadius of the inscribed Triangle
    double innerCircumcenterRadius = (this.circumcenterRadius - radiusDifference);
    double innerHeight = (3.0 / 2.0) * innerCircumcenterRadius;
    double innerSideLength = (2 * innerHeight)/Math.sqrt(3.0);

    double xOffset = (radiusDifference/2) * (Math.sqrt(3.0)); 

    // Recalculate coordintes for inner Triangle
    this.innerXCoordinates = new double[] {
            (this.location.x + xOffset),
            (this.location.x + xOffset)
                    + innerSideLength/ 2,
            (this.location.x + xOffset)
                    + innerSideLength };

    this.innerYCoordinates = new double[] {
            (this.location.y + radiusDifference) + innerHeight,
            (this.location.y + radiusDifference),
            (this.location.y + radiusDifference) + innerHeight };

    Path2D.Double inscribedTriangle = new Path2D.Double();

    inscribedTriangle.moveTo(this.innerXCoordinates[0],
            this.innerYCoordinates[0]);
    for (int h = 1; h < this.innerXCoordinates.length; h++) {
        inscribedTriangle.lineTo(this.innerXCoordinates[h],
                this.innerYCoordinates[h]);
    }

    inscribedTriangle.closePath();

    return inscribedTriangle;
}
user1118321
  • 24,739
  • 4
  • 55
  • 82
Jacob Young
  • 25
  • 1
  • 8
  • I would, personally, use some kind of `Shape` and simply translate/transform it, but that's just me, for [example](http://stackoverflow.com/questions/16434273/drawing-sierpinskis-triangle-in-java/16434439#16434439) and [example](http://stackoverflow.com/questions/13676364/flipping-shape-not-image/13676513#13676513), but I like easy ;) – MadProgrammer Jul 29 '14 at 04:48
  • @MadProgrammer Thanks for the response. I see your reasonings for not using paint() and I thank you. I guess I have been lazy in that regard and I will modify my code to include it where it is not needed. I can also try and use a shape but at the moment I have a very elaborate system of XML Unmarshalling with JAXB in order to contract something for a game, and I am limited to using Polygons and Grpahics for the moment. I appreciate your response :D – Jacob Young Jul 29 '14 at 04:52
  • I think you want the center of the circumbscribed circle. http://en.wikipedia.org/wiki/Circumcenter tells how to get the coordinates (scroll down to Cartesian coordinates). Then if you draw a line from the circumcenter to each vertex, then you can figure out how to compute the point on that line that is a given distance from the vertex. This will give you a triangle with the same circumcenter. So far I don't know if there's a simple formula that does everything. Looks interesting, I might work on this ... – ajb Jul 29 '14 at 05:08
  • @ajb that's exactly what I needed! I think I can work with that and make method for placing a triangle a determined distance from each vertex – Jacob Young Jul 29 '14 at 05:11

0 Answers0