private void douglasPeuckerSimplificationRoutine(Point[] bpoints, int j, int k, boolean[] pointMarker){
      if (k <= j + 1)return;                    // there is nothing to simplify
        
      // check for adequate approximation by segment S from v[j] to v[k]
      int farthesti = j;                        // index of vertex farthest from S
      double farthestDistance2 = 0.0;           // distance squared of farthest vertex
      Point[] segment = Point.oneDarray(2);     // define segment
      segment[0] = bpoints[j];
      segment[1] = bpoints[k];
      VectorMaths vjk = new VectorMaths(bpoints[j], bpoints[k]);
      double dist2jk = bpoints[j].distanceSquared(bpoints[k]);
      VectorMaths seg0i = null;
      Point perplBase = null;               // base of perpendicular point under consideration to S
      double lratio = 0.0;
      double svang = 0.0; 
      double dist2ps = 0.0;                 // dv2 = distance of point under consideration to to S squared

      for (int i = j + 1; i < k; i++) {
        seg0i = new VectorMaths(segment[0],bpoints[i]);
        svang = seg0i.dot(vjk);
        if (svang <= 0){
            dist2ps = Point.distanceSquared(bpoints[i], segment[0]);
        }
        else{
            if (dist2jk <= svang){
                dist2ps = Point.distanceSquared(bpoints[i], segment[1]);
            }
            else{
                lratio = svang/dist2jk;
                VectorMaths vlr = vjk.times(lratio);
                VectorMaths s0vlr = (new VectorMaths(segment[0])).plus(vlr);
                perplBase = s0vlr.getFinalPoint();
                dist2ps = Point.distanceSquared(bpoints[i], perplBase);
            }
        }
        // test with current max distance squared
        if (dist2ps <= farthestDistance2)continue;
        // v[i] is a new max vertex
        farthesti = i;
        farthestDistance2 = dist2ps;
      }
      if (farthestDistance2 > this.toleranceSquared){        // error is worse than the tolerance
        // split the polyline at the farthest vertex from S
        pointMarker[farthesti] = true;      
        // recursively simplify the two subpolylines
        douglasPeuckerSimplificationRoutine(bpoints, j, farthesti, pointMarker);  
        douglasPeuckerSimplificationRoutine(bpoints, farthesti, k, pointMarker); 
      }
    }