docs: protected void updateLocation( T image , RectangleRotate_F32 region ) {
  
  		double bestHistScore = Double.MAX_VALUE;
  		float bestX = -1, bestY = -1;
  
  		for( int i = 0; i < maxIterations; i++ ) {
  			calcHistogram.computeHistogram(image,region);
  
  			float histogram[] = calcHistogram.getHistogram();
  			updateWeights(histogram);
  
  			// the histogram fit doesn't always improve with each mean-shift iteration
  			// save the best one and use it later on
  			double histScore = distanceHistogram(keyHistogram, histogram);
  			if( histScore < bestHistScore ) {
  				bestHistScore = histScore;
  				bestX = region.cx;
  				bestY = region.cy;
  			}
  
  			List<Point2D_F32> samples = calcHistogram.getSamplePts();
  			int sampleHistIndex[] = calcHistogram.getSampleHistIndex();
  
  			// Compute equation 13
  			float meanX = 0;
  			float meanY = 0;
  			float totalWeight = 0;
  			for( int j = 0; j < samples.size(); j++ ) {
  				Point2D_F32 samplePt = samples.get(j);
  
  				int histIndex = sampleHistIndex[j];
  
  				if( histIndex < 0 )
  					continue;
  
  				// compute the weight derived from the Bhattacharyya coefficient.  Equation 10.
  				float w = weightHistogram[histIndex];
  
  				meanX += w*samplePt.x;
  				meanY += w*samplePt.y;
  				totalWeight += w;
  			}
  			meanX /= totalWeight;
  			meanY /= totalWeight;
  
  			// convert to image pixels
  			calcHistogram.squareToImageSample(meanX, meanY, region);
  			meanX = calcHistogram.imageX;
  			meanY = calcHistogram.imageY;
  
  			// see if the change is below the threshold
  			boolean done = Math.abs(meanX-region.cx ) <= minimumChange && Math.abs(meanY-region.cy ) <= minimumChange;
  			region.cx = meanX;
  			region.cy = meanY;
  
  			if( done ) {
  				break;
  			}
  		}
  
  		// use the best location found
  		region.cx = bestX;
  		region.cy = bestY;
  	}