001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.geometry.euclidean;
018
019import java.util.Objects;
020
021import org.apache.commons.geometry.core.Embedding;
022import org.apache.commons.geometry.euclidean.oned.Vector1D;
023
024/** Base class for intersections discovered during linecast operations. This class contains
025 * the intersection point and the normal of the target boundary at the point of intersection
026 * along with the intersecting line and abscissa.
027 * @param <P> Euclidean point/vector implementation type
028 * @param <U> Unit-length Euclidean vector implementation type
029 * @param <L> Line implementation type
030 */
031public abstract class AbstractLinecastPoint<
032    P extends EuclideanVector<P>,
033    U extends P,
034    L extends Embedding<P, Vector1D>> {
035
036    /** Line intersection point. */
037    private final P point;
038
039    /** Normal of the target boundary at the intersection point. */
040    private final U normal;
041
042    /** The intersecting line. */
043    private final L line;
044
045    /** Abscissa of the intersection point along the intersecting line. */
046    private final double abscissa;
047
048    /** Construct a new instance from its components.
049     * @param point intersection point
050     * @param normal surface normal
051     * @param line line that the intersection point belongs to
052     */
053    protected AbstractLinecastPoint(final P point, final U normal, final L line) {
054        this.point = point;
055        this.normal = normal;
056        this.line = line;
057
058        this.abscissa = line.toSubspace(point).getX();
059    }
060
061    /** Get the line intersection point.
062     * @return the line intersection point
063     */
064    public P getPoint() {
065        return point;
066    }
067
068    /** Get the normal of the target boundary at the intersection point.
069     * @return the normal of the target boundary at the intersection point
070     */
071    public U getNormal() {
072        return normal;
073    }
074
075    /** Get the intersecting line.
076     * @return the intersecting line
077     */
078    public L getLine() {
079        return line;
080    }
081
082    /** Get the abscissa (1D position) of the intersection point
083     * along the linecast line.
084     * @return the abscissa of the intersection point.
085     */
086    public double getAbscissa() {
087        return abscissa;
088    }
089
090    /** {@inheritDoc} */
091    @Override
092    public int hashCode() {
093        return Objects.hash(point, normal, line);
094    }
095
096    /** {@inheritDoc} */
097    @Override
098    public boolean equals(final Object obj) {
099        if (this == obj) {
100            return true;
101        }
102        if (obj == null || !getClass().equals(obj.getClass())) {
103            return false;
104        }
105
106        final AbstractLinecastPoint<?, ?, ?> other = (AbstractLinecastPoint<?, ?, ?>) obj;
107
108        return Objects.equals(point, other.point) &&
109                Objects.equals(normal, other.normal) &&
110                Objects.equals(line, other.line);
111    }
112
113    /** {@inheritDoc} */
114    @Override
115    public String toString() {
116        final StringBuilder sb = new StringBuilder(50);
117        sb.append(getClass().getSimpleName())
118            .append("[point= ")
119            .append(getPoint())
120            .append(", normal= ")
121            .append(getNormal())
122            .append(", abscissa= ")
123            .append(getAbscissa())
124            .append(", line= ")
125            .append(getLine())
126            .append(']');
127
128        return sb.toString();
129    }
130}