Added a consistent classes hierarchy for Euclidean spaces in dimension 1, 2 and 3
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1131123 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
6b3df11f0d
commit
a31933b64a
|
@ -14,16 +14,26 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.commons.math.geometry.partitioning;
|
||||
package org.apache.commons.math.geometry;
|
||||
|
||||
/** This interface represents a generic point to be used in a space partition.
|
||||
* <p>Points are completely virtual entities with no specification at
|
||||
* all, so this class is essentially a marker interface with no
|
||||
* methods. This allows to perform partition in traditional euclidean
|
||||
* n-dimensions spaces, but also in more exotic universes like for
|
||||
* example the surface of the unit sphere.</p>
|
||||
* @version $Revision$ $Date$
|
||||
import java.io.Serializable;
|
||||
|
||||
/** This interface represents a generic space, with affine and vectorial counterparts.
|
||||
* @version $Id:$
|
||||
* @see Vector
|
||||
* @since 3.0
|
||||
*/
|
||||
public interface Point {
|
||||
// nothing here, this is only a marker interface
|
||||
public interface Space extends Serializable {
|
||||
|
||||
/** Get the dimension of the space.
|
||||
* @return dimension of the space
|
||||
*/
|
||||
int getDimension();
|
||||
|
||||
/** Get the n-1 dimension subspace of this space.
|
||||
* @return n-1 dimension sub-space of this space
|
||||
* @see #getDimension()
|
||||
*/
|
||||
Space getSubSpace();
|
||||
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.commons.math.geometry;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.NumberFormat;
|
||||
|
||||
/** This interface represents a generic vector in a vectorial space or a point in an affine space.
|
||||
* @version $Id:$
|
||||
* @see Space
|
||||
* @see Vector
|
||||
* @since 3.0
|
||||
*/
|
||||
public interface Vector<S extends Space> extends Serializable {
|
||||
|
||||
/** Get the space to which the vector belongs.
|
||||
* @return containing space
|
||||
*/
|
||||
Space getSpace();
|
||||
|
||||
/** Get the null vector of the vetorial space or origin point of the affine space.
|
||||
* @return null vector of the vetorial space or origin point of the affine space
|
||||
*/
|
||||
Vector<S> getZero();
|
||||
|
||||
/** Get the L<sub>1</sub> norm for the vector.
|
||||
* @return L<sub>1</sub> norm for the vector
|
||||
*/
|
||||
double getNorm1();
|
||||
|
||||
/** Get the L<sub>2</sub> norm for the vector.
|
||||
* @return Euclidean norm for the vector
|
||||
*/
|
||||
double getNorm();
|
||||
|
||||
/** Get the square of the norm for the vector.
|
||||
* @return square of the Euclidean norm for the vector
|
||||
*/
|
||||
double getNormSq();
|
||||
|
||||
/** Get the L<sub>∞</sub> norm for the vector.
|
||||
* @return L<sub>∞</sub> norm for the vector
|
||||
*/
|
||||
double getNormInf();
|
||||
|
||||
/** Add a vector to the instance.
|
||||
* @param v vector to add
|
||||
* @return a new vector
|
||||
*/
|
||||
Vector<S> add(Vector<S> v);
|
||||
|
||||
/** Add a scaled vector to the instance.
|
||||
* @param factor scale factor to apply to v before adding it
|
||||
* @param v vector to add
|
||||
* @return a new vector
|
||||
*/
|
||||
Vector<S> add(double factor, Vector<S> v);
|
||||
|
||||
/** Subtract a vector from the instance.
|
||||
* @param v vector to subtract
|
||||
* @return a new vector
|
||||
*/
|
||||
Vector<S> subtract(Vector<S> v);
|
||||
|
||||
/** Subtract a scaled vector from the instance.
|
||||
* @param factor scale factor to apply to v before subtracting it
|
||||
* @param v vector to subtract
|
||||
* @return a new vector
|
||||
*/
|
||||
Vector<S> subtract(double factor, Vector<S> v);
|
||||
|
||||
/**
|
||||
* Returns true if any coordinate of this vector is NaN; false otherwise
|
||||
* @return true if any coordinate of this vector is NaN; false otherwise
|
||||
*/
|
||||
boolean isNaN();
|
||||
|
||||
/**
|
||||
* Returns true if any coordinate of this vector is infinite and none are NaN;
|
||||
* false otherwise
|
||||
* @return true if any coordinate of this vector is infinite and none are NaN;
|
||||
* false otherwise
|
||||
*/
|
||||
boolean isInfinite();
|
||||
|
||||
/** Compute the distance between the instance and another vector according to the L<sub>1</sub> norm.
|
||||
* <p>Calling this method is equivalent to calling:
|
||||
* <code>q.subtract(p).getNorm1()</code> except that no intermediate
|
||||
* vector is built</p>
|
||||
* @param v second vector
|
||||
* @return the distance between the instance and p according to the L<sub>1</sub> norm
|
||||
*/
|
||||
double distance1(Vector<S> v);
|
||||
|
||||
/** Compute the distance between the instance and another vector according to the L<sub>2</sub> norm.
|
||||
* <p>Calling this method is equivalent to calling:
|
||||
* <code>q.subtract(p).getNorm()</code> except that no intermediate
|
||||
* vector is built</p>
|
||||
* @param v second vector
|
||||
* @return the distance between the instance and p according to the L<sub>2</sub> norm
|
||||
*/
|
||||
double distance(Vector<S> v);
|
||||
|
||||
/** Compute the distance between the instance and another vector according to the L<sub>∞</sub> norm.
|
||||
* <p>Calling this method is equivalent to calling:
|
||||
* <code>q.subtract(p).getNormInf()</code> except that no intermediate
|
||||
* vector is built</p>
|
||||
* @param v second vector
|
||||
* @return the distance between the instance and p according to the L<sub>∞</sub> norm
|
||||
*/
|
||||
double distanceInf(Vector<S> v);
|
||||
|
||||
/** Compute the square of the distance between the instance and another vector.
|
||||
* <p>Calling this method is equivalent to calling:
|
||||
* <code>q.subtract(p).getNormSq()</code> except that no intermediate
|
||||
* vector is built</p>
|
||||
* @param v second vector
|
||||
* @return the square of the distance between the instance and p
|
||||
*/
|
||||
double distanceSq(Vector<S> v);
|
||||
|
||||
/** Get a string representation of this vector.
|
||||
* @param format the custom format for components.
|
||||
*/
|
||||
public String toString(final NumberFormat format);
|
||||
|
||||
}
|
|
@ -0,0 +1,289 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.commons.math.geometry;
|
||||
|
||||
import java.text.FieldPosition;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParsePosition;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.commons.math.util.CompositeFormat;
|
||||
import org.apache.commons.math.exception.MathParseException;
|
||||
|
||||
/**
|
||||
* Formats a vector in components list format "{x; y; ...}".
|
||||
* <p>The prefix and suffix "{" and "}" and the separator "; " can be replaced by
|
||||
* any user-defined strings. The number format for components can be configured.</p>
|
||||
* <p>White space is ignored at parse time, even if it is in the prefix, suffix
|
||||
* or separator specifications. So even if the default separator does include a space
|
||||
* character that is used at format time, both input string "{1;1;1}" and
|
||||
* " { 1 ; 1 ; 1 } " will be parsed without error and the same vector will be
|
||||
* returned. In the second case, however, the parse position after parsing will be
|
||||
* just after the closing curly brace, i.e. just before the trailing space.</p>
|
||||
*
|
||||
* @version $Id:$
|
||||
* @since 3.0
|
||||
*/
|
||||
public abstract class VectorFormat<S extends Space> {
|
||||
|
||||
/** The default prefix: "{". */
|
||||
public static final String DEFAULT_PREFIX = "{";
|
||||
|
||||
/** The default suffix: "}". */
|
||||
public static final String DEFAULT_SUFFIX = "}";
|
||||
|
||||
/** The default separator: ", ". */
|
||||
public static final String DEFAULT_SEPARATOR = "; ";
|
||||
|
||||
/** Prefix. */
|
||||
private final String prefix;
|
||||
|
||||
/** Suffix. */
|
||||
private final String suffix;
|
||||
|
||||
/** Separator. */
|
||||
private final String separator;
|
||||
|
||||
/** Trimmed prefix. */
|
||||
private final String trimmedPrefix;
|
||||
|
||||
/** Trimmed suffix. */
|
||||
private final String trimmedSuffix;
|
||||
|
||||
/** Trimmed separator. */
|
||||
private final String trimmedSeparator;
|
||||
|
||||
/** The format used for components. */
|
||||
private final NumberFormat format;
|
||||
|
||||
/**
|
||||
* Create an instance with default settings.
|
||||
* <p>The instance uses the default prefix, suffix and separator:
|
||||
* "{", "}", and "; " and the default number format for components.</p>
|
||||
*/
|
||||
protected VectorFormat() {
|
||||
this(DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_SEPARATOR,
|
||||
CompositeFormat.getDefaultNumberFormat());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance with a custom number format for components.
|
||||
* @param format the custom format for components.
|
||||
*/
|
||||
protected VectorFormat(final NumberFormat format) {
|
||||
this(DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_SEPARATOR, format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance with custom prefix, suffix and separator.
|
||||
* @param prefix prefix to use instead of the default "{"
|
||||
* @param suffix suffix to use instead of the default "}"
|
||||
* @param separator separator to use instead of the default "; "
|
||||
*/
|
||||
protected VectorFormat(final String prefix, final String suffix,
|
||||
final String separator) {
|
||||
this(prefix, suffix, separator, CompositeFormat.getDefaultNumberFormat());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance with custom prefix, suffix, separator and format
|
||||
* for components.
|
||||
* @param prefix prefix to use instead of the default "{"
|
||||
* @param suffix suffix to use instead of the default "}"
|
||||
* @param separator separator to use instead of the default "; "
|
||||
* @param format the custom format for components.
|
||||
*/
|
||||
protected VectorFormat(final String prefix, final String suffix,
|
||||
final String separator, final NumberFormat format) {
|
||||
this.prefix = prefix;
|
||||
this.suffix = suffix;
|
||||
this.separator = separator;
|
||||
trimmedPrefix = prefix.trim();
|
||||
trimmedSuffix = suffix.trim();
|
||||
trimmedSeparator = separator.trim();
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the set of locales for which point/vector formats are available.
|
||||
* <p>This is the same set as the {@link NumberFormat} set.</p>
|
||||
* @return available point/vector format locales.
|
||||
*/
|
||||
public static Locale[] getAvailableLocales() {
|
||||
return NumberFormat.getAvailableLocales();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the format prefix.
|
||||
* @return format prefix.
|
||||
*/
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the format suffix.
|
||||
* @return format suffix.
|
||||
*/
|
||||
public String getSuffix() {
|
||||
return suffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the format separator between components.
|
||||
* @return format separator.
|
||||
*/
|
||||
public String getSeparator() {
|
||||
return separator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the components format.
|
||||
* @return components format.
|
||||
*/
|
||||
public NumberFormat getFormat() {
|
||||
return format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a {@link Vector} object to produce a string.
|
||||
* @param vector the object to format.
|
||||
* @return a formatted string.
|
||||
*/
|
||||
public String format(Vector<S> vector) {
|
||||
return format(vector, new StringBuffer(), new FieldPosition(0)).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a {@link Vector} object to produce a string.
|
||||
* @param vector the object to format.
|
||||
* @param toAppendTo where the text is to be appended
|
||||
* @param pos On input: an alignment field, if desired. On output: the
|
||||
* offsets of the alignment field
|
||||
* @return the value passed in as toAppendTo.
|
||||
*/
|
||||
public abstract StringBuffer format(Vector<S> vector,
|
||||
StringBuffer toAppendTo, FieldPosition pos);
|
||||
|
||||
/**
|
||||
* Formats the coordinates of a {@link Vector} to produce a string.
|
||||
* @param toAppendTo where the text is to be appended
|
||||
* @param pos On input: an alignment field, if desired. On output: the
|
||||
* offsets of the alignment field
|
||||
* @param coordinates coordinates of the object to format.
|
||||
* @return the value passed in as toAppendTo.
|
||||
*/
|
||||
protected StringBuffer format(StringBuffer toAppendTo, FieldPosition pos,
|
||||
double ... coordinates) {
|
||||
|
||||
pos.setBeginIndex(0);
|
||||
pos.setEndIndex(0);
|
||||
|
||||
// format prefix
|
||||
toAppendTo.append(prefix);
|
||||
|
||||
// format components
|
||||
for (int i = 0; i < coordinates.length; ++i) {
|
||||
if (i > 0) {
|
||||
toAppendTo.append(separator);
|
||||
}
|
||||
CompositeFormat.formatDouble(coordinates[i], format, toAppendTo, pos);
|
||||
}
|
||||
|
||||
// format suffix
|
||||
toAppendTo.append(suffix);
|
||||
|
||||
return toAppendTo;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a string to produce a {@link Vector} object.
|
||||
* @param source the string to parse
|
||||
* @return the parsed {@link Vector} object.
|
||||
* @throws MathParseException if the beginning of the specified string
|
||||
* cannot be parsed.
|
||||
*/
|
||||
public abstract Vector<S> parse(String source);
|
||||
|
||||
/**
|
||||
* Parses a string to produce a {@link Vector} object.
|
||||
* @param source the string to parse
|
||||
* @param pos input/ouput parsing parameter.
|
||||
* @return the parsed {@link Vector} object.
|
||||
*/
|
||||
public abstract Vector<S> parse(String source, ParsePosition pos);
|
||||
|
||||
/**
|
||||
* Parses a string to produce an array of coordinates.
|
||||
* @param dimension dimension of the space
|
||||
* @param source the string to parse
|
||||
* @param pos input/ouput parsing parameter.
|
||||
* @return coordinates array.
|
||||
*/
|
||||
protected double[] parseCoordinates(int dimension, String source, ParsePosition pos) {
|
||||
|
||||
int initialIndex = pos.getIndex();
|
||||
double[] coordinates = new double[dimension];
|
||||
|
||||
// parse prefix
|
||||
CompositeFormat.parseAndIgnoreWhitespace(source, pos);
|
||||
if (!CompositeFormat.parseFixedstring(source, trimmedPrefix, pos)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (int i = 0; i < dimension; ++i) {
|
||||
|
||||
// skip whitespace
|
||||
CompositeFormat.parseAndIgnoreWhitespace(source, pos);
|
||||
|
||||
// parse separator
|
||||
if (i > 0) {
|
||||
if (!CompositeFormat.parseFixedstring(source, trimmedSeparator, pos)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// skip whitespace
|
||||
CompositeFormat.parseAndIgnoreWhitespace(source, pos);
|
||||
|
||||
// parse coordinate
|
||||
Number c = CompositeFormat.parseNumber(source, format, pos);
|
||||
if (c == null) {
|
||||
// invalid coordinate
|
||||
// set index back to initial, error index should already be set
|
||||
pos.setIndex(initialIndex);
|
||||
return null;
|
||||
}
|
||||
|
||||
// store coordinate
|
||||
coordinates[i] = c.doubleValue();
|
||||
|
||||
}
|
||||
|
||||
// parse suffix
|
||||
CompositeFormat.parseAndIgnoreWhitespace(source, pos);
|
||||
if (!CompositeFormat.parseFixedstring(source, trimmedSuffix, pos)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return coordinates;
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.commons.math.geometry.euclidean.oned;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.apache.commons.math.exception.MathUnsupportedOperationException;
|
||||
import org.apache.commons.math.exception.util.LocalizedFormats;
|
||||
import org.apache.commons.math.geometry.Space;
|
||||
|
||||
/**
|
||||
* This class implements a one-dimensional space.
|
||||
* @version $Id:$
|
||||
* @since 3.0
|
||||
*/
|
||||
public class Euclidean1D implements Serializable, Space {
|
||||
|
||||
/** Serializable version identifier. */
|
||||
private static final long serialVersionUID = -1178039568877797126L;
|
||||
|
||||
/** Private constructor for the singleton.
|
||||
*/
|
||||
private Euclidean1D() {
|
||||
}
|
||||
|
||||
/** Get the unique instance.
|
||||
* @return the unique instance
|
||||
*/
|
||||
public static Euclidean1D getInstance() {
|
||||
return LazyHolder.INSTANCE;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public int getDimension() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** {@inheritDoc}
|
||||
* <p>
|
||||
* As the 1-dimension Euclidean space does not have proper sub-spaces,
|
||||
* this method always throws a {@link MathUnsupportedOperationException}
|
||||
* </p>
|
||||
* @return nothing
|
||||
* @throws MathUnsupportedOperationException in all cases
|
||||
*/
|
||||
public Space getSubSpace() throws MathUnsupportedOperationException {
|
||||
throw new MathUnsupportedOperationException(LocalizedFormats.NOT_SUPPORTED_IN_DIMENSION_N, 1);
|
||||
}
|
||||
|
||||
// CHECKSTYLE: stop HideUtilityClassConstructor
|
||||
/** Holder for the instance.
|
||||
* <p>We use here the Initialization On Demand Holder Idiom.</p>
|
||||
*/
|
||||
private static class LazyHolder {
|
||||
/** Cached field instance. */
|
||||
private static final Euclidean1D INSTANCE = new Euclidean1D();
|
||||
}
|
||||
// CHECKSTYLE: resume HideUtilityClassConstructor
|
||||
|
||||
/** Handle deserialization of the singleton.
|
||||
* @return the singleton instance
|
||||
*/
|
||||
private Object readResolve() {
|
||||
// return the singleton instance
|
||||
return LazyHolder.INSTANCE;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.commons.math.geometry.euclidean.oned;
|
||||
|
||||
import org.apache.commons.math.geometry.partitioning.Point;
|
||||
|
||||
/** This class represents a 1D point.
|
||||
* <p>Instances of this class are guaranteed to be immutable.</p>
|
||||
* @version $Revision$ $Date$
|
||||
*/
|
||||
public class Point1D implements Point {
|
||||
|
||||
/** Point at 0.0 abscissa. */
|
||||
public static final Point1D ZERO = new Point1D(0.0);
|
||||
|
||||
/** Point at 1.0 abscissa. */
|
||||
public static final Point1D ONE = new Point1D(1.0);
|
||||
|
||||
/** Point at undefined (NaN) abscissa. */
|
||||
public static final Point1D UNDEFINED = new Point1D(Double.NaN);
|
||||
|
||||
/** Abscissa of the point. */
|
||||
private double x;
|
||||
|
||||
/** Simple constructor.
|
||||
* @param x abscissa of the point
|
||||
*/
|
||||
public Point1D(final double x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
/** Get the abscissa of the point.
|
||||
* @return abscissa of the point
|
||||
*/
|
||||
public double getAbscissa() {
|
||||
return x;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,322 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.commons.math.geometry.euclidean.oned;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
|
||||
import org.apache.commons.math.geometry.Vector;
|
||||
import org.apache.commons.math.geometry.Space;
|
||||
import org.apache.commons.math.util.FastMath;
|
||||
import org.apache.commons.math.util.MathUtils;
|
||||
|
||||
/** This class represents a 1D vector.
|
||||
* <p>Instances of this class are guaranteed to be immutable.</p>
|
||||
* @version $Id:$
|
||||
* @since 3.0
|
||||
*/
|
||||
public class Vector1D implements Vector<Euclidean1D> {
|
||||
|
||||
/** Origin (coordinates: 0). */
|
||||
public static final Vector1D ZERO = new Vector1D(0.0);
|
||||
|
||||
/** Unit (coordinates: 1). */
|
||||
public static final Vector1D ONE = new Vector1D(1.0);
|
||||
|
||||
// CHECKSTYLE: stop ConstantName
|
||||
/** A vector with all coordinates set to NaN. */
|
||||
public static final Vector1D NaN = new Vector1D(Double.NaN);
|
||||
// CHECKSTYLE: resume ConstantName
|
||||
|
||||
/** A vector with all coordinates set to positive infinity. */
|
||||
public static final Vector1D POSITIVE_INFINITY =
|
||||
new Vector1D(Double.POSITIVE_INFINITY);
|
||||
|
||||
/** A vector with all coordinates set to negative infinity. */
|
||||
public static final Vector1D NEGATIVE_INFINITY =
|
||||
new Vector1D(Double.NEGATIVE_INFINITY);
|
||||
|
||||
/** Serializable UID. */
|
||||
private static final long serialVersionUID = 7556674948671647925L;
|
||||
|
||||
/** Abscissa. */
|
||||
private final double x;
|
||||
|
||||
/** Simple constructor.
|
||||
* Build a vector from its coordinates
|
||||
* @param x abscissa
|
||||
* @see #getX()
|
||||
*/
|
||||
public Vector1D(double x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
/** Multiplicative constructor
|
||||
* Build a vector from another one and a scale factor.
|
||||
* The vector built will be a * u
|
||||
* @param a scale factor
|
||||
* @param u base (unscaled) vector
|
||||
*/
|
||||
public Vector1D(double a, Vector1D u) {
|
||||
this.x = a * u.x;
|
||||
}
|
||||
|
||||
/** Linear constructor
|
||||
* Build a vector from two other ones and corresponding scale factors.
|
||||
* The vector built will be a1 * u1 + a2 * u2
|
||||
* @param a1 first scale factor
|
||||
* @param u1 first base (unscaled) vector
|
||||
* @param a2 second scale factor
|
||||
* @param u2 second base (unscaled) vector
|
||||
*/
|
||||
public Vector1D(double a1, Vector1D u1, double a2, Vector1D u2) {
|
||||
this.x = a1 * u1.x + a2 * u2.x;
|
||||
}
|
||||
|
||||
/** Linear constructor
|
||||
* Build a vector from three other ones and corresponding scale factors.
|
||||
* The vector built will be a1 * u1 + a2 * u2 + a3 * u3
|
||||
* @param a1 first scale factor
|
||||
* @param u1 first base (unscaled) vector
|
||||
* @param a2 second scale factor
|
||||
* @param u2 second base (unscaled) vector
|
||||
* @param a3 third scale factor
|
||||
* @param u3 third base (unscaled) vector
|
||||
*/
|
||||
public Vector1D(double a1, Vector1D u1, double a2, Vector1D u2,
|
||||
double a3, Vector1D u3) {
|
||||
this.x = a1 * u1.x + a2 * u2.x + a3 * u3.x;
|
||||
}
|
||||
|
||||
/** Linear constructor
|
||||
* Build a vector from four other ones and corresponding scale factors.
|
||||
* The vector built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4
|
||||
* @param a1 first scale factor
|
||||
* @param u1 first base (unscaled) vector
|
||||
* @param a2 second scale factor
|
||||
* @param u2 second base (unscaled) vector
|
||||
* @param a3 third scale factor
|
||||
* @param u3 third base (unscaled) vector
|
||||
* @param a4 fourth scale factor
|
||||
* @param u4 fourth base (unscaled) vector
|
||||
*/
|
||||
public Vector1D(double a1, Vector1D u1, double a2, Vector1D u2,
|
||||
double a3, Vector1D u3, double a4, Vector1D u4) {
|
||||
this.x = a1 * u1.x + a2 * u2.x + a3 * u3.x + a4 * u4.x;
|
||||
}
|
||||
|
||||
/** Get the abscissa of the vector.
|
||||
* @return abscissa of the vector
|
||||
* @see #Vector1D(double)
|
||||
*/
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public Space getSpace() {
|
||||
return Euclidean1D.getInstance();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public Vector1D getZero() {
|
||||
return ZERO;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double getNorm1() {
|
||||
return FastMath.abs(x);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double getNorm() {
|
||||
return FastMath.abs(x);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double getNormSq() {
|
||||
return x * x;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double getNormInf() {
|
||||
return FastMath.abs(x);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public Vector1D add(Vector<Euclidean1D> v) {
|
||||
Vector1D v1 = (Vector1D) v;
|
||||
return new Vector1D(x + v1.getX());
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public Vector1D add(double factor, Vector<Euclidean1D> v) {
|
||||
Vector1D v1 = (Vector1D) v;
|
||||
return new Vector1D(x + factor * v1.getX());
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public Vector1D subtract(Vector<Euclidean1D> p) {
|
||||
Vector1D p3 = (Vector1D) p;
|
||||
return new Vector1D(x - p3.x);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public Vector1D subtract(double factor, Vector<Euclidean1D> v) {
|
||||
Vector1D v1 = (Vector1D) v;
|
||||
return new Vector1D(x - factor * v1.getX());
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public boolean isNaN() {
|
||||
return Double.isNaN(x);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public boolean isInfinite() {
|
||||
return !isNaN() && Double.isInfinite(x);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double distance1(Vector<Euclidean1D> p) {
|
||||
Vector1D p3 = (Vector1D) p;
|
||||
final double dx = FastMath.abs(p3.x - x);
|
||||
return dx;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double distance(Vector<Euclidean1D> p) {
|
||||
Vector1D p3 = (Vector1D) p;
|
||||
final double dx = p3.x - x;
|
||||
return FastMath.abs(dx);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double distanceInf(Vector<Euclidean1D> p) {
|
||||
Vector1D p3 = (Vector1D) p;
|
||||
final double dx = FastMath.abs(p3.x - x);
|
||||
return dx;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double distanceSq(Vector<Euclidean1D> p) {
|
||||
Vector1D p3 = (Vector1D) p;
|
||||
final double dx = p3.x - x;
|
||||
return dx * dx;
|
||||
}
|
||||
|
||||
/** Compute the distance between two vectors according to the L<sub>2</sub> norm.
|
||||
* <p>Calling this method is equivalent to calling:
|
||||
* <code>p1.subtract(p2).getNorm()</code> except that no intermediate
|
||||
* vector is built</p>
|
||||
* @param p1 first vector
|
||||
* @param p2 second vector
|
||||
* @return the distance between p1 and p2 according to the L<sub>2</sub> norm
|
||||
*/
|
||||
public static double distance(Vector1D p1, Vector1D p2) {
|
||||
return p1.distance(p2);
|
||||
}
|
||||
|
||||
/** Compute the distance between two vectors according to the L<sub>∞</sub> norm.
|
||||
* <p>Calling this method is equivalent to calling:
|
||||
* <code>p1.subtract(p2).getNormInf()</code> except that no intermediate
|
||||
* vector is built</p>
|
||||
* @param p1 first vector
|
||||
* @param p2 second vector
|
||||
* @return the distance between p1 and p2 according to the L<sub>∞</sub> norm
|
||||
*/
|
||||
public static double distanceInf(Vector1D p1, Vector1D p2) {
|
||||
return p1.distanceInf(p2);
|
||||
}
|
||||
|
||||
/** Compute the square of the distance between two vectors.
|
||||
* <p>Calling this method is equivalent to calling:
|
||||
* <code>p1.subtract(p2).getNormSq()</code> except that no intermediate
|
||||
* vector is built</p>
|
||||
* @param p1 first vector
|
||||
* @param p2 second vector
|
||||
* @return the square of the distance between p1 and p2
|
||||
*/
|
||||
public static double distanceSq(Vector1D p1, Vector1D p2) {
|
||||
return p1.distanceSq(p2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for the equality of two 1D vectors.
|
||||
* <p>
|
||||
* If all coordinates of two 1D vectors are exactly the same, and none are
|
||||
* <code>Double.NaN</code>, the two 1D vectors are considered to be equal.
|
||||
* </p>
|
||||
* <p>
|
||||
* <code>NaN</code> coordinates are considered to affect globally the vector
|
||||
* and be equals to each other - i.e, if either (or all) coordinates of the
|
||||
* 1D vector are equal to <code>Double.NaN</code>, the 1D vector is equal to
|
||||
* {@link #NaN}.
|
||||
* </p>
|
||||
*
|
||||
* @param other Object to test for equality to this
|
||||
* @return true if two 1D vector objects are equal, false if
|
||||
* object is null, not an instance of Vector1D, or
|
||||
* not equal to this Vector1D instance
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (other instanceof Vector1D) {
|
||||
final Vector1D rhs = (Vector1D)other;
|
||||
if (rhs.isNaN()) {
|
||||
return this.isNaN();
|
||||
}
|
||||
|
||||
return x == rhs.x;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a hashCode for the 1D vector.
|
||||
* <p>
|
||||
* All NaN values have the same hash code.</p>
|
||||
*
|
||||
* @return a hash code value for this object
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if (isNaN()) {
|
||||
return 7785;
|
||||
}
|
||||
return 997 * MathUtils.hash(x);
|
||||
}
|
||||
|
||||
/** Get a string representation of this vector.
|
||||
* @return a string representation of this vector
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return Vector1DFormat.getInstance().format(this);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public String toString(final NumberFormat format) {
|
||||
return new Vector1DFormat(format).format(this);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.commons.math.geometry.euclidean.oned;
|
||||
|
||||
import java.text.FieldPosition;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParsePosition;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.commons.math.exception.MathParseException;
|
||||
import org.apache.commons.math.geometry.Vector;
|
||||
import org.apache.commons.math.geometry.VectorFormat;
|
||||
import org.apache.commons.math.util.CompositeFormat;
|
||||
|
||||
/**
|
||||
* Formats a 1D vector in components list format "{x}".
|
||||
* <p>The prefix and suffix "{" and "}" can be replaced by
|
||||
* any user-defined strings. The number format for components can be configured.</p>
|
||||
* <p>White space is ignored at parse time, even if it is in the prefix, suffix
|
||||
* or separator specifications. So even if the default separator does include a space
|
||||
* character that is used at format time, both input string "{1}" and
|
||||
* " { 1 } " will be parsed without error and the same vector will be
|
||||
* returned. In the second case, however, the parse position after parsing will be
|
||||
* just after the closing curly brace, i.e. just before the trailing space.</p>
|
||||
*
|
||||
* @version $Id:$
|
||||
* @since 3.0
|
||||
*/
|
||||
public class Vector1DFormat extends VectorFormat<Euclidean1D> {
|
||||
|
||||
/**
|
||||
* Create an instance with default settings.
|
||||
* <p>The instance uses the default prefix, suffix and separator:
|
||||
* "{", "}", and "; " and the default number format for components.</p>
|
||||
*/
|
||||
public Vector1DFormat() {
|
||||
super(DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_SEPARATOR,
|
||||
CompositeFormat.getDefaultNumberFormat());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance with a custom number format for components.
|
||||
* @param format the custom format for components.
|
||||
*/
|
||||
public Vector1DFormat(final NumberFormat format) {
|
||||
super(DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_SEPARATOR, format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance with custom prefix, suffix and separator.
|
||||
* @param prefix prefix to use instead of the default "{"
|
||||
* @param suffix suffix to use instead of the default "}"
|
||||
*/
|
||||
public Vector1DFormat(final String prefix, final String suffix) {
|
||||
super(prefix, suffix, DEFAULT_SEPARATOR, CompositeFormat.getDefaultNumberFormat());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance with custom prefix, suffix, separator and format
|
||||
* for components.
|
||||
* @param prefix prefix to use instead of the default "{"
|
||||
* @param suffix suffix to use instead of the default "}"
|
||||
* @param format the custom format for components.
|
||||
*/
|
||||
public Vector1DFormat(final String prefix, final String suffix,
|
||||
final NumberFormat format) {
|
||||
super(prefix, suffix, DEFAULT_SEPARATOR, format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default 1D vector format for the current locale.
|
||||
* @return the default 1D vector format.
|
||||
*/
|
||||
public static Vector1DFormat getInstance() {
|
||||
return getInstance(Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default 1D vector format for the given locale.
|
||||
* @param locale the specific locale used by the format.
|
||||
* @return the 1D vector format specific to the given locale.
|
||||
*/
|
||||
public static Vector1DFormat getInstance(final Locale locale) {
|
||||
return new Vector1DFormat(CompositeFormat.getDefaultNumberFormat(locale));
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public StringBuffer format(final Vector<Euclidean1D> vector, final StringBuffer toAppendTo,
|
||||
final FieldPosition pos) {
|
||||
final Vector1D p1 = (Vector1D) vector;
|
||||
return format(toAppendTo, pos, p1.getX());
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public Vector1D parse(final String source) {
|
||||
ParsePosition parsePosition = new ParsePosition(0);
|
||||
Vector1D result = parse(source, parsePosition);
|
||||
if (parsePosition.getIndex() == 0) {
|
||||
throw new MathParseException(source,
|
||||
parsePosition.getErrorIndex(),
|
||||
Vector1D.class);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public Vector1D parse(final String source, final ParsePosition pos) {
|
||||
final double[] coordinates = parseCoordinates(1, source, pos);
|
||||
if (coordinates == null) {
|
||||
return null;
|
||||
}
|
||||
return new Vector1D(coordinates[0]);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.commons.math.geometry.euclidean.threed;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.apache.commons.math.geometry.Space;
|
||||
import org.apache.commons.math.geometry.euclidean.twod.Euclidean2D;
|
||||
|
||||
/**
|
||||
* This class implements a three-dimensional space.
|
||||
* @version $Id:$
|
||||
* @since 3.0
|
||||
*/
|
||||
public class Euclidean3D implements Serializable, Space {
|
||||
|
||||
/** Serializable version identifier. */
|
||||
private static final long serialVersionUID = 6249091865814886817L;
|
||||
|
||||
/** Private constructor for the singleton.
|
||||
*/
|
||||
private Euclidean3D() {
|
||||
}
|
||||
|
||||
/** Get the unique instance.
|
||||
* @return the unique instance
|
||||
*/
|
||||
public static Euclidean3D getInstance() {
|
||||
return LazyHolder.INSTANCE;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public int getDimension() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public Euclidean2D getSubSpace() {
|
||||
return Euclidean2D.getInstance();
|
||||
}
|
||||
|
||||
// CHECKSTYLE: stop HideUtilityClassConstructor
|
||||
/** Holder for the instance.
|
||||
* <p>We use here the Initialization On Demand Holder Idiom.</p>
|
||||
*/
|
||||
private static class LazyHolder {
|
||||
/** Cached field instance. */
|
||||
private static final Euclidean3D INSTANCE = new Euclidean3D();
|
||||
}
|
||||
// CHECKSTYLE: resume HideUtilityClassConstructor
|
||||
|
||||
/** Handle deserialization of the singleton.
|
||||
* @return the singleton instance
|
||||
*/
|
||||
private Object readResolve() {
|
||||
// return the singleton instance
|
||||
return LazyHolder.INSTANCE;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.commons.math.geometry.euclidean.threed;
|
||||
|
||||
import org.apache.commons.math.geometry.partitioning.Point;
|
||||
|
||||
/** This class represents a 3D point.
|
||||
* <p>Instances of this class are guaranteed to be immutable.</p>
|
||||
* @version $Revision$ $Date$
|
||||
*/
|
||||
public class Point3D extends Vector3D implements Point {
|
||||
|
||||
/** Point at undefined (NaN) coordinates. */
|
||||
public static final Point3D UNDEFINED = new Point3D(Double.NaN, Double.NaN, Double.NaN);
|
||||
|
||||
/** Serializable UID. */
|
||||
private static final long serialVersionUID = 9128130934224884451L;
|
||||
|
||||
/** Simple constructor.
|
||||
* Build a vector from its coordinates
|
||||
* @param x abscissa
|
||||
* @param y ordinate
|
||||
* @param z height
|
||||
* @see #getX()
|
||||
* @see #getY()
|
||||
* @see #getZ()
|
||||
*/
|
||||
public Point3D(final double x, final double y, final double z) {
|
||||
super(x, y, z);
|
||||
}
|
||||
|
||||
/** Simple constructor.
|
||||
* Build a vector from its azimuthal coordinates
|
||||
* @param alpha azimuth (α) around Z
|
||||
* (0 is +X, π/2 is +Y, π is -X and 3π/2 is -Y)
|
||||
* @param delta elevation (δ) above (XY) plane, from -π/2 to +π/2
|
||||
* @see #getAlpha()
|
||||
* @see #getDelta()
|
||||
*/
|
||||
public Point3D(final double alpha, final double delta) {
|
||||
super(alpha, delta);
|
||||
}
|
||||
|
||||
/** Multiplicative constructor
|
||||
* Build a vector from another one and a scale factor.
|
||||
* The vector built will be a * u
|
||||
* @param a scale factor
|
||||
* @param u base (unscaled) vector
|
||||
*/
|
||||
public Point3D(final double a, final Vector3D u) {
|
||||
super(a, u);
|
||||
}
|
||||
|
||||
/** Linear constructor
|
||||
* Build a vector from two other ones and corresponding scale factors.
|
||||
* The vector built will be a1 * u1 + a2 * u2
|
||||
* @param a1 first scale factor
|
||||
* @param u1 first base (unscaled) vector
|
||||
* @param a2 second scale factor
|
||||
* @param u2 second base (unscaled) vector
|
||||
*/
|
||||
public Point3D(final double a1, final Vector3D u1, final double a2, final Vector3D u2) {
|
||||
super(a1, u1, a2, u2);
|
||||
}
|
||||
|
||||
/** Linear constructor
|
||||
* Build a vector from three other ones and corresponding scale factors.
|
||||
* The vector built will be a1 * u1 + a2 * u2 + a3 * u3
|
||||
* @param a1 first scale factor
|
||||
* @param u1 first base (unscaled) vector
|
||||
* @param a2 second scale factor
|
||||
* @param u2 second base (unscaled) vector
|
||||
* @param a3 third scale factor
|
||||
* @param u3 third base (unscaled) vector
|
||||
*/
|
||||
public Point3D(final double a1, final Vector3D u1, final double a2, final Vector3D u2,
|
||||
final double a3, final Vector3D u3) {
|
||||
super(a1, u1, a2, u2, a3, u3);
|
||||
}
|
||||
|
||||
/** Linear constructor
|
||||
* Build a vector from four other ones and corresponding scale factors.
|
||||
* The vector built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4
|
||||
* @param a1 first scale factor
|
||||
* @param u1 first base (unscaled) vector
|
||||
* @param a2 second scale factor
|
||||
* @param u2 second base (unscaled) vector
|
||||
* @param a3 third scale factor
|
||||
* @param u3 third base (unscaled) vector
|
||||
* @param a4 fourth scale factor
|
||||
* @param u4 fourth base (unscaled) vector
|
||||
*/
|
||||
public Point3D(final double a1, final Vector3D u1, final double a2, final Vector3D u2,
|
||||
final double a3, final Vector3D u3, final double a4, final Vector3D u4) {
|
||||
super(a1, u1, a2, u2, a3, u3, a4, u4);
|
||||
}
|
||||
|
||||
}
|
|
@ -18,19 +18,26 @@
|
|||
package org.apache.commons.math.geometry.euclidean.threed;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.text.NumberFormat;
|
||||
|
||||
import org.apache.commons.math.exception.MathArithmeticException;
|
||||
import org.apache.commons.math.exception.util.LocalizedFormats;
|
||||
import org.apache.commons.math.util.MathUtils;
|
||||
import org.apache.commons.math.geometry.Vector;
|
||||
import org.apache.commons.math.geometry.Space;
|
||||
import org.apache.commons.math.util.FastMath;
|
||||
import org.apache.commons.math.util.MathUtils;
|
||||
|
||||
/**
|
||||
* This class implements vectors in a three-dimensional space.
|
||||
* <p>Instance of this class are guaranteed to be immutable.</p>
|
||||
* @version $Revision$ $Date$
|
||||
* @version $Id$
|
||||
* @since 1.2
|
||||
*/
|
||||
public class Vector3D implements Serializable {
|
||||
public class Vector3D implements Serializable, Vector<Euclidean3D> {
|
||||
|
||||
/** Serializable version id. */
|
||||
private static final long serialVersionUID = 1313493323784566947L;
|
||||
|
||||
/** Null vector (coordinates: 0, 0, 0). */
|
||||
public static final Vector3D ZERO = new Vector3D(0, 0, 0);
|
||||
|
||||
|
@ -65,12 +72,7 @@ public class Vector3D implements Serializable {
|
|||
public static final Vector3D NEGATIVE_INFINITY =
|
||||
new Vector3D(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY);
|
||||
|
||||
/** Default format. */
|
||||
private static final Vector3DFormat DEFAULT_FORMAT =
|
||||
Vector3DFormat.getInstance();
|
||||
|
||||
/** Serializable version identifier. */
|
||||
private static final long serialVersionUID = 5133268763396045979L;
|
||||
|
||||
/** Abscissa. */
|
||||
private final double x;
|
||||
|
@ -197,30 +199,32 @@ public class Vector3D implements Serializable {
|
|||
return z;
|
||||
}
|
||||
|
||||
/** Get the L<sub>1</sub> norm for the vector.
|
||||
* @return L<sub>1</sub> norm for the vector
|
||||
*/
|
||||
/** {@inheritDoc} */
|
||||
public Space getSpace() {
|
||||
return Euclidean3D.getInstance();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public Vector3D getZero() {
|
||||
return ZERO;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double getNorm1() {
|
||||
return FastMath.abs(x) + FastMath.abs(y) + FastMath.abs(z);
|
||||
}
|
||||
|
||||
/** Get the L<sub>2</sub> norm for the vector.
|
||||
* @return euclidean norm for the vector
|
||||
*/
|
||||
/** {@inheritDoc} */
|
||||
public double getNorm() {
|
||||
return FastMath.sqrt (x * x + y * y + z * z);
|
||||
}
|
||||
|
||||
/** Get the square of the norm for the vector.
|
||||
* @return square of the euclidean norm for the vector
|
||||
*/
|
||||
/** {@inheritDoc} */
|
||||
public double getNormSq() {
|
||||
return x * x + y * y + z * z;
|
||||
}
|
||||
|
||||
/** Get the L<sub>∞</sub> norm for the vector.
|
||||
* @return L<sub>∞</sub> norm for the vector
|
||||
*/
|
||||
/** {@inheritDoc} */
|
||||
public double getNormInf() {
|
||||
return FastMath.max(FastMath.max(FastMath.abs(x), FastMath.abs(y)), FastMath.abs(z));
|
||||
}
|
||||
|
@ -241,44 +245,31 @@ public class Vector3D implements Serializable {
|
|||
return FastMath.asin(z / getNorm());
|
||||
}
|
||||
|
||||
/** Add a vector to the instance.
|
||||
* @param v vector to add
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector3D add(Vector3D v) {
|
||||
return new Vector3D(x + v.x, y + v.y, z + v.z);
|
||||
/** {@inheritDoc} */
|
||||
public Vector3D add(final Vector<Euclidean3D> v) {
|
||||
final Vector3D v3 = (Vector3D) v;
|
||||
return new Vector3D(x + v3.x, y + v3.y, z + v3.z);
|
||||
}
|
||||
|
||||
/** Add a scaled vector to the instance.
|
||||
* @param factor scale factor to apply to v before adding it
|
||||
* @param v vector to add
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector3D add(double factor, Vector3D v) {
|
||||
return new Vector3D(x + factor * v.x, y + factor * v.y, z + factor * v.z);
|
||||
/** {@inheritDoc} */
|
||||
public Vector3D add(double factor, final Vector<Euclidean3D> v) {
|
||||
final Vector3D v3 = (Vector3D) v;
|
||||
return new Vector3D(x + factor * v3.x, y + factor * v3.y, z + factor * v3.z);
|
||||
}
|
||||
|
||||
/** Subtract a vector from the instance.
|
||||
* @param v vector to subtract
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector3D subtract(Vector3D v) {
|
||||
return new Vector3D(x - v.x, y - v.y, z - v.z);
|
||||
/** {@inheritDoc} */
|
||||
public Vector3D subtract(final Vector<Euclidean3D> v) {
|
||||
final Vector3D v3 = (Vector3D) v;
|
||||
return new Vector3D(x - v3.x, y - v3.y, z - v3.z);
|
||||
}
|
||||
|
||||
/** Subtract a scaled vector from the instance.
|
||||
* @param factor scale factor to apply to v before subtracting it
|
||||
* @param v vector to subtract
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector3D subtract(double factor, Vector3D v) {
|
||||
return new Vector3D(x - factor * v.x, y - factor * v.y, z - factor * v.z);
|
||||
/** {@inheritDoc} */
|
||||
public Vector3D subtract(final double factor, final Vector<Euclidean3D> v) {
|
||||
final Vector3D v3 = (Vector3D) v;
|
||||
return new Vector3D(x - factor * v3.x, y - factor * v3.y, z - factor * v3.z);
|
||||
}
|
||||
|
||||
/** Get a normalized vector aligned with the instance.
|
||||
* @return a new normalized vector
|
||||
* @exception ArithmeticException if the norm is zero
|
||||
*/
|
||||
/** {@inheritDoc} */
|
||||
public Vector3D normalize() {
|
||||
double s = getNorm();
|
||||
if (s == 0) {
|
||||
|
@ -300,7 +291,7 @@ public class Vector3D implements Serializable {
|
|||
* Vector3D j = Vector3D.crossProduct(k, i);
|
||||
* </code></pre></p>
|
||||
* @return a new normalized vector orthogonal to the instance
|
||||
* @exception ArithmeticException if the norm of the instance is null
|
||||
* @exception MathArithmeticException if the norm of the instance is null
|
||||
*/
|
||||
public Vector3D orthogonal() {
|
||||
|
||||
|
@ -330,7 +321,7 @@ public class Vector3D implements Serializable {
|
|||
* @param v1 first vector
|
||||
* @param v2 second vector
|
||||
* @return angular separation between v1 and v2
|
||||
* @exception ArithmeticException if either vector has a null norm
|
||||
* @exception MathArithmeticException if either vector has a null norm
|
||||
*/
|
||||
public static double angle(Vector3D v1, Vector3D v2) {
|
||||
|
||||
|
@ -355,35 +346,22 @@ public class Vector3D implements Serializable {
|
|||
|
||||
}
|
||||
|
||||
/** Get the opposite of the instance.
|
||||
* @return a new vector which is opposite to the instance
|
||||
*/
|
||||
/** {@inheritDoc} */
|
||||
public Vector3D negate() {
|
||||
return new Vector3D(-x, -y, -z);
|
||||
}
|
||||
|
||||
/** Multiply the instance by a scalar
|
||||
* @param a scalar
|
||||
* @return a new vector
|
||||
*/
|
||||
/** {@inheritDoc} */
|
||||
public Vector3D scalarMultiply(double a) {
|
||||
return new Vector3D(a * x, a * y, a * z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if any coordinate of this vector is NaN; false otherwise
|
||||
* @return true if any coordinate of this vector is NaN; false otherwise
|
||||
*/
|
||||
/** {@inheritDoc} */
|
||||
public boolean isNaN() {
|
||||
return Double.isNaN(x) || Double.isNaN(y) || Double.isNaN(z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if any coordinate of this vector is infinite and none are NaN;
|
||||
* false otherwise
|
||||
* @return true if any coordinate of this vector is infinite and none are NaN;
|
||||
* false otherwise
|
||||
*/
|
||||
/** {@inheritDoc} */
|
||||
public boolean isInfinite() {
|
||||
return !isNaN() && (Double.isInfinite(x) || Double.isInfinite(y) || Double.isInfinite(z));
|
||||
}
|
||||
|
@ -435,29 +413,23 @@ public class Vector3D implements Serializable {
|
|||
@Override
|
||||
public int hashCode() {
|
||||
if (isNaN()) {
|
||||
return 8;
|
||||
return 642;
|
||||
}
|
||||
return 31 * (23 * MathUtils.hash(x) + 19 * MathUtils.hash(y) + MathUtils.hash(z));
|
||||
return 643 * (164 * MathUtils.hash(x) + 3 * MathUtils.hash(y) + MathUtils.hash(z));
|
||||
}
|
||||
|
||||
/** Compute the dot-product of two vectors.
|
||||
* @param v1 first vector
|
||||
* @param v2 second vector
|
||||
* @return the dot product v1.v2
|
||||
*/
|
||||
public static double dotProduct(Vector3D v1, Vector3D v2) {
|
||||
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
|
||||
/** {@inheritDoc} */
|
||||
public double dotProduct(final Vector<Euclidean3D> v) {
|
||||
final Vector3D v3 = (Vector3D) v;
|
||||
return x * v3.x + y * v3.y + z * v3.z;
|
||||
}
|
||||
|
||||
/** Compute the cross-product of two vectors.
|
||||
* @param v1 first vector
|
||||
* @param v2 second vector
|
||||
* @return the cross product v1 ^ v2 as a new Vector
|
||||
*/
|
||||
public static Vector3D crossProduct(final Vector3D v1, final Vector3D v2) {
|
||||
/** {@inheritDoc} */
|
||||
public Vector3D crossProduct(final Vector<Euclidean3D> v) {
|
||||
final Vector3D v3 = (Vector3D) v;
|
||||
|
||||
final double n1 = v1.getNormSq();
|
||||
final double n2 = v2.getNormSq();
|
||||
final double n1 = getNormSq();
|
||||
final double n2 = v.getNormSq();
|
||||
if ((n1 * n2) < MathUtils.SAFE_MIN) {
|
||||
return ZERO;
|
||||
}
|
||||
|
@ -465,12 +437,12 @@ public class Vector3D implements Serializable {
|
|||
// rescale both vectors without losing precision,
|
||||
// to ensure their norm are the same order of magnitude
|
||||
final int deltaExp = (FastMath.getExponent(n1) - FastMath.getExponent(n2)) / 4;
|
||||
final double x1 = FastMath.scalb(v1.x, -deltaExp);
|
||||
final double y1 = FastMath.scalb(v1.y, -deltaExp);
|
||||
final double z1 = FastMath.scalb(v1.z, -deltaExp);
|
||||
final double x2 = FastMath.scalb(v2.x, deltaExp);
|
||||
final double y2 = FastMath.scalb(v2.y, deltaExp);
|
||||
final double z2 = FastMath.scalb(v2.z, deltaExp);
|
||||
final double x1 = FastMath.scalb(x, -deltaExp);
|
||||
final double y1 = FastMath.scalb(y, -deltaExp);
|
||||
final double z1 = FastMath.scalb(z, -deltaExp);
|
||||
final double x2 = FastMath.scalb(v3.x, deltaExp);
|
||||
final double y2 = FastMath.scalb(v3.y, deltaExp);
|
||||
final double z2 = FastMath.scalb(v3.z, deltaExp);
|
||||
|
||||
// we reduce cancellation errors by preconditioning,
|
||||
// we replace v1 by v3 = v1 - rho v2 with rho chosen in order to compute
|
||||
|
@ -491,6 +463,60 @@ public class Vector3D implements Serializable {
|
|||
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double distance1(Vector<Euclidean3D> v) {
|
||||
final Vector3D v3 = (Vector3D) v;
|
||||
final double dx = FastMath.abs(v3.x - x);
|
||||
final double dy = FastMath.abs(v3.y - y);
|
||||
final double dz = FastMath.abs(v3.z - z);
|
||||
return dx + dy + dz;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double distance(Vector<Euclidean3D> v) {
|
||||
final Vector3D v3 = (Vector3D) v;
|
||||
final double dx = v3.x - x;
|
||||
final double dy = v3.y - y;
|
||||
final double dz = v3.z - z;
|
||||
return FastMath.sqrt(dx * dx + dy * dy + dz * dz);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double distanceInf(Vector<Euclidean3D> v) {
|
||||
final Vector3D v3 = (Vector3D) v;
|
||||
final double dx = FastMath.abs(v3.x - x);
|
||||
final double dy = FastMath.abs(v3.y - y);
|
||||
final double dz = FastMath.abs(v3.z - z);
|
||||
return FastMath.max(FastMath.max(dx, dy), dz);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double distanceSq(Vector<Euclidean3D> v) {
|
||||
final Vector3D v3 = (Vector3D) v;
|
||||
final double dx = v3.x - x;
|
||||
final double dy = v3.y - y;
|
||||
final double dz = v3.z - z;
|
||||
return dx * dx + dy * dy + dz * dz;
|
||||
}
|
||||
|
||||
/** Compute the dot-product of two vectors.
|
||||
* @param v1 first vector
|
||||
* @param v2 second vector
|
||||
* @return the dot product v1.v2
|
||||
*/
|
||||
public static double dotProduct(Vector3D v1, Vector3D v2) {
|
||||
return v1.dotProduct(v2);
|
||||
}
|
||||
|
||||
/** Compute the cross-product of two vectors.
|
||||
* @param v1 first vector
|
||||
* @param v2 second vector
|
||||
* @return the cross product v1 ^ v2 as a new Vector
|
||||
*/
|
||||
public static Vector3D crossProduct(final Vector3D v1, final Vector3D v2) {
|
||||
return v1.crossProduct(v2);
|
||||
}
|
||||
|
||||
/** Compute the distance between two vectors according to the L<sub>1</sub> norm.
|
||||
* <p>Calling this method is equivalent to calling:
|
||||
* <code>v1.subtract(v2).getNorm1()</code> except that no intermediate
|
||||
|
@ -500,10 +526,7 @@ public class Vector3D implements Serializable {
|
|||
* @return the distance between v1 and v2 according to the L<sub>1</sub> norm
|
||||
*/
|
||||
public static double distance1(Vector3D v1, Vector3D v2) {
|
||||
final double dx = FastMath.abs(v2.x - v1.x);
|
||||
final double dy = FastMath.abs(v2.y - v1.y);
|
||||
final double dz = FastMath.abs(v2.z - v1.z);
|
||||
return dx + dy + dz;
|
||||
return v1.distance1(v2);
|
||||
}
|
||||
|
||||
/** Compute the distance between two vectors according to the L<sub>2</sub> norm.
|
||||
|
@ -515,10 +538,7 @@ public class Vector3D implements Serializable {
|
|||
* @return the distance between v1 and v2 according to the L<sub>2</sub> norm
|
||||
*/
|
||||
public static double distance(Vector3D v1, Vector3D v2) {
|
||||
final double dx = v2.x - v1.x;
|
||||
final double dy = v2.y - v1.y;
|
||||
final double dz = v2.z - v1.z;
|
||||
return FastMath.sqrt(dx * dx + dy * dy + dz * dz);
|
||||
return v1.distance(v2);
|
||||
}
|
||||
|
||||
/** Compute the distance between two vectors according to the L<sub>∞</sub> norm.
|
||||
|
@ -530,10 +550,7 @@ public class Vector3D implements Serializable {
|
|||
* @return the distance between v1 and v2 according to the L<sub>∞</sub> norm
|
||||
*/
|
||||
public static double distanceInf(Vector3D v1, Vector3D v2) {
|
||||
final double dx = FastMath.abs(v2.x - v1.x);
|
||||
final double dy = FastMath.abs(v2.y - v1.y);
|
||||
final double dz = FastMath.abs(v2.z - v1.z);
|
||||
return FastMath.max(FastMath.max(dx, dy), dz);
|
||||
return v1.distanceInf(v2);
|
||||
}
|
||||
|
||||
/** Compute the square of the distance between two vectors.
|
||||
|
@ -545,10 +562,7 @@ public class Vector3D implements Serializable {
|
|||
* @return the square of the distance between v1 and v2
|
||||
*/
|
||||
public static double distanceSq(Vector3D v1, Vector3D v2) {
|
||||
final double dx = v2.x - v1.x;
|
||||
final double dy = v2.y - v1.y;
|
||||
final double dz = v2.z - v1.z;
|
||||
return dx * dx + dy * dy + dz * dz;
|
||||
return v1.distanceSq(v2);
|
||||
}
|
||||
|
||||
/** Get a string representation of this vector.
|
||||
|
@ -556,7 +570,12 @@ public class Vector3D implements Serializable {
|
|||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return DEFAULT_FORMAT.format(this);
|
||||
return Vector3DFormat.getInstance().format(this);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public String toString(final NumberFormat format) {
|
||||
return new Vector3DFormat(format).format(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,8 +22,10 @@ import java.text.NumberFormat;
|
|||
import java.text.ParsePosition;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.commons.math.util.CompositeFormat;
|
||||
import org.apache.commons.math.exception.MathParseException;
|
||||
import org.apache.commons.math.geometry.Vector;
|
||||
import org.apache.commons.math.geometry.VectorFormat;
|
||||
import org.apache.commons.math.util.CompositeFormat;
|
||||
|
||||
/**
|
||||
* Formats a 3D vector in components list format "{x; y; z}".
|
||||
|
@ -36,31 +38,9 @@ import org.apache.commons.math.exception.MathParseException;
|
|||
* returned. In the second case, however, the parse position after parsing will be
|
||||
* just after the closing curly brace, i.e. just before the trailing space.</p>
|
||||
*
|
||||
* @version $Revision$ $Date$
|
||||
* @version $Id:$
|
||||
*/
|
||||
public class Vector3DFormat {
|
||||
/** Serializable version identifier */
|
||||
private static final long serialVersionUID = -5447606608652576301L;
|
||||
/** The default prefix: "{". */
|
||||
private static final String DEFAULT_PREFIX = "{";
|
||||
/** The default suffix: "}". */
|
||||
private static final String DEFAULT_SUFFIX = "}";
|
||||
/** The default separator: ", ". */
|
||||
private static final String DEFAULT_SEPARATOR = "; ";
|
||||
/** Prefix. */
|
||||
private final String prefix;
|
||||
/** Suffix. */
|
||||
private final String suffix;
|
||||
/** Separator. */
|
||||
private final String separator;
|
||||
/** Trimmed prefix. */
|
||||
private final String trimmedPrefix;
|
||||
/** Trimmed suffix. */
|
||||
private final String trimmedSuffix;
|
||||
/** Trimmed separator. */
|
||||
private final String trimmedSeparator;
|
||||
/** The format used for components. */
|
||||
private final NumberFormat format;
|
||||
public class Vector3DFormat extends VectorFormat<Euclidean3D> {
|
||||
|
||||
/**
|
||||
* Create an instance with default settings.
|
||||
|
@ -68,7 +48,7 @@ public class Vector3DFormat {
|
|||
* "{", "}", and "; " and the default number format for components.</p>
|
||||
*/
|
||||
public Vector3DFormat() {
|
||||
this(DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_SEPARATOR,
|
||||
super(DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_SEPARATOR,
|
||||
CompositeFormat.getDefaultNumberFormat());
|
||||
}
|
||||
|
||||
|
@ -77,7 +57,7 @@ public class Vector3DFormat {
|
|||
* @param format the custom format for components.
|
||||
*/
|
||||
public Vector3DFormat(final NumberFormat format) {
|
||||
this(DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_SEPARATOR, format);
|
||||
super(DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_SEPARATOR, format);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -88,7 +68,7 @@ public class Vector3DFormat {
|
|||
*/
|
||||
public Vector3DFormat(final String prefix, final String suffix,
|
||||
final String separator) {
|
||||
this(prefix, suffix, separator, CompositeFormat.getDefaultNumberFormat());
|
||||
super(prefix, suffix, separator, CompositeFormat.getDefaultNumberFormat());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -101,54 +81,7 @@ public class Vector3DFormat {
|
|||
*/
|
||||
public Vector3DFormat(final String prefix, final String suffix,
|
||||
final String separator, final NumberFormat format) {
|
||||
this.prefix = prefix;
|
||||
this.suffix = suffix;
|
||||
this.separator = separator;
|
||||
trimmedPrefix = prefix.trim();
|
||||
trimmedSuffix = suffix.trim();
|
||||
trimmedSeparator = separator.trim();
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the set of locales for which 3D vectors formats are available.
|
||||
* <p>This is the same set as the {@link NumberFormat} set.</p>
|
||||
* @return available 3D vector format locales.
|
||||
*/
|
||||
public static Locale[] getAvailableLocales() {
|
||||
return NumberFormat.getAvailableLocales();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the format prefix.
|
||||
* @return format prefix.
|
||||
*/
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the format suffix.
|
||||
* @return format suffix.
|
||||
*/
|
||||
public String getSuffix() {
|
||||
return suffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the format separator between components.
|
||||
* @return format separator.
|
||||
*/
|
||||
public String getSeparator() {
|
||||
return separator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the components format.
|
||||
* @return components format.
|
||||
*/
|
||||
public NumberFormat getFormat() {
|
||||
return format;
|
||||
super(prefix, suffix, separator, format);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -168,16 +101,6 @@ public class Vector3DFormat {
|
|||
return new Vector3DFormat(CompositeFormat.getDefaultNumberFormat(locale));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method calls {@link #format(Vector3D,StringBuffer,FieldPosition)}.
|
||||
*
|
||||
* @param v Vector3D object to format.
|
||||
* @return a formatted vector.
|
||||
*/
|
||||
public String format(Vector3D v) {
|
||||
return format(v, new StringBuffer(), new FieldPosition(0)).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a {@link Vector3D} object to produce a string.
|
||||
* @param vector the object to format.
|
||||
|
@ -186,26 +109,10 @@ public class Vector3DFormat {
|
|||
* offsets of the alignment field
|
||||
* @return the value passed in as toAppendTo.
|
||||
*/
|
||||
public StringBuffer format(Vector3D vector, StringBuffer toAppendTo,
|
||||
FieldPosition pos) {
|
||||
|
||||
pos.setBeginIndex(0);
|
||||
pos.setEndIndex(0);
|
||||
|
||||
// format prefix
|
||||
toAppendTo.append(prefix);
|
||||
|
||||
// format components
|
||||
CompositeFormat.formatDouble(vector.getX(), format, toAppendTo, pos);
|
||||
toAppendTo.append(separator);
|
||||
CompositeFormat.formatDouble(vector.getY(), format, toAppendTo, pos);
|
||||
toAppendTo.append(separator);
|
||||
CompositeFormat.formatDouble(vector.getZ(), format, toAppendTo, pos);
|
||||
|
||||
// format suffix
|
||||
toAppendTo.append(suffix);
|
||||
|
||||
return toAppendTo;
|
||||
public StringBuffer format(final Vector<Euclidean3D> vector, final StringBuffer toAppendTo,
|
||||
final FieldPosition pos) {
|
||||
final Vector3D v3 = (Vector3D) vector;
|
||||
return format(toAppendTo, pos, v3.getX(), v3.getY(), v3.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -215,7 +122,7 @@ public class Vector3DFormat {
|
|||
* @throws MathParseException if the beginning of the specified string
|
||||
* cannot be parsed.
|
||||
*/
|
||||
public Vector3D parse(String source) {
|
||||
public Vector3D parse(final String source) {
|
||||
ParsePosition parsePosition = new ParsePosition(0);
|
||||
Vector3D result = parse(source, parsePosition);
|
||||
if (parsePosition.getIndex() == 0) {
|
||||
|
@ -232,59 +139,12 @@ public class Vector3DFormat {
|
|||
* @param pos input/ouput parsing parameter.
|
||||
* @return the parsed {@link Vector3D} object.
|
||||
*/
|
||||
public Vector3D parse(String source, ParsePosition pos) {
|
||||
int initialIndex = pos.getIndex();
|
||||
|
||||
// parse prefix
|
||||
CompositeFormat.parseAndIgnoreWhitespace(source, pos);
|
||||
if (!CompositeFormat.parseFixedstring(source, trimmedPrefix, pos)) {
|
||||
public Vector3D parse(final String source, final ParsePosition pos) {
|
||||
final double[] coordinates = parseCoordinates(3, source, pos);
|
||||
if (coordinates == null) {
|
||||
return null;
|
||||
}
|
||||
return new Vector3D(coordinates[0], coordinates[1], coordinates[2]);
|
||||
}
|
||||
|
||||
// parse X component
|
||||
CompositeFormat.parseAndIgnoreWhitespace(source, pos);
|
||||
Number x = CompositeFormat.parseNumber(source, format, pos);
|
||||
if (x == null) {
|
||||
// invalid abscissa
|
||||
// set index back to initial, error index should already be set
|
||||
pos.setIndex(initialIndex);
|
||||
return null;
|
||||
}
|
||||
|
||||
// parse Y component
|
||||
CompositeFormat.parseAndIgnoreWhitespace(source, pos);
|
||||
if (!CompositeFormat.parseFixedstring(source, trimmedSeparator, pos)) {
|
||||
return null;
|
||||
}
|
||||
CompositeFormat.parseAndIgnoreWhitespace(source, pos);
|
||||
Number y = CompositeFormat.parseNumber(source, format, pos);
|
||||
if (y == null) {
|
||||
// invalid ordinate
|
||||
// set index back to initial, error index should already be set
|
||||
pos.setIndex(initialIndex);
|
||||
return null;
|
||||
}
|
||||
|
||||
// parse Z component
|
||||
CompositeFormat.parseAndIgnoreWhitespace(source, pos);
|
||||
if (!CompositeFormat.parseFixedstring(source, trimmedSeparator, pos)) {
|
||||
return null;
|
||||
}
|
||||
CompositeFormat.parseAndIgnoreWhitespace(source, pos);
|
||||
Number z = CompositeFormat.parseNumber(source, format, pos);
|
||||
if (z == null) {
|
||||
// invalid height
|
||||
// set index back to initial, error index should already be set
|
||||
pos.setIndex(initialIndex);
|
||||
return null;
|
||||
}
|
||||
|
||||
// parse suffix
|
||||
CompositeFormat.parseAndIgnoreWhitespace(source, pos);
|
||||
if (!CompositeFormat.parseFixedstring(source, trimmedSuffix, pos)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Vector3D(x.doubleValue(), y.doubleValue(), z.doubleValue());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.commons.math.geometry.euclidean.twod;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.apache.commons.math.geometry.Space;
|
||||
import org.apache.commons.math.geometry.euclidean.oned.Euclidean1D;
|
||||
|
||||
/**
|
||||
* This class implements a three-dimensional space.
|
||||
* @version $Id:$
|
||||
* @since 3.0
|
||||
*/
|
||||
public class Euclidean2D implements Serializable, Space {
|
||||
|
||||
/** Serializable version identifier. */
|
||||
private static final long serialVersionUID = 4793432849757649566L;
|
||||
|
||||
/** Private constructor for the singleton.
|
||||
*/
|
||||
private Euclidean2D() {
|
||||
}
|
||||
|
||||
/** Get the unique instance.
|
||||
* @return the unique instance
|
||||
*/
|
||||
public static Euclidean2D getInstance() {
|
||||
return LazyHolder.INSTANCE;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public int getDimension() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public Euclidean1D getSubSpace() {
|
||||
return Euclidean1D.getInstance();
|
||||
}
|
||||
|
||||
// CHECKSTYLE: stop HideUtilityClassConstructor
|
||||
/** Holder for the instance.
|
||||
* <p>We use here the Initialization On Demand Holder Idiom.</p>
|
||||
*/
|
||||
private static class LazyHolder {
|
||||
/** Cached field instance. */
|
||||
private static final Euclidean2D INSTANCE = new Euclidean2D();
|
||||
}
|
||||
// CHECKSTYLE: resume HideUtilityClassConstructor
|
||||
|
||||
/** Handle deserialization of the singleton.
|
||||
* @return the singleton instance
|
||||
*/
|
||||
private Object readResolve() {
|
||||
// return the singleton instance
|
||||
return LazyHolder.INSTANCE;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.commons.math.geometry.euclidean.twod;
|
||||
|
||||
import org.apache.commons.math.geometry.partitioning.Point;
|
||||
import org.apache.commons.math.geometry.partitioning.SubSpace;
|
||||
|
||||
/** This class represents a 2D point.
|
||||
* <p>Instances of this class are guaranteed to be immutable.</p>
|
||||
* @version $Revision$ $Date$
|
||||
*/
|
||||
public class Point2D extends java.awt.geom.Point2D.Double implements Point, SubSpace {
|
||||
|
||||
/** Point at undefined (NaN) coordinates. */
|
||||
public static final Point2D UNDEFINED = new Point2D(java.lang.Double.NaN, java.lang.Double.NaN);
|
||||
|
||||
/** Serializable UID. */
|
||||
private static final long serialVersionUID = 8883702098988517151L;
|
||||
|
||||
/** Build a point with default coordinates.
|
||||
*/
|
||||
public Point2D() {
|
||||
}
|
||||
|
||||
/** Build a point from its coordinates.
|
||||
* @param x abscissa
|
||||
* @param y ordinate
|
||||
*/
|
||||
public Point2D(final double x, final double y) {
|
||||
super(x, y);
|
||||
}
|
||||
|
||||
/** Build a point from a java awt point.
|
||||
* @param point java awt point
|
||||
*/
|
||||
public Point2D(final java.awt.geom.Point2D.Double point) {
|
||||
super(point.x, point.y);
|
||||
}
|
||||
|
||||
/** Transform a 2D space point into a sub-space point.
|
||||
* @param point 2D point of the space
|
||||
* @return always return null
|
||||
* @see #toSpace
|
||||
*/
|
||||
public Point toSubSpace(final Point point) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Transform a sub-space point into a space point.
|
||||
* @param point ignored parameter
|
||||
* @return always return the instance
|
||||
* @see #toSubSpace
|
||||
*/
|
||||
public Point toSpace(final Point point) {
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,346 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.commons.math.geometry.euclidean.twod;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
|
||||
import org.apache.commons.math.geometry.Space;
|
||||
import org.apache.commons.math.geometry.Vector;
|
||||
import org.apache.commons.math.util.FastMath;
|
||||
import org.apache.commons.math.util.MathUtils;
|
||||
|
||||
/** This class represents a 2D vector.
|
||||
* <p>Instances of this class are guaranteed to be immutable.</p>
|
||||
* @version $Id:$
|
||||
* @since 3.0
|
||||
*/
|
||||
public class Vector2D implements Vector<Euclidean2D> {
|
||||
|
||||
/** Origin (coordinates: 0, 0). */
|
||||
public static final Vector2D ZERO = new Vector2D(0, 0);
|
||||
|
||||
// CHECKSTYLE: stop ConstantName
|
||||
/** A vector with all coordinates set to NaN. */
|
||||
public static final Vector2D NaN = new Vector2D(Double.NaN, Double.NaN);
|
||||
// CHECKSTYLE: resume ConstantName
|
||||
|
||||
/** A vector with all coordinates set to positive infinity. */
|
||||
public static final Vector2D POSITIVE_INFINITY =
|
||||
new Vector2D(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
|
||||
|
||||
/** A vector with all coordinates set to negative infinity. */
|
||||
public static final Vector2D NEGATIVE_INFINITY =
|
||||
new Vector2D(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY);
|
||||
|
||||
/** Serializable UID. */
|
||||
private static final long serialVersionUID = 266938651998679754L;
|
||||
|
||||
/** Abscissa. */
|
||||
private final double x;
|
||||
|
||||
/** Ordinate. */
|
||||
private final double y;
|
||||
|
||||
/** Simple constructor.
|
||||
* Build a vector from its coordinates
|
||||
* @param x abscissa
|
||||
* @param y ordinate
|
||||
* @see #getX()
|
||||
* @see #getY()
|
||||
*/
|
||||
public Vector2D(double x, double y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
/** Multiplicative constructor
|
||||
* Build a vector from another one and a scale factor.
|
||||
* The vector built will be a * u
|
||||
* @param a scale factor
|
||||
* @param u base (unscaled) vector
|
||||
*/
|
||||
public Vector2D(double a, Vector2D u) {
|
||||
this.x = a * u.x;
|
||||
this.y = a * u.y;
|
||||
}
|
||||
|
||||
/** Linear constructor
|
||||
* Build a vector from two other ones and corresponding scale factors.
|
||||
* The vector built will be a1 * u1 + a2 * u2
|
||||
* @param a1 first scale factor
|
||||
* @param u1 first base (unscaled) vector
|
||||
* @param a2 second scale factor
|
||||
* @param u2 second base (unscaled) vector
|
||||
*/
|
||||
public Vector2D(double a1, Vector2D u1, double a2, Vector2D u2) {
|
||||
this.x = a1 * u1.x + a2 * u2.x;
|
||||
this.y = a1 * u1.y + a2 * u2.y;
|
||||
}
|
||||
|
||||
/** Linear constructor
|
||||
* Build a vector from three other ones and corresponding scale factors.
|
||||
* The vector built will be a1 * u1 + a2 * u2 + a3 * u3
|
||||
* @param a1 first scale factor
|
||||
* @param u1 first base (unscaled) vector
|
||||
* @param a2 second scale factor
|
||||
* @param u2 second base (unscaled) vector
|
||||
* @param a3 third scale factor
|
||||
* @param u3 third base (unscaled) vector
|
||||
*/
|
||||
public Vector2D(double a1, Vector2D u1, double a2, Vector2D u2,
|
||||
double a3, Vector2D u3) {
|
||||
this.x = a1 * u1.x + a2 * u2.x + a3 * u3.x;
|
||||
this.y = a1 * u1.y + a2 * u2.y + a3 * u3.y;
|
||||
}
|
||||
|
||||
/** Linear constructor
|
||||
* Build a vector from four other ones and corresponding scale factors.
|
||||
* The vector built will be a1 * u1 + a2 * u2 + a3 * u3 + a4 * u4
|
||||
* @param a1 first scale factor
|
||||
* @param u1 first base (unscaled) vector
|
||||
* @param a2 second scale factor
|
||||
* @param u2 second base (unscaled) vector
|
||||
* @param a3 third scale factor
|
||||
* @param u3 third base (unscaled) vector
|
||||
* @param a4 fourth scale factor
|
||||
* @param u4 fourth base (unscaled) vector
|
||||
*/
|
||||
public Vector2D(double a1, Vector2D u1, double a2, Vector2D u2,
|
||||
double a3, Vector2D u3, double a4, Vector2D u4) {
|
||||
this.x = a1 * u1.x + a2 * u2.x + a3 * u3.x + a4 * u4.x;
|
||||
this.y = a1 * u1.y + a2 * u2.y + a3 * u3.y + a4 * u4.y;
|
||||
}
|
||||
|
||||
/** Get the abscissa of the vector.
|
||||
* @return abscissa of the vector
|
||||
* @see #Vector2D(double, double)
|
||||
*/
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
/** Get the ordinate of the vector.
|
||||
* @return ordinate of the vector
|
||||
* @see #Vector2D(double, double)
|
||||
*/
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public Space getSpace() {
|
||||
return Euclidean2D.getInstance();
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public Vector2D getZero() {
|
||||
return ZERO;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public Vector2D toVector() {
|
||||
return new Vector2D(x, y);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double getNorm1() {
|
||||
return FastMath.abs(x) + FastMath.abs(y);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double getNorm() {
|
||||
return FastMath.sqrt (x * x + y * y);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double getNormSq() {
|
||||
return x * x + y * y;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double getNormInf() {
|
||||
return FastMath.max(FastMath.abs(x), FastMath.abs(y));
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public Vector2D add(Vector<Euclidean2D> v) {
|
||||
Vector2D v2 = (Vector2D) v;
|
||||
return new Vector2D(x + v2.getX(), y + v2.getY());
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public Vector2D add(double factor, Vector<Euclidean2D> v) {
|
||||
Vector2D v2 = (Vector2D) v;
|
||||
return new Vector2D(x + factor * v2.getX(), y + factor * v2.getY());
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public Vector2D subtract(Vector<Euclidean2D> p) {
|
||||
Vector2D p3 = (Vector2D) p;
|
||||
return new Vector2D(x - p3.x, y - p3.y);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public Vector2D subtract(double factor, Vector<Euclidean2D> v) {
|
||||
Vector2D v2 = (Vector2D) v;
|
||||
return new Vector2D(x - factor * v2.getX(), y - factor * v2.getY());
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public boolean isNaN() {
|
||||
return Double.isNaN(x) || Double.isNaN(y);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public boolean isInfinite() {
|
||||
return !isNaN() && (Double.isInfinite(x) || Double.isInfinite(y));
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double distance1(Vector<Euclidean2D> p) {
|
||||
Vector2D p3 = (Vector2D) p;
|
||||
final double dx = FastMath.abs(p3.x - x);
|
||||
final double dy = FastMath.abs(p3.y - y);
|
||||
return dx + dy;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double distance(Vector<Euclidean2D> p) {
|
||||
Vector2D p3 = (Vector2D) p;
|
||||
final double dx = p3.x - x;
|
||||
final double dy = p3.y - y;
|
||||
return FastMath.sqrt(dx * dx + dy * dy);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double distanceInf(Vector<Euclidean2D> p) {
|
||||
Vector2D p3 = (Vector2D) p;
|
||||
final double dx = FastMath.abs(p3.x - x);
|
||||
final double dy = FastMath.abs(p3.y - y);
|
||||
return FastMath.max(dx, dy);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public double distanceSq(Vector<Euclidean2D> p) {
|
||||
Vector2D p3 = (Vector2D) p;
|
||||
final double dx = p3.x - x;
|
||||
final double dy = p3.y - y;
|
||||
return dx * dx + dy * dy;
|
||||
}
|
||||
|
||||
/** Compute the distance between two vectors according to the L<sub>2</sub> norm.
|
||||
* <p>Calling this method is equivalent to calling:
|
||||
* <code>p1.subtract(p2).getNorm()</code> except that no intermediate
|
||||
* vector is built</p>
|
||||
* @param p1 first vector
|
||||
* @param p2 second vector
|
||||
* @return the distance between p1 and p2 according to the L<sub>2</sub> norm
|
||||
*/
|
||||
public static double distance(Vector2D p1, Vector2D p2) {
|
||||
return p1.distance(p2);
|
||||
}
|
||||
|
||||
/** Compute the distance between two vectors according to the L<sub>∞</sub> norm.
|
||||
* <p>Calling this method is equivalent to calling:
|
||||
* <code>p1.subtract(p2).getNormInf()</code> except that no intermediate
|
||||
* vector is built</p>
|
||||
* @param p1 first vector
|
||||
* @param p2 second vector
|
||||
* @return the distance between p1 and p2 according to the L<sub>∞</sub> norm
|
||||
*/
|
||||
public static double distanceInf(Vector2D p1, Vector2D p2) {
|
||||
return p1.distanceInf(p2);
|
||||
}
|
||||
|
||||
/** Compute the square of the distance between two vectors.
|
||||
* <p>Calling this method is equivalent to calling:
|
||||
* <code>p1.subtract(p2).getNormSq()</code> except that no intermediate
|
||||
* vector is built</p>
|
||||
* @param p1 first vector
|
||||
* @param p2 second vector
|
||||
* @return the square of the distance between p1 and p2
|
||||
*/
|
||||
public static double distanceSq(Vector2D p1, Vector2D p2) {
|
||||
return p1.distanceSq(p2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for the equality of two 2D vectors.
|
||||
* <p>
|
||||
* If all coordinates of two 2D vectors are exactly the same, and none are
|
||||
* <code>Double.NaN</code>, the two 2D vectors are considered to be equal.
|
||||
* </p>
|
||||
* <p>
|
||||
* <code>NaN</code> coordinates are considered to affect globally the vector
|
||||
* and be equals to each other - i.e, if either (or all) coordinates of the
|
||||
* 2D vector are equal to <code>Double.NaN</code>, the 2D vector is equal to
|
||||
* {@link #NaN}.
|
||||
* </p>
|
||||
*
|
||||
* @param other Object to test for equality to this
|
||||
* @return true if two 2D vector objects are equal, false if
|
||||
* object is null, not an instance of Vector2D, or
|
||||
* not equal to this Vector2D instance
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (other instanceof Vector2D) {
|
||||
final Vector2D rhs = (Vector2D)other;
|
||||
if (rhs.isNaN()) {
|
||||
return this.isNaN();
|
||||
}
|
||||
|
||||
return (x == rhs.x) && (y == rhs.y);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a hashCode for the 2D vector.
|
||||
* <p>
|
||||
* All NaN values have the same hash code.</p>
|
||||
*
|
||||
* @return a hash code value for this object
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if (isNaN()) {
|
||||
return 542;
|
||||
}
|
||||
return 122 * (76 * MathUtils.hash(x) + MathUtils.hash(y));
|
||||
}
|
||||
|
||||
/** Get a string representation of this vector.
|
||||
* @return a string representation of this vector
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return Vector2DFormat.getInstance().format(this);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public String toString(final NumberFormat format) {
|
||||
return new Vector2DFormat(format).format(this);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.commons.math.geometry.euclidean.twod;
|
||||
|
||||
import java.text.FieldPosition;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.ParsePosition;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.commons.math.exception.MathParseException;
|
||||
import org.apache.commons.math.geometry.Vector;
|
||||
import org.apache.commons.math.geometry.VectorFormat;
|
||||
import org.apache.commons.math.util.CompositeFormat;
|
||||
|
||||
/**
|
||||
* Formats a 2D vector in components list format "{x; y}".
|
||||
* <p>The prefix and suffix "{" and "}" and the separator "; " can be replaced by
|
||||
* any user-defined strings. The number format for components can be configured.</p>
|
||||
* <p>White space is ignored at parse time, even if it is in the prefix, suffix
|
||||
* or separator specifications. So even if the default separator does include a space
|
||||
* character that is used at format time, both input string "{1;1}" and
|
||||
* " { 1 ; 1 } " will be parsed without error and the same vector will be
|
||||
* returned. In the second case, however, the parse position after parsing will be
|
||||
* just after the closing curly brace, i.e. just before the trailing space.</p>
|
||||
*
|
||||
* @version $Id:$
|
||||
* @since 3.0
|
||||
*/
|
||||
public class Vector2DFormat extends VectorFormat<Euclidean2D> {
|
||||
|
||||
/**
|
||||
* Create an instance with default settings.
|
||||
* <p>The instance uses the default prefix, suffix and separator:
|
||||
* "{", "}", and "; " and the default number format for components.</p>
|
||||
*/
|
||||
public Vector2DFormat() {
|
||||
super(DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_SEPARATOR,
|
||||
CompositeFormat.getDefaultNumberFormat());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance with a custom number format for components.
|
||||
* @param format the custom format for components.
|
||||
*/
|
||||
public Vector2DFormat(final NumberFormat format) {
|
||||
super(DEFAULT_PREFIX, DEFAULT_SUFFIX, DEFAULT_SEPARATOR, format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance with custom prefix, suffix and separator.
|
||||
* @param prefix prefix to use instead of the default "{"
|
||||
* @param suffix suffix to use instead of the default "}"
|
||||
* @param separator separator to use instead of the default "; "
|
||||
*/
|
||||
public Vector2DFormat(final String prefix, final String suffix,
|
||||
final String separator) {
|
||||
super(prefix, suffix, separator, CompositeFormat.getDefaultNumberFormat());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance with custom prefix, suffix, separator and format
|
||||
* for components.
|
||||
* @param prefix prefix to use instead of the default "{"
|
||||
* @param suffix suffix to use instead of the default "}"
|
||||
* @param separator separator to use instead of the default "; "
|
||||
* @param format the custom format for components.
|
||||
*/
|
||||
public Vector2DFormat(final String prefix, final String suffix,
|
||||
final String separator, final NumberFormat format) {
|
||||
super(prefix, suffix, separator, format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default 2D vector format for the current locale.
|
||||
* @return the default 2D vector format.
|
||||
*/
|
||||
public static Vector2DFormat getInstance() {
|
||||
return getInstance(Locale.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default 2D vector format for the given locale.
|
||||
* @param locale the specific locale used by the format.
|
||||
* @return the 2D vector format specific to the given locale.
|
||||
*/
|
||||
public static Vector2DFormat getInstance(final Locale locale) {
|
||||
return new Vector2DFormat(CompositeFormat.getDefaultNumberFormat(locale));
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public StringBuffer format(final Vector<Euclidean2D> vector, final StringBuffer toAppendTo,
|
||||
final FieldPosition pos) {
|
||||
final Vector2D p2 = (Vector2D) vector;
|
||||
return format(toAppendTo, pos, p2.getX(), p2.getY());
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public Vector2D parse(final String source) {
|
||||
ParsePosition parsePosition = new ParsePosition(0);
|
||||
Vector2D result = parse(source, parsePosition);
|
||||
if (parsePosition.getIndex() == 0) {
|
||||
throw new MathParseException(source,
|
||||
parsePosition.getErrorIndex(),
|
||||
Vector2D.class);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public Vector2D parse(final String source, final ParsePosition pos) {
|
||||
final double[] coordinates = parseCoordinates(2, source, pos);
|
||||
if (coordinates == null) {
|
||||
return null;
|
||||
}
|
||||
return new Vector2D(coordinates[0], coordinates[1]);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
<html>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<!-- $Revision$ -->
|
||||
<body>
|
||||
<p>
|
||||
This package is the top level package for geometry. It provides only a few interfaces
|
||||
related to vectorial/affine spaces that are implemented in sub-packages.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.commons.math.geometry.partitioning;
|
||||
|
||||
import org.apache.commons.math.geometry.Vector;
|
||||
import org.apache.commons.math.geometry.Space;
|
||||
|
||||
/** This interface defines mappers between a space and one of its sub-spaces.
|
||||
|
||||
* <p>Sub-spaces are the lower dimensions subsets of a n-dimensions
|
||||
* space. The (n-1)-dimension sub-spaces are specific sub-spaces known
|
||||
* as {@link Hyperplane hyperplanes}. This interface can be used regardless
|
||||
* of the dimensions differences. As an example, {@link
|
||||
* org.apache.commons.math.geometry.euclidean.threed.Line Line} in 3D
|
||||
* implements Embedding<{@link
|
||||
* org.apache.commons.math.geometry.euclidean.threed.Vector3D Vector3D}, {link
|
||||
* org.apache.commons.math.geometry.euclidean.oned.Vector1D Vector1D>, i.e. it
|
||||
* maps directly dimensions 3 and 1.</p>
|
||||
|
||||
* <p>In the 3D euclidean space, hyperplanes are 2D planes, and the 1D
|
||||
* sub-spaces are lines.</p>
|
||||
|
||||
* @param <S> Type of the embedding space.
|
||||
* @param <T> Type of the embedded sub-space.
|
||||
|
||||
* @see Hyperplane
|
||||
* @version $Id:$
|
||||
* @since 3.0
|
||||
*/
|
||||
public interface Embedding<S extends Space, T extends Space> {
|
||||
|
||||
/** Transform a space point into a sub-space point.
|
||||
* @param point n-dimension point of the space
|
||||
* @return (n-1)-dimension point of the sub-space corresponding to
|
||||
* the specified space point
|
||||
* @see #toSpace
|
||||
*/
|
||||
Vector<T> toSubSpace(Vector<S> point);
|
||||
|
||||
/** Transform a sub-space point into a space point.
|
||||
* @param point (n-1)-dimension point of the sub-space
|
||||
* @return n-dimension point of the space corresponding to the
|
||||
* specified sub-space point
|
||||
* @see #toSubSpace
|
||||
*/
|
||||
Vector<S> toSpace(Vector<T> point);
|
||||
|
||||
}
|
|
@ -52,6 +52,9 @@ The <action> type attribute can be add,update,fix,remove.
|
|||
If the output is not quite correct, check for invisible trailing spaces!
|
||||
-->
|
||||
<release version="3.0" date="TBD" description="TBD">
|
||||
<action dev="luc" type="add">
|
||||
Added a consistent classes hierarchy for Euclidean spaces in dimension 1, 2 and 3.
|
||||
</action>
|
||||
<action dev="luc" type="fix" issue="MATH-579">
|
||||
Improved javadoc for FastMath explaining the overhead at class loading and
|
||||
the targeted use cases.
|
||||
|
|
Loading…
Reference in New Issue