All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.hipparchus.geometry.euclidean.threed.FieldLine Maven / Gradle / Ivy

There is a newer version: 3.1
Show newest version
/*
 * 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.
 */

/*
 * This is not the original file distributed by the Apache Software Foundation
 * It has been modified by the Hipparchus project
 */
package org.hipparchus.geometry.euclidean.threed;

import org.hipparchus.RealFieldElement;
import org.hipparchus.exception.LocalizedCoreFormats;
import org.hipparchus.exception.MathIllegalArgumentException;
import org.hipparchus.util.FastMath;
import org.hipparchus.util.Precision;

/** The class represent lines in a three dimensional space.

 * 

Each oriented line is intrinsically associated with an abscissa * which is a coordinate on the line. The point at abscissa 0 is the * orthogonal projection of the origin on the line, another equivalent * way to express this is to say that it is the point of the line * which is closest to the origin. Abscissa increases in the line * direction.

* @param the type of the field elements */ public class FieldLine> { /** Line direction. */ private FieldVector3D direction; /** Line point closest to the origin. */ private FieldVector3D zero; /** Tolerance below which points are considered identical. */ private final double tolerance; /** Build a line from two points. * @param p1 first point belonging to the line (this can be any point) * @param p2 second point belonging to the line (this can be any point, different from p1) * @param tolerance tolerance below which points are considered identical * @exception MathIllegalArgumentException if the points are equal */ public FieldLine(final FieldVector3D p1, final FieldVector3D p2, final double tolerance) throws MathIllegalArgumentException { reset(p1, p2); this.tolerance = tolerance; } /** Copy constructor. *

The created instance is completely independent from the * original instance, it is a deep copy.

* @param line line to copy */ public FieldLine(final FieldLine line) { this.direction = line.direction; this.zero = line.zero; this.tolerance = line.tolerance; } /** Reset the instance as if built from two points. * @param p1 first point belonging to the line (this can be any point) * @param p2 second point belonging to the line (this can be any point, different from p1) * @exception MathIllegalArgumentException if the points are equal */ public void reset(final FieldVector3D p1, final FieldVector3D p2) throws MathIllegalArgumentException { final FieldVector3D delta = p2.subtract(p1); final T norm2 = delta.getNormSq(); if (norm2.getReal() == 0.0) { throw new MathIllegalArgumentException(LocalizedCoreFormats.ZERO_NORM); } this.direction = new FieldVector3D<>(norm2.sqrt().reciprocal(), delta); zero = new FieldVector3D<>(norm2.getField().getOne(), p1, p1.dotProduct(delta).negate().divide(norm2), delta); } /** Get the tolerance below which points are considered identical. * @return tolerance below which points are considered identical */ public double getTolerance() { return tolerance; } /** Get a line with reversed direction. * @return a new instance, with reversed direction */ public FieldLine revert() { final FieldLine reverted = new FieldLine<>(this); reverted.direction = reverted.direction.negate(); return reverted; } /** Get the normalized direction vector. * @return normalized direction vector */ public FieldVector3D getDirection() { return direction; } /** Get the line point closest to the origin. * @return line point closest to the origin */ public FieldVector3D getOrigin() { return zero; } /** Get the abscissa of a point with respect to the line. *

The abscissa is 0 if the projection of the point and the * projection of the frame origin on the line are the same * point.

* @param point point to check * @return abscissa of the point */ public T getAbscissa(final FieldVector3D point) { return point.subtract(zero).dotProduct(direction); } /** Get the abscissa of a point with respect to the line. *

The abscissa is 0 if the projection of the point and the * projection of the frame origin on the line are the same * point.

* @param point point to check * @return abscissa of the point */ public T getAbscissa(final Vector3D point) { return zero.subtract(point).dotProduct(direction).negate(); } /** Get one point from the line. * @param abscissa desired abscissa for the point * @return one point belonging to the line, at specified abscissa */ public FieldVector3D pointAt(final T abscissa) { return new FieldVector3D(abscissa.getField().getOne(), zero, abscissa, direction); } /** Get one point from the line. * @param abscissa desired abscissa for the point * @return one point belonging to the line, at specified abscissa */ public FieldVector3D pointAt(final double abscissa) { return new FieldVector3D(1, zero, abscissa, direction); } /** Check if the instance is similar to another line. *

Lines are considered similar if they contain the same * points. This does not mean they are equal since they can have * opposite directions.

* @param line line to which instance should be compared * @return true if the lines are similar */ public boolean isSimilarTo(final FieldLine line) { final double angle = FieldVector3D.angle(direction, line.direction).getReal(); return ((angle < tolerance) || (angle > (FastMath.PI - tolerance))) && contains(line.zero); } /** Check if the instance contains a point. * @param p point to check * @return true if p belongs to the line */ public boolean contains(final FieldVector3D p) { return distance(p).getReal() < tolerance; } /** Check if the instance contains a point. * @param p point to check * @return true if p belongs to the line */ public boolean contains(final Vector3D p) { return distance(p).getReal() < tolerance; } /** Compute the distance between the instance and a point. * @param p to check * @return distance between the instance and the point */ public T distance(final FieldVector3D p) { final FieldVector3D d = p.subtract(zero); final FieldVector3D n = new FieldVector3D<>(zero.getX().getField().getOne(), d, d.dotProduct(direction).negate(), direction); return n.getNorm(); } /** Compute the distance between the instance and a point. * @param p to check * @return distance between the instance and the point */ public T distance(final Vector3D p) { final FieldVector3D d = zero.subtract(p).negate(); final FieldVector3D n = new FieldVector3D<>(zero.getX().getField().getOne(), d, d.dotProduct(direction).negate(), direction); return n.getNorm(); } /** Compute the shortest distance between the instance and another line. * @param line line to check against the instance * @return shortest distance between the instance and the line */ public T distance(final FieldLine line) { final FieldVector3D normal = FieldVector3D.crossProduct(direction, line.direction); final T n = normal.getNorm(); if (n.getReal() < Precision.SAFE_MIN) { // lines are parallel return distance(line.zero); } // signed separation of the two parallel planes that contains the lines final T offset = line.zero.subtract(zero).dotProduct(normal).divide(n); return offset.abs(); } /** Compute the point of the instance closest to another line. * @param line line to check against the instance * @return point of the instance closest to another line */ public FieldVector3D closestPoint(final FieldLine line) { final T cos = direction.dotProduct(line.direction); final T n = cos.multiply(cos).subtract(1).negate(); if (n.getReal() < Precision.EPSILON) { // the lines are parallel return zero; } final FieldVector3D delta0 = line.zero.subtract(zero); final T a = delta0.dotProduct(direction); final T b = delta0.dotProduct(line.direction); return new FieldVector3D(a.getField().getOne(), zero, a.subtract(b.multiply(cos)).divide(n), direction); } /** Get the intersection point of the instance and another line. * @param line other line * @return intersection point of the instance and the other line * or null if there are no intersection points */ public FieldVector3D intersection(final FieldLine line) { final FieldVector3D closest = closestPoint(line); return line.contains(closest) ? closest : null; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy