public void generate(int x1,int y1,int x2,int y2){
  Point midPoint=new Point();
  Point arcCenter=new Point();
  Point2D peakPoint=new Point2D.Float();
  double distance=Math.sqrt(Math.pow(Math.abs(y2 - y1),2.0) + Math.pow(Math.abs(x2 - x1),2.0));
  double straightLineSlope=Math.atan((double)(y2 - y1) / (double)(x2 - x1));
  double inverseSlope=straightLineSlope - (Math.PI / 2.0);
  if (Debug.debugging("arc")) {
    Debug.output("ArcCalc.generate: Slope is " + Math.toDegrees(straightLineSlope) + " degrees, distance = "+ distance+ " pixels.");
  }
  midPoint.setLocation(x1 + ((x2 - x1) / 2),y1 + ((y2 - y1) / 2));
  if (Debug.debugging("arc")) {
    Debug.output("ArcCalc.generate: Center point for (" + x1 + ", "+ y1+ ") to ("+ x2+ ", "+ y2+ ") is ("+ midPoint.x+ ", "+ midPoint.y+ ")");
  }
  double arccos=Math.cos(arcAngle);
  double arcRadius;
  if (arccos != 1.0) {
    arcRadius=distance / Math.sqrt(2.0 * (1.0 - Math.cos(arcAngle)));
  }
 else {
    arcRadius=distance / Math.sqrt(2.0);
  }
  if (Debug.debugging("arc")) {
    Debug.output("ArcCalc.generate: radius of arc = " + arcRadius);
  }
  double x=arcRadius - arcRadius * Math.cos(arcAngle);
  double rPrime=(distance / 2.0) * (Math.sqrt(1.0 - Math.pow(x / distance,2.0))) / Math.sin(arcAngle / 2.0);
  if (Debug.debugging("arc")) {
    Debug.output("ArcCalc.generate: rPrime = " + rPrime);
  }
  int direction=1;
  if (arcUp)   direction=-1;
  arcCenter.x=midPoint.x + (direction * (int)(rPrime * Math.cos(inverseSlope)));
  arcCenter.y=midPoint.y + (direction * (int)(rPrime * Math.sin(inverseSlope)));
  if (Debug.debugging("arc")) {
    Debug.output("ArcCalc.generateArc: creating supplimental graphics list");
    arcGraphics=new OMGraphicList();
    double dist1=Math.sqrt(Math.pow((double)(arcCenter.x - x1),2.0) + Math.pow((double)(arcCenter.y - y1),2.0));
    double dist2=Math.sqrt(Math.pow((double)(arcCenter.x - x2),2.0) + Math.pow((double)(arcCenter.y - y2),2.0));
    Debug.output("ArcCalc.generate: Center focus for arc is (" + arcCenter.x + ", "+ arcCenter.y+ ") along slope line of "+ Math.toDegrees(inverseSlope)+ " degrees).");
    Debug.output("ArcCalc.generate: Distance to point 1 from arc focus = " + dist1 + "\n                    Distance to point 2 from arc focus = "+ dist2);
    OMRect point1=new OMRect(x1 - 1,y1 - 1,x1 + 1,y1 + 1);
    OMRect point2=new OMRect(x2 - 1,y2 - 1,x2 + 1,y2 + 1);
    OMRect arcPoint=new OMRect(arcCenter.x - 1,arcCenter.y - 1,arcCenter.x + 1,arcCenter.y + 1);
    point1.setLinePaint(OMColor.red);
    point2.setLinePaint(OMColor.red);
    arcPoint.setLinePaint(OMColor.blue);
    arcGraphics.add(point1);
    arcGraphics.add(point2);
    arcGraphics.add(arcPoint);
    OMLine line1=new OMLine(x1,y1,x2,y2);
    OMLine line2=new OMLine(midPoint.x,midPoint.y,arcCenter.x,arcCenter.y);
    arcGraphics.add(line1);
    arcGraphics.add(line2);
  }
  int realCount=0;
  double startSlope=getRealAngle((float)arcCenter.getX(),(float)arcCenter.getY(),x1,y1);
  double endSlope=getRealAngle((float)arcCenter.getX(),(float)arcCenter.getY(),x2,y2);
  double smallSlope, largeSlope;
  double angleIncrement;
  smallSlope=(startSlope > endSlope) ? endSlope : startSlope;
  largeSlope=(smallSlope == startSlope) ? endSlope : startSlope;
  while (Math.abs(smallSlope - largeSlope) > Math.PI) {
    if (Math.abs(largeSlope - smallSlope - Math.PI) < .001) {
      break;
    }
    Debug.message("arc","ArcCalc.generate: Modifying the starting slope.");
    double tmpSlope=smallSlope + MoreMath.TWO_PI;
    smallSlope=largeSlope;
    largeSlope=tmpSlope;
  }
  if (MoreMath.approximately_equal(arcAngle,Math.PI) && arcUp) {
    Debug.message("arc","ArcCalc.generate: Modifying 180 angle points.");
    double tmpSlope=smallSlope + MoreMath.TWO_PI;
    smallSlope=largeSlope;
    largeSlope=tmpSlope;
  }
  if (Math.abs(y2 - y1) < Math.abs(x2 - x1)) {
    angleIncrement=Math.PI / Math.abs(x2 - x1);
  }
 else {
    angleIncrement=Math.PI / Math.abs(y2 - y1);
  }
  int numPoints=(int)(Math.abs(smallSlope - largeSlope) / angleIncrement + 2);
  float[] xPoints=new float[numPoints];
  float[] yPoints=new float[numPoints];
  if (Debug.debugging("arc")) {
    Debug.output("ArcCalc.generate: angle to x1, y1 is " + startSlope + " ("+ Math.toDegrees(startSlope)+ " degrees), angle to x2, y2 is "+ endSlope+ " ("+ Math.toDegrees(endSlope)+ " degrees)");
    Debug.output("ArcCalc.generate: Starting angle is " + smallSlope + "("+ Math.toDegrees(smallSlope)+ " degrees), end angle is "+ largeSlope+ " ("+ Math.toDegrees(largeSlope)+ " degrees), incrementing by "+ angleIncrement+ " ("+ Math.toDegrees(angleIncrement)+ " degrees)");
  }
  reversed=false;
  while (smallSlope < largeSlope && realCount < numPoints) {
    xPoints[realCount]=arcCenter.x + (int)(arcRadius * Math.cos(smallSlope));
    yPoints[realCount]=arcCenter.y + (int)(arcRadius * Math.sin(smallSlope));
    if (realCount == 0 && xPoints[realCount] == x2) {
      Debug.message("arc","ArcCalc: line reversed");
      reversed=true;
    }
    if (Debug.debugging("arc") && realCount == 0) {
      OMLine startLine=new OMLine(arcCenter.x,arcCenter.y,(int)xPoints[0],(int)yPoints[0]);
      startLine.setLinePaint(OMColor.white);
      arcGraphics.add(startLine);
    }
 else     if (Debug.debugging("arcdetail")) {
      Debug.output("  angle " + smallSlope + " ("+ smallSlope * 180 / Math.PI + " degrees)  = " + xPoints[realCount] + ", " + yPoints[realCount]);
    }
    if (Math.abs(largeSlope - smallSlope - (arcAngle / 2.0)) < angleIncrement) {
      peakPoint.setLocation(xPoints[realCount],yPoints[realCount]);
      Debug.message("arc","ArcCalc: Found a midpoint.");
    }
    smallSlope+=angleIncrement;
    realCount++;
  }
  xpoints=new float[realCount];
  ypoints=new float[realCount];
  System.arraycopy(xPoints,0,xpoints,0,realCount);
  System.arraycopy(yPoints,0,ypoints,0,realCount);
}

public void generate ( int x1 , int y1 , int x2 , int y2 ) { Point midPoint = new Point ( ) ; Point arcCenter = new Point ( ) ; Point2D peakPoint = new Point2D . Float ( ) ; double distance = Math . sqrt ( Math . pow ( Math . abs ( y2 - y1 ) , 2.0 ) + Math . pow ( Math . abs ( x2 - x1 ) , 2.0 ) ) ; double straightLineSlope = Math . atan ( ( double ) ( y2 - y1 ) / ( double ) ( x2 - x1 ) ) ; double inverseSlope = straightLineSlope - ( Math . PI / 2.0 ) ; if ( Debug . debugging ( "arc" ) ) { Debug . output ( "ArcCalc.generate: Slope is " + Math . toDegrees ( straightLineSlope ) + " degrees, distance = " + distance + " pixels." ) ; } midPoint . setLocation ( x1 + ( ( x2 - x1 ) / 2 ) , y1 + ( ( y2 - y1 ) / 2 ) ) ; if ( Debug . debugging ( "arc" ) ) { Debug . output ( "ArcCalc.generate: Center point for (" + x1 + ", " + y1 + ") to (" + x2 + ", " + y2 + ") is (" + midPoint . x + ", " + midPoint . y + ")" ) ; } double arccos = Math . cos ( arcAngle ) ; double arcRadius ; if ( arccos != 1.0 ) { arcRadius = distance / Math . sqrt ( 2.0 * ( 1.0 - Math . cos ( arcAngle ) ) ) ; } else { arcRadius = distance / Math . sqrt ( 2.0 ) ; } if ( Debug . debugging ( "arc" ) ) { Debug . output ( "ArcCalc.generate: radius of arc = " + arcRadius ) ; } double x = arcRadius - arcRadius * Math . cos ( arcAngle ) ; double rPrime = ( distance / 2.0 ) * ( Math . sqrt ( 1.0 - Math . pow ( x / distance , 2.0 ) ) ) / Math . sin ( arcAngle / 2.0 ) ; if ( Debug . debugging ( "arc" ) ) { Debug . output ( "ArcCalc.generate: rPrime = " + rPrime ) ; } int direction = 1 ; if ( arcUp ) direction = - 1 ; arcCenter . x = midPoint . x + ( direction * ( int ) ( rPrime * Math . cos ( inverseSlope ) ) ) ; arcCenter . y = midPoint . y + ( direction * ( int ) ( rPrime * Math . sin ( inverseSlope ) ) ) ; if ( Debug . debugging ( "arc" ) ) { Debug . output ( "ArcCalc.generateArc: creating supplimental graphics list" ) ; arcGraphics = new OMGraphicList ( ) ; double dist1 = Math . sqrt ( Math . pow ( ( double ) ( arcCenter . x - x1 ) , 2.0 ) + Math . pow ( ( double ) ( arcCenter . y - y1 ) , 2.0 ) ) ; double dist2 = Math . sqrt ( Math . pow ( ( double ) ( arcCenter . x - x2 ) , 2.0 ) + Math . pow ( ( double ) ( arcCenter . y - y2 ) , 2.0 ) ) ; Debug . output ( "ArcCalc.generate: Center focus for arc is (" + arcCenter . x + ", " + arcCenter . y + ") along slope line of " + Math . toDegrees ( inverseSlope ) + " degrees)." ) ; Debug . output ( "ArcCalc.generate: Distance to point 1 from arc focus = " + dist1 + "\n                    Distance to point 2 from arc focus = " + dist2 ) ; OMRect point1 = new OMRect ( x1 - 1 , y1 - 1 , x1 + 1 , y1 + 1 ) ; OMRect point2 = new OMRect ( x2 - 1 , y2 - 1 , x2 + 1 , y2 + 1 ) ; OMRect arcPoint = new OMRect ( arcCenter . x - 1 , arcCenter . y - 1 , arcCenter . x + 1 , arcCenter . y + 1 ) ; point1 . setLinePaint ( OMColor . red ) ; point2 . setLinePaint ( OMColor . red ) ; arcPoint . setLinePaint ( OMColor . blue ) ; arcGraphics . add ( point1 ) ; arcGraphics . add ( point2 ) ; arcGraphics . add ( arcPoint ) ; OMLine line1 = new OMLine ( x1 , y1 , x2 , y2 ) ; OMLine line2 = new OMLine ( midPoint . x , midPoint . y , arcCenter . x , arcCenter . y ) ; arcGraphics . add ( line1 ) ; arcGraphics . add ( line2 ) ; } int realCount = 0 ; double startSlope = getRealAngle ( ( float ) arcCenter . getX ( ) , ( float ) arcCenter . getY ( ) , x1 , y1 ) ; double endSlope = getRealAngle ( ( float ) arcCenter . getX ( ) , ( float ) arcCenter . getY ( ) , x2 , y2 ) ; double smallSlope , largeSlope ; double angleIncrement ; smallSlope = ( startSlope > endSlope ) ? endSlope : startSlope ; largeSlope = ( smallSlope == startSlope ) ? endSlope : startSlope ; while ( Math . abs ( smallSlope - largeSlope ) > Math . PI ) { if ( Math . abs ( largeSlope - smallSlope - Math . PI ) < .001 ) { break ; } Debug . message ( "arc" , "ArcCalc.generate: Modifying the starting slope." ) ; double tmpSlope = smallSlope + MoreMath . TWO_PI ; smallSlope = largeSlope ; largeSlope = tmpSlope ; } if ( MoreMath . approximately_equal ( arcAngle , Math . PI ) && arcUp ) { Debug . message ( "arc" , "ArcCalc.generate: Modifying 180 angle points." ) ; double tmpSlope = smallSlope + MoreMath . TWO_PI ; smallSlope = largeSlope ; largeSlope = tmpSlope ; } if ( Math . abs ( y2 - y1 ) < Math . abs ( x2 - x1 ) ) { angleIncrement = Math . PI / Math . abs ( x2 - x1 ) ; } else { angleIncrement = Math . PI / Math . abs ( y2 - y1 ) ; } int numPoints = ( int ) ( Math . abs ( smallSlope - largeSlope ) / angleIncrement + 2 ) ; float [ ] xPoints = new float [ numPoints ] ; float [ ] yPoints = new float [ numPoints ] ; if ( Debug . debugging ( "arc" ) ) { Debug . output ( "ArcCalc.generate: angle to x1, y1 is " + startSlope + " (" + Math . toDegrees ( startSlope ) + " degrees), angle to x2, y2 is " + endSlope + " (" + Math . toDegrees ( endSlope ) + " degrees)" ) ; Debug . output ( "ArcCalc.generate: Starting angle is " + smallSlope + "(" + Math . toDegrees ( smallSlope ) + " degrees), end angle is " + largeSlope + " (" + Math . toDegrees ( largeSlope ) + " degrees), incrementing by " + angleIncrement + " (" + Math . toDegrees ( angleIncrement ) + " degrees)" ) ; } reversed = false ; while ( smallSlope < largeSlope && realCount < numPoints ) { xPoints [ realCount ] = arcCenter . x + ( int ) ( arcRadius * Math . cos ( smallSlope ) ) ; yPoints [ realCount ] = arcCenter . y + ( int ) ( arcRadius * Math . sin ( smallSlope ) ) ; if ( realCount == 0 && xPoints [ realCount ] == x2 ) { Debug . message ( "arc" , "ArcCalc: line reversed" ) ; reversed = true ; } if ( Debug . debugging ( "arc" ) && realCount == 0 ) { OMLine startLine = new OMLine ( arcCenter . x , arcCenter . y , ( int ) xPoints [ 0 ] , ( int ) yPoints [ 0 ] ) ; startLine . setLinePaint ( OMColor . white ) ; arcGraphics . add ( startLine ) ; } else if ( Debug . debugging ( "arcdetail" ) ) { Debug . output ( "  angle " + smallSlope + " (" + smallSlope * 180 / Math . PI + " degrees)  = " + xPoints [ realCount ] + ", " + yPoints [ realCount ] ) ; } if ( Math . abs ( largeSlope - smallSlope - ( arcAngle / 2.0 ) ) < angleIncrement ) { peakPoint . setLocation ( xPoints [ realCount ] , yPoints [ realCount ] ) ; Debug . message ( "arc" , "ArcCalc: Found a midpoint." ) ; } smallSlope += angleIncrement ; realCount ++ ; } xpoints = new float [ realCount ] ; ypoints = new float [ realCount ] ; System . arraycopy ( xPoints , 0 , xpoints , 0 , realCount ) ; System . arraycopy ( yPoints , 0 , ypoints , 0 , realCount ) ; }
generate the points that will generate the curved line between two points . the arcangle is the number of radians of a circle that the arc should represent . math . pi is the max . the setarcangle should be called before this method is called , so that the method knows what to create .
