/* @(#)RegularShape.java   20 November 2006 */

/* Useful imports */

import edu.neu.ccs.*;
import edu.neu.ccs.gui.*;
import edu.neu.ccs.codec.*;
import edu.neu.ccs.console.*;
import edu.neu.ccs.filter.*;
import edu.neu.ccs.jpf.*;
import edu.neu.ccs.parser.*;
import edu.neu.ccs.pedagogy.*;
import edu.neu.ccs.quick.*;
import edu.neu.ccs.util.*;

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.font.*;
import java.awt.image.*;
import javax.swing.*;
import javax.swing.border.*;
import java.io.*;
import java.util.*;
import java.math.*;
import java.beans.*;
import java.lang.reflect.*;
import java.net.URL;
import java.util.regex.*;
import java.text.ParseException;


/**
 * Class <code>RegularShape</code> creates
 * regular polygons or regular star shapes.
 */
public class RegularShape
{
    /**
     * Creates a regular polygon
     * with center (x,y) and radius r with the initial
     * vertex positioned vertically above the center and
     * with the given number of vertices.
     */
    public static PolygonShape polygon
        (double x, double y, double r, int vertices)
    {
        return new PolygonShape
            (regularShapeDataFloat(x, y, r, vertices, 1));
    }
    
    
    /**
     * <p>Creates a regular polygon or a regular star shape
     * with center (x,y) and radius r with the initial
     * vertex positioned vertically above the center and
     * with the given number of vertices and given jump.</p>
     * 
     * <p>The shape is a regular polygon if jump equals 1.</p>
     */
    public static PolygonShape star
        (double x, double y, double r, int vertices, int jump)
    {
        return new PolygonShape
            (regularShapeDataFloat(x, y, r, vertices, jump));
    }
    
    
    public static double[][] regularShapeData
        (double x, double y, double r, int vertices, int jump)
    {
        // error check vertices
        vertices = Math.abs(vertices);
        
        if (vertices < 3)
            vertices = 3;
        
        // error check jump
        if (vertices < 5) {
            jump = 1;
        }
        else {
            jump = Math.abs(jump);
            
            jump = jump % vertices;
            
            int half = vertices / 2;
            
            if (jump > half)
                jump = vertices - jump;
            
            if ((jump == 0) || ((2 * jump) == vertices))
                jump = 1;
        }
        
        double[][] result = null;
        
        if (jump == 1)
            // polygon
        {
            int V = vertices;
            int I = 0;
            
            result = new double[V][2];
            
            double T = 0;           // initial angle
            double C = 360.0 / V;   // angular change
            
            while (I < V) {
                // polygon vertex
                result[I][0] =
                    x + r * MathUtilities.sindeg(T);
                
                result[I][1] =
                    y - r * MathUtilities.cosdeg(T);
                
                I++;
                T += C;
            }
        }
        else
            // star
        {
            // star has 2 * vertices points
            int V = 2 * vertices;
            int I = 0;
            
            result = new double[V][2];
            
            double T = 0;           // initial angle
            double C = 360.0 / V;   // angular change
            
            // Use Law of Sines to compute inner star radius s
            double A = 90.0  - C * jump;
            double B = 180.0 - A - C;
            
            double sinA = MathUtilities.sindeg(A);
            double sinB = MathUtilities.sindeg(B);
            
            double s = r * sinA / sinB;
            
            while (I < V) {
                // outer vertex at radius r
                result[I][0] =
                    x + r * MathUtilities.sindeg(T);
                
                result[I][1] =
                    y - r * MathUtilities.cosdeg(T);
                
                I++;
                T += C;
                
                // inner vertex at radius s
                result[I][0] =
                    x + s * MathUtilities.sindeg(T);
                
                result[I][1] =
                    y - s * MathUtilities.cosdeg(T);
                
                I++;
                T += C;
            }
        }
        
        return result;
    }
    
    
    public static float[][] regularShapeDataFloat
        (double x, double y, double r, int vertices, int jump)
    {
        double[][] dataD =
            regularShapeData(x, y, r, vertices, jump);
        
        int V = dataD.length;
        
        float[][] dataF = new float[V][2];
        
        for (int i = 0; i < V; i++)
            for (int j = 0; j < 2; j++)
                dataF[i][j] = (float) dataD[i][j];
        
        return dataF;
    }
     
}

