/*
* Copyright (c) 2010, Frederik Vanhoutte This library is free software; you can
* redistribute it and/or modify it under the terms of the GNU Lesser General
* Public License as published by the Free Software Foundation; either version
* 2.1 of the License, or (at your option) any later version.
* http://creativecommons.org/licenses/LGPL/2.1/ This library is distributed in
* the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
* the GNU Lesser General Public License for more details. You should have
* received a copy of the GNU Lesser General Public License along with this
* library; if not, write to the Free Software Foundation, Inc., 51 Franklin St,
* Fifth Floor, Boston, MA 02110-1301 USA
*/
package wblut.geom;
import java.util.ArrayList;
import java.util.List;
// TODO: Auto-generated Javadoc
/**
* Planar polygon class.
*/
public class WB_Polyline {
/** Ordered array of WB_Point. */
public WB_Point3d[] points;
/** Number of points. */
public int n;
/**
* Instantiates a new WB_Polyline.
*/
public WB_Polyline() {
points = new WB_Point3d[0];
n = 0;
}
/**
* Instantiates a new WB_Polyline.
*
* @param points array of WB_Point, no copies are made
* @param n number of points
*/
public WB_Polyline(final WB_Point3d[] points, final int n) {
this.points = points;
this.n = n;
}
/**
* Instantiates a new WB_Polyline.
*
* @param points array of WB_Point
* @param n number of points
* @param copy copy points?
*/
public WB_Polyline(final WB_Point3d[] points, final int n,
final boolean copy) {
if (copy == false) {
this.points = points;
} else {
this.points = new WB_Point3d[n];
for (int i = 0; i < n; i++) {
this.points[i] = points[i].get();
}
}
this.n = n;
}
/**
* Instantiates a new WB_Polyline.
*
* @param points arrayList of WB_Point
*/
public WB_Polyline(final List<WB_Point3d> points) {
n = points.size();
this.points = new WB_Point3d[n];
for (int i = 0; i < n; i++) {
this.points[i] = points.get(i);
}
}
/**
* Set polyline.
*
* @param points array of WB_Point, no copies are made
* @param n number of points
*/
public void set(final WB_Point3d[] points, final int n) {
this.points = points;
this.n = n;
}
/**
* Set polyline.
*
* @param poly source polygon, no copies are made
*/
public void set(final WB_Polyline poly) {
points = poly.points;
n = poly.n;
}
/**
* Set polyline.
*
* @param points arrayList of WB_Point, no copies are made
* @param n number of points
*/
public void set(final ArrayList<WB_Point3d> points, final int n) {
this.points = new WB_Point3d[n];
for (int i = 0; i < n; i++) {
this.points[i] = points.get(i);
}
this.n = n;
}
/**
* Get deep copy.
*
* @return copy
*/
public WB_Polyline get() {
final WB_Point3d[] newPoints = new WB_Point3d[n];
for (int i = 0; i < n; i++) {
newPoints[i] = points[i].get();
}
return new WB_Polyline(newPoints, n);
}
/**
* Get shallow copy.
*
* @return copy
*/
public WB_Polyline getNoCopy() {
return new WB_Polyline(points, n);
}
/**
* Closest point on polyline to given point.
*
* @param p point
* @return closest point of polyline
*/
public WB_Point3d closestPoint(final WB_Point3d p) {
double d = Double.POSITIVE_INFINITY;
int id = -1;
for (int i = 0; i < n; i++) {
final double cd = WB_Distance.sqDistance(p, points[i]);
if (cd < d) {
id = i;
d = cd;
}
}
return points[id];
}
/**
* Index of closest point on polyline to given point.
*
* @param p point
* @return index of closest point of polyline
*/
public int closestIndex(final WB_Point3d p) {
double d = Double.POSITIVE_INFINITY;
int id = -1;
for (int i = 0; i < n; i++) {
final double cd = WB_Distance.sqDistance(p, points[i]);
if (cd < d) {
id = i;
d = cd;
}
}
return id;
}
/**
* Removes point.
*
* @param i index of point to remove
* @return new WB_Polyline with point removed
*/
public WB_Polyline removePoint(final int i) {
final WB_Point3d[] newPoints = new WB_Point3d[n - 1];
for (int j = 0; j < i; j++) {
newPoints[j] = points[j];
}
for (int j = i; j < n - 1; j++) {
newPoints[j] = points[j + 1];
}
return new WB_Polyline(newPoints, n - 1);
}
/**
* Adds point.
*
* @param i index to put point
* @param p point
* @return new WB_Polyline with point addedd
*/
public WB_Polyline addPoint(final int i, final WB_Point3d p) {
final WB_Point3d[] newPoints = new WB_Point3d[n + 1];
for (int j = 0; j < i; j++) {
newPoints[j] = points[j];
}
newPoints[i] = p;
for (int j = i + 1; j < n + 1; j++) {
newPoints[j] = points[j - 1];
}
return new WB_Polyline(newPoints, n + 1);
}
/**
* Refine polygon and smooth with simple Laplacian filter.
*
* @return new refined WB_Polyline
*/
public WB_Polyline smooth() {
final WB_Point3d[] newPoints = new WB_Point3d[2 * n - 1];
newPoints[0] = points[0].get();
for (int i = 1; i < n; i++) {
newPoints[2 * i - 1] = points[i].addAndCopy(points[i - 1]);
newPoints[2 * i - 1].mult(0.5);
newPoints[2 * i] = points[i].get();
}
final WB_Point3d[] sPoints = new WB_Point3d[2 * n - 1];
sPoints[0] = newPoints[0];
for (int i = 1; i < 2 * n - 2; i++) {
sPoints[i] = newPoints[i - 1].addAndCopy(newPoints[i + 1]);
sPoints[i].mult(0.5);
}
sPoints[2 * n - 2] = newPoints[2 * n - 2];
return new WB_Polyline(sPoints, 2 * n - 1);
}
}