/*******************************************************************************
* Copyright (c) 2016 Weasis Team and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Nicolas Roduit - initial API and implementation
*******************************************************************************/
package org.weasis.core.ui.model.utils.algo;
import java.util.List;
/**
* The Class ChainPoint.
*
* @author Nicolas Roduit
*/
public class ChainPoint implements Comparable<ChainPoint> {
// Fields
public final int x;
public final int y;
private float segLength;
public ChainPoint(int x, int y) {
this.x = x;
this.y = y;
}
// get the length of the segment between the current point and the next one.
public float getSegLength() {
return segLength;
}
public void setSegLength(float segLength) {
this.segLength = segLength;
}
@Override
public int compareTo(ChainPoint anotherPoint) {
return (this.y < anotherPoint.y ? -1
: (this.y == anotherPoint.y ? (this.x < anotherPoint.x ? -1 : (this.x == anotherPoint.x ? 0 : 1)) : 1));
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ChainPoint other = (ChainPoint) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
public static double[] regression(List<ChainPoint> list) {
double meanx = 0.0;
double meany = 0.0;
for (int i = 0; i < list.size(); i++) {
ChainPoint p = list.get(i);
meanx += p.x;
meany += p.y;
}
meanx /= list.size();
meany /= list.size();
/*
* We have to solve two equations with two unknows:
*
* 1) mean(y) = b + m*mean(x) 2) mean(xy) = b*mean(x) + m*mean(x²)
*
* Those formulas lead to a quadratic equation. However, the formulas become very simples if we set 'mean(x)=0'.
* We can achieve this result by computing instead of (2):
*
* 2b) mean(dx y) = m*mean(dx²)
*
* where dx=x-mean(x). In this case mean(dx)==0.
*/
double meanx2 = 0;
double meany2 = 0;
double meanxy = 0;
for (int i = 0; i < list.size(); i++) {
ChainPoint p = list.get(i);
double xi = p.x;
double yi = p.y;
xi -= meanx;
meanx2 += xi * xi;
meany2 += yi * yi;
meanxy += xi * yi;
}
meanx2 /= list.size();
meany2 /= list.size();
meanxy /= list.size();
/*
* Assuming that 'mean(x)==0', then the correlation coefficient can be approximate by:
*
* R = mean(xy) / sqrt( mean(x²) * (mean(y²) - mean(y)²) )
*/
double[] val = new double[3];
val[0] = meanxy / meanx2; // slope
if (Double.isNaN(val[0])) {
val[0] = 0.0;
}
val[1] = meany - meanx * val[0]; // y0 or b
val[2] = meanxy / Math.sqrt(meanx2 * (meany2 - meany * meany)); // R
if (Double.isInfinite(val[2]) || Double.isNaN(val[2])) {
val[2] = 1;
}
return val;
}
}