// returing curve for BC segment
 // all coords are vectors against Bpoint
 protected static String lastSegmentToCurve(int[][] stroke, float lineCurveThreshold)
     throws Exception {
   // Here we tidy up things left unfinished
   // What's left unfinished there is the curve between the last points
   // in the stroke
   // We can also be called when there is only one point in the stroke (meaning, the
   // stroke was just a dot), in which case there is nothing for us to do.
   // So for "this curve" to be calc'ed we need 3 points
   // 	A, B, C
   // and 2 lines:
   //  pre-line (from points A to B),
   //  this line (from points B to C)
   // Well, actually, we don't need to *know* the point A, just the vector A->B
   // so, we really need points B, C and AB vector.
   int positionInStroke = stroke.length - 1;
   // there must be at least 2 points in the stroke.for us to work. Hope calling code checks for
   // that.
   Vector BCvector = new Vector(stroke[positionInStroke][0], stroke[positionInStroke][1]);
   /* [UNSUPPORTED] 'var' as type is unsupported "var" */ rounding = 2;
   String curvetemplate = "c {0} {1} {2} {3} {4} {5}";
   String linetemplate = "l {0} {1}";
   if (positionInStroke > 1 && BCvector.getLength() > lineCurveThreshold) {
     // we have at least 3 elems in stroke
     Vector ABvector =
         new Vector(stroke[positionInStroke - 1][0], stroke[positionInStroke - 1][1]);
     /* [UNSUPPORTED] 'var' as type is unsupported "var" */ ABCangle =
         BCvector.angleTo(ABvector.getReversed());
     /* [UNSUPPORTED] 'var' as type is unsupported "var" */ minlenfraction = 0.05;
     /* [UNSUPPORTED] 'var' as type is unsupported "var" */ maxlen = BCvector.getLength() * 0.35;
     Vector BtoCP1vector =
         new Vector(ABvector.x + BCvector.x, ABvector.y + BCvector.y)
             .getResizedTo((float) (Math.Max(minlenfraction, ABCangle) * maxlen));
     return String.Format(
         curvetemplate,
         Math.Round(BtoCP1vector.x, rounding),
         Math.Round(BtoCP1vector.y, rounding),
         Math.Round(BCvector.x, rounding),
         Math.Round(BCvector.y, rounding),
         Math.Round(BCvector.x, rounding),
         Math.Round(BCvector.y, rounding));
   } else {
     return String.Format(
         linetemplate, Math.Round(BCvector.x, rounding), Math.Round(BCvector.y, rounding));
   }
 }
 protected static String segmentToCurve(
     int[][] stroke, int positionInStroke, float lineCurveThreshold) throws Exception {
   // long lines (ones with many pixels between them) do not look good when they are part of a
   // large curvy stroke.
   // You know, the jaggedy crocodile spine instead of a pretty, smooth curve. Yuck!
   // We want to approximate pretty curves in-place of those ugly lines.
   // To approximate a very nice curve we need to know the direction of line before and after.
   // Hence, on long lines we actually wait for another point beyond it to come back from
   // mousemoved before we draw this curve.
   // So for "prior curve" to be calc'ed we need 4 points
   // 	A, B, C, D (we are on D now, A is 3 points in the past.)
   // and 3 lines:
   //  pre-line (from points A to B),
   //  this line (from points B to C), (we call it "this" because if it was not yet, it's the only
   // one we can draw for sure.)
   //  post-line (from points C to D) (even through D point is 'current' we don't know how we can
   // draw it yet)
   //
   // Well, actually, we don't need to *know* the point A, just the vector A->B
   // Again, we can only derive curve between points positionInStroke-1 and positionInStroke
   // Thus, since we can only draw a line if we know one point ahead of it, we need to shift our
   // focus one point ahead.
   positionInStroke += 1;
   // Let's hope the code that calls us knows we do that and does not call us with positionInStroke
   // = index of last point.
   Vector CDvector = new Vector(stroke[positionInStroke][0], stroke[positionInStroke][1]);
   // Again, we have a chance here to draw only PREVIOUS line segment - BC
   // So, let's start with BC curve.
   // if there is only 2 points in stroke array (C, D), we don't have "history" long enough to have
   // point B, let alone point A.
   // so positionInStroke should start with 2, ie
   // we are here when there are at least 3 points in stroke array.
   Vector BCvector = new Vector(stroke[positionInStroke - 1][0], stroke[positionInStroke - 1][1]);
   Vector ABvector;
   int rounding = 2;
   String curvetemplate = "c {0} {1} {2} {3} {4} {5}";
   String linetemplate = "l {0} {1}";
   if (BCvector.getLength() > lineCurveThreshold) {
     // Yey! Pretty curves, here we come!
     if (positionInStroke > 2) {
       ABvector = new Vector(stroke[positionInStroke - 2][0], stroke[positionInStroke - 2][1]);
     } else {
       ABvector = new Vector(0, 0);
     }
     float minlenfraction = 0.05f;
     float maxlen = (float) (BCvector.getLength() * 0.35);
     float ABCangle = BCvector.angleTo(ABvector.getReversed());
     float BCDangle = CDvector.angleTo(BCvector.getReversed());
     Vector BtoCP1vector =
         new Vector(ABvector.x + BCvector.x, ABvector.y + BCvector.y)
             .getResizedTo((float) (Math.max(minlenfraction, ABCangle) * maxlen));
     Vector CtoCP2vector =
         new Vector(BCvector.x + CDvector.x, BCvector.y + CDvector.y)
             .getReversed()
             .getResizedTo((float) (Math.max(minlenfraction, BCDangle) * maxlen));
     Vector BtoCP2vector = new Vector(BCvector.x + CtoCP2vector.x, BCvector.y + CtoCP2vector.y);
     BigDecimal BtoCP1vector_x_BC = new BigDecimal(BtoCP1vector.x);
     BigDecimal BtoCP1vector_y_BC = new BigDecimal(BtoCP1vector.y);
     BigDecimal BtoCP2vector_x_BC = new BigDecimal(BtoCP2vector.x);
     BigDecimal BtoCP2vector_y_BC = new BigDecimal(BtoCP2vector.y);
     BigDecimal BCvector_x_BC = new BigDecimal(BCvector.x);
     BigDecimal BCvector_y_BC = new BigDecimal(BCvector.y);
     return MessageFormat.format(
         curvetemplate,
         BtoCP1vector_x_BC.setScale(rounding),
         BtoCP1vector_y_BC.setScale(rounding),
         BtoCP2vector_x_BC.setScale(rounding),
         BtoCP2vector_y_BC.setScale(rounding),
         BCvector_x_BC.setScale(rounding),
         BCvector_y_BC.setScale(rounding));
   } else {
     BigDecimal BCvector_x_BC = new BigDecimal(BCvector.x);
     BigDecimal BCvector_y_BC = new BigDecimal(BCvector.y);
     return MessageFormat.format(
         linetemplate, BCvector_x_BC.setScale(rounding), BCvector_y_BC.setScale(rounding));
   }
 }