Sindbad~EG File Manager

Current Path : /usr/home/beeson/public_html/dynamicgeometry/org/dynamicgeometry/scripts/
Upload File :
Current File : /usr/home/beeson/public_html/dynamicgeometry/org/dynamicgeometry/scripts/Scripts.java

package org.dynamicgeometry.scripts;
import sun.reflect.Reflection;
import java.util.ArrayList;
import org.dynamicgeometry.diagrammer.GeometricObject;
import org.dynamicgeometry.diagrammer.Point;

// 11.5.06 made Euclid public, provided Earlier and earlier, put in code to deal with PackagePath so that it should look twice for the class.
// 12.18.06 added ActiveLine
// 12.21.06 added ReturnTypes and getReturnTypes
// 12.24.06 added Purpose
// 12.25.06 added setCommands

/**
 * author: Michael Beeson. This code is in the public domain.
 */

class IllegalScriptException extends Exception{
   public IllegalScriptException(){}
   public IllegalScriptException(String msg) { super(msg);}
}


public class Scripts
{
	String Name;
	String ReturnType;
	String[] ReturnTypes;   // for scripts with multiple returns
	String[] ParameterNames;
	String[] ParameterTypes;
	String[] Script;
	public String Purpose;      // for pedagogic use
	public String EuclidReference;       // for pedagogic use, e.g. "Book I, Prop. 2"
	public int ActiveLine;


	private static final String PackagePath = "org.dynamicgeometry.scripts.";
	private static Class getScriptClass(String CommandName)
	// return the class formed by adding "Script" to ScriptName,  finding it using the PackagePath.
	{ try{
	       return Class.forName(CommandName + "Script");
	     }
	  catch (ClassNotFoundException e)
	     {  //System.out.println("Class " + CommandName + "Script not found,  probably the package path is wrong.");
	        // so try it again with no package path
	        try{
	           return Class.forName(PackagePath + CommandName + "Script");
	           }
	        catch(ClassNotFoundException e2)
	           { System.out.println("Senor, you reeeally have a problem with " + CommandName);
	           }
	     }
	  return null;

	}

	public Scripts(String n, String ret, String[] p, String[] q, String[] s)
	{
		Name = n;
		ReturnType = ret;
		ReturnTypes = null;
		ParameterNames = p;
		ParameterTypes = q;
		Script = s;
	}

   public Scripts(String _Name, String _ReturnType, String[] _ParameterNames, String[] _ParameterTypes, String[] _Script, String[] _ReturnTypes)
	{
		Name = _Name;
		ReturnType = _ReturnType;
		ParameterNames = _ParameterNames;
		ParameterTypes = _ParameterTypes;
		Script = _Script;
		ReturnTypes = _ReturnTypes;
	}
	/**
	 * @return The name of this script
	 */
	public static final String[] Euclid = {
			"EquilateralTriangle", // Book I, prop. 1
			"CopySegment", // Book I, prop. 2
			"CopySegmentOntoLine", // Book I, prop. 3
			"CopySegmentOntoLine2", // done
			"BisectAngle2", // Book I, prop. 9 --uses EquilateralTriangle
			"BisectAngle",  // continuous solution, using BisectSegment
			"BisectSegment", // Book I, prop. 10
			"BisectSegment2", // Book I, prop. 10
			"ErectPerpendicular", // Book I, prop. 11
			"DropPerpendicular", // Book I, prop. 12
			"TriangleFromSegments", // Book I, Prop. 22
			"ConstructTriangle", // Book I, prop. 22 (alternate)
			"CircleFromCenterAndRadius", // not directly in Euclid
			"CopyAngleToSegment", // Book I, prop. 23
			"ParallelThroughPoint", // Book I, prop. 31
			"ParallelogramEqualToTriangle", // Book I, prop. 42.  This works only in Euclidean geometry
			"ParallelogramOfGivenWidthEqualToTriangle", // Book I, prop. 44
			// "ParallelogramEqualToQuadrilateral",  // Book I, prop. 45.  This requires accessing the points of a quadrilateral,
			//                                          and that is not in the specs.
			"SquareOnGivenSide",                   // Book I, prop. 46
			"SquareOnGivenSide2",                  // shorter method
			"CutSegmentInGoldenSection",           // Book II, prop. 11
			//"SquareEqualToConvexPolygon",
			"FindCenterOfCircle",
			"TangentToCircle",
			"CircleFromArc",
			"BisectCircumference",
			"GivenSegmentAndAngleConstructCircle",
			"GivenCircleAndAngleConstructArc",
			"FitSegmentInCircle",
			"TriangleInCircle",
			"TriangleAroundCircle",
			"CircleInTriangle",
			"CircleAroundTriangle",
			"SquareInCircle",
			"SquareAroundCircle",
			"CircleInSquare",
			"CircleAroundSquare",
			"ConstructGoldenTriangle",
			"PentagonInCircle",
			"PentagonAroundCircle",
			"CircleInPentagon",
			"CircleAroundPentagon",
			"HexagonInCircle",
			"FifteenGonInCircle",
			"DivideSegmentIntoParts",
			"SegmentOnLine",
			"ThirdProportional",
			"FourthProportional",
			"MeanProportional",
			"SimilarConvexPolygonWithGivenSide"}; // not finished yet

    private static final boolean done(String ScriptName)
    // return true if it's been implemented
    { return earlier(ScriptName, "FindCenterOfCircle");
    }

	/**
	 * @return The name of the script
	 */
	public String getName()
	{
		return Name;
	}

	/**
	 * @return The return type of the script
	 */
	public String getReturnType()
	{
		return ReturnType;
	}

	/**
	* @return The purpose of the script, i.e. its postcondition
	*/

	public String getPurpose()
	{
	    return Purpose;
	}


	/**
	 * @return The variables used to name the points, lines, segments, arcs,
	 *         circles, etc. that are the inputs to this script.
	 */
	public String[] getParameters()
	{
		return ParameterNames;
	}

	/**
	 * @return The types of the variables used to name the points, lines,
	 *         segments, arcs, circles, etc. that are the inputs to this script.
	 */
	public String[] getParameterNames()
	{
		return ParameterNames;
	}

	/**
	 * @return The types of the variables used to name the points, lines,
	 *         segments, arcs, circles, etc. that are the inputs to this script.
	 */
	public String[] getParameterTypes()
	{
		return ParameterTypes;
	}

	/**
	 * @return The Geoscript commands making up the script.
	 */
	public String[] getScript()
	{
		return Script;
	}

	/**
		 * @return The Geoscript commands making up the script.
		 */
		public void setScript(String[] newCommands)
		{
		   Script = newCommands;
		}


	/**
	 * @param CommandName
	 *        The name of a supported construction.
	 * @return The Geoscript for the construction named in the parameter. A
	 *         construction "Foo" is supported if class FooScript exists
	 *         extending Scripts.
	 */
	static public String[] getScript(String CommandName)
		throws ClassNotFoundException, InstantiationException,
		IllegalAccessException
	{
		Class C = getScriptClass(CommandName);
		Scripts X = (Scripts)C.newInstance();
		return X.getScript();
	}

	static public Scripts getScriptObject(String CommandName)
	{
	    Class C = getScriptClass(CommandName);
	    Scripts ans;
		try{ ans = (Scripts)C.newInstance();}
		catch(Exception ex) { ex.printStackTrace(); return null;}
		return ans;
	}

	/**
	* @return The return types of a script with multiple returns
	*/
	static public String[] getReturnTypes(String CommandName)
	throws ClassNotFoundException, InstantiationException,
		IllegalAccessException
	{
	    Class C = getScriptClass(CommandName);
		Scripts X = (Scripts)C.newInstance();
		return X.ReturnTypes;
	}


	/**
	 * @param CommandName
	 *        The name of a supported construction.
	 * @return the list of variables used in the script to name the input
	 *         parameters. A construction "Foo" is supported if class FooScript
	 *         exists extending Scripts. Deprecated way to call
	 *         getParameterNames--use that method instead.
	 */
	static public String[] getParameters(String CommandName)
		throws ClassNotFoundException, InstantiationException,
		IllegalAccessException
	{
		Class C = getScriptClass(CommandName);
		Scripts X = (Scripts)C.newInstance();
		return X.getParameterNames();
	}

	/**
	 * @param CommandName
	 *        The name of a supported construction.
	 * @return the list of variables used in the script to name the input
	 *         parameters. A construction "Foo" is supported if class FooScript
	 *         exists extending Scripts.
	 */
	static public String[] getParameterNames(String CommandName) throws
		ClassNotFoundException, InstantiationException, IllegalAccessException
	{
	    Class C = getScriptClass(CommandName);
		Scripts X = (Scripts)C.newInstance();
		return X.getParameterNames();
	}
    /** Get the return type of any command, whether it is primitive or defined by a script.
    */
	static public String getReturnType(String CommandName) throws
		ClassNotFoundException, InstantiationException, IllegalAccessException
	{   String t = primitiveReturnType(CommandName);
	    if(t != null)
	        return t;
	    Class C = getScriptClass(CommandName);
		Scripts X = (Scripts)C.newInstance();
		return X.ReturnType;
	}

	/**
	 * @param CommandName
	 *        The name of a supported construction.
	 * @return the list of types of the parameters of this command. Example:
	 *         since the Midpoint command takes two Points,
	 *         getParameterTypes("Midpoint") returns {"Point", "Point"}. A
	 *         construction "Foo" is supported if class FooScript exists
	 *         extending Scripts.
	 */
	static public String[] getParameterTypes(String CommandName)
		throws ClassNotFoundException, InstantiationException, IllegalAccessException
	{
		Class C = getScriptClass(CommandName);
		Scripts X = (Scripts)C.newInstance();
		return X.getParameterTypes();
	}

    public static final boolean Earlier(String FirstScript, String SecondScript)
//   it's in the specs with a capital E
    {   return earlier(FirstScript, SecondScript);
    }

    public static final boolean earlier(String FirstScript, String SecondScript)
   //   it's in the specs with a capital E, but Java methods should begin with lowercase, so here it is both ways.
   //   returns true if FirstScript is a member of Euclid and SecondScript is not listed in Euclid before FirstScript.
   //   Otherwise, returns false.  In particular it returns false if SecondScript is listed in Euclide before FirstScript
   //   or is not listed at all.  It also returns false in the special case when the two inputs are equal.
    {   for(String s: Euclid)
           { if(s == FirstScript && s != SecondScript)
		         return true;
             if(s != SecondScript)
                  return false;
           }
        return false;
    }


	// Returns a new instance of the Script
	public static Scripts finalScript(String scriptName)
		throws ClassNotFoundException, InstantiationException, IllegalAccessException
	{
		Scripts X = null;
		try
		{
			Class C = getScriptClass(scriptName);
		    X = (Scripts)C.newInstance();
		}
		catch(Exception ioe)
		{
			System.out.println("Class " + scriptName + " not found.");
			ioe.printStackTrace();
		}
		return X;
	}

	/**
	 * This provides a unit test for the class Scripts
	 */
	public static void main(String args[])
	{
		for (String CommandName : Euclid)
		{   if(!done(CommandName))
		        continue;
			try
			{

				String[] Script = getScript(CommandName);
				String[] ParameterNames = getParameterNames(CommandName);
				String[] ParameterTypes = getParameterTypes(CommandName);
				String ReturnType = getReturnType(CommandName);
				System.out.print(ReturnType + " " + CommandName + "(");
				if (ParameterNames.length > 0)
				{
					System.out.print(ParameterTypes[0]);
					System.out.print(" " + ParameterNames[0]);
				}
				int i;
				for (i = 1; i < ParameterNames.length; ++i)
				{
					System.out.print("," + ParameterTypes[i]);
					System.out.print(" " + ParameterNames[i]);
				}
				System.out.println(")");
				for (String s : Script)
					System.out.println(s);
			}
			catch (Exception e)
			{   System.out.println( e.getMessage());
				// System.out.println("Oops! " + CommandName + " hasn't been programmed yet.");
			}
		}
	}

   /**
	 *	Return true if the given command is primitive, false otherwise
	 */
	public  static boolean isPrimitiveCommand( String cmdName ) {
		if( cmdName.equalsIgnoreCase( "line" )) return true;
		else if( cmdName.equalsIgnoreCase( "segment" )) return true;
		else if( cmdName.equalsIgnoreCase( "circle" )) return true;
		else if( cmdName.equalsIgnoreCase( "ray" )) return true;
		else if( cmdName.equalsIgnoreCase( "arc" )) return true;
		else if( cmdName.equalsIgnoreCase( "triangle" )) return true;
		else if( cmdName.equalsIgnoreCase( "quadrilateral" )) return true;
		else if( cmdName.equalsIgnoreCase( "vertex" )) return true;
		else if( cmdName.equalsIgnoreCase( "intersectLines" )) return true;
		else if( cmdName.equalsIgnoreCase( "intersectLineCircle1" )) return true;
		else if( cmdName.equalsIgnoreCase( "intersectLineCircle2" )) return true;
		else if( cmdName.equalsIgnoreCase( "intersectLineCircle3" )) return true;
		else if( cmdName.equalsIgnoreCase( "intersectCircles1" )) return true;
		else if( cmdName.equalsIgnoreCase( "intersectCircles2" )) return true;
		else if( cmdName.equalsIgnoreCase( "extend" )) return true;
		return false;
	}

	/**
     *  Return the return type of a primitive command.
     *  Returns null if cmdName is not a primitive command.
     */
    private static String primitiveReturnType(String cmdName)
    {
        if( cmdName.equalsIgnoreCase( "line" )) return "Line";
		else if( cmdName.equalsIgnoreCase( "segment" )) return "Segment";
		else if( cmdName.equalsIgnoreCase( "circle" )) return "Circle";
		else if( cmdName.equalsIgnoreCase( "ray" )) return "Ray";
		else if( cmdName.equalsIgnoreCase( "arc" )) return "Arc";
		else if( cmdName.equalsIgnoreCase( "triangle" )) return "Triangle";
		else if( cmdName.equalsIgnoreCase( "quadrilateral" )) return "Quadrilateral";
		else if( cmdName.equalsIgnoreCase( "vertex" )) return "Point";
		else if( cmdName.equalsIgnoreCase( "intersectLines" )) return "Point";
		else if( cmdName.equalsIgnoreCase( "intersectLineCircle1" )) return "Point";
		else if( cmdName.equalsIgnoreCase( "intersectLineCircle2" )) return "Point";
		else if( cmdName.equalsIgnoreCase( "intersectLineCircle3" )) return "Point";
		else if( cmdName.equalsIgnoreCase( "intersectCircles1" )) return "Point";
		else if( cmdName.equalsIgnoreCase( "intersectCircles2" )) return "Point";
		else if( cmdName.equalsIgnoreCase( "extend" )) return "Point";
		return null;    // command is not primitive
	}


  /** Produces initial data for the script commandName.
  *   The members of the returned ArrayList must match the parameters
  *   of commandName in label and type.  They must also satisfy the
  *   preconditions (hypotheses) of commandName, and they should ideally
  *   look nice on the screen as well, in particular allowing the whole
  *   construction to complete visibly in the applet window.
  */
  public ArrayList<GeometricObject> startData(int width, int height)
  throws IllegalScriptException

  {
    int minDistance = 50;
	int n = ParameterTypes.length;
	if(n != ParameterNames.length)
	    throw(new IllegalScriptException("Parameter names and types have different length in " +  Name));

	ArrayList<GeometricObject> ans = new ArrayList(n);
	// prepare the arguments for the construction
	for(int i = 0; i < n; ++i)
	{
		GeometricObject nextarg = null;
		try {
	    	  Class cls = Class.forName("org.dynamicgeometry.diagrammer." + ParameterTypes[i]);
	    	  nextarg = (GeometricObject) cls.newInstance();
	    	  if(nextarg == null)
			    throw new IllegalScriptException("Illegal parameter type in script " +  Name);
			  ans.add(nextarg);

	    	}
	    catch(Exception ex)
	    	{   ex.printStackTrace();
			}
	    nextarg.setVisible(true);
	    nextarg.setIsInput(0);   // strangely,  0 means it IS in an input.
	    nextarg.setLabelFromString(ParameterNames[i]);
	    nextarg.setSelected(true);
	    if(ParameterTypes[i].equals("Point"))
	    {
	       double dMin = 0.0;
  	       double d;
 	       boolean ok = false;
	       do
	         { d = 2* Math.max(width,height);
	           ok = true;
	           double margin = 0.35;
	           double x = Math.random()*(width - 2*margin *width) + margin*width;
 	           double y = Math.random()*(height - 2*margin *height) + margin*height;
 	           boolean firstFlag = false;
	           for(int j = 0;j<i;j++)
	              { if(!ParameterTypes[j].equals("Point"))
	                   continue;
	                d = Math.hypot(x- ((Point) ans.get(j)).getX(), y - ((Point) ans.get(j)).getY());
	                if(d < minDistance)
	                   { // this x and y won't do
	                     ok = false;
	                     break;
	                   }
	              }
	          if(ok)
	              { // this x and y are OK
	                ((Point) ans.get(i)).setX((int)x);
	                ((Point) ans.get(i)).setY((int)y);
	              }
	         } while(!ok);
	    }
	 }
     return ans;
   }


}

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists