View Javadoc
1   // ******************************************************************************
2   //
3   // Title:       Force Field X.
4   // Description: Force Field X - Software for Molecular Biophysics.
5   // Copyright:   Copyright (c) Michael J. Schnieders 2001-2025.
6   //
7   // This file is part of Force Field X.
8   //
9   // Force Field X is free software; you can redistribute it and/or modify it
10  // under the terms of the GNU General Public License version 3 as published by
11  // the Free Software Foundation.
12  //
13  // Force Field X is distributed in the hope that it will be useful, but WITHOUT
14  // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16  // details.
17  //
18  // You should have received a copy of the GNU General Public License along with
19  // Force Field X; if not, write to the Free Software Foundation, Inc., 59 Temple
20  // Place, Suite 330, Boston, MA 02111-1307 USA
21  //
22  // Linking this library statically or dynamically with other modules is making a
23  // combined work based on this library. Thus, the terms and conditions of the
24  // GNU General Public License cover the whole combination.
25  //
26  // As a special exception, the copyright holders of this library give you
27  // permission to link this library with independent modules to produce an
28  // executable, regardless of the license terms of these independent modules, and
29  // to copy and distribute the resulting executable under terms of your choice,
30  // provided that you also meet, for each linked independent module, the terms
31  // and conditions of the license of that module. An independent module is a
32  // module which is not derived from or based on this library. If you modify this
33  // library, you may extend this exception to your version of the library, but
34  // you are not obligated to do so. If you do not wish to do so, delete this
35  // exception statement from your version.
36  //
37  // ******************************************************************************
38  package ffx.numerics.quickhull;
39  
40  /**
41   * Represents the half-edges that surround each face in a counter-clockwise
42   * direction.
43   *
44   * @author John E. Lloyd, Fall 2004
45   * @author Michael J. Schnieders
46   * @since 1.0
47   */
48  public class HalfEdge {
49  
50    /**
51     * The vertex associated with the head of this half-edge.
52     */
53    protected Vertex vertex;
54  
55    /**
56     * Triangular face associated with this half-edge.
57     */
58    protected Face face;
59  
60    /**
61     * Next half-edge in the triangle.
62     */
63    protected HalfEdge next;
64  
65    /**
66     * Previous half-edge in the triangle.
67     */
68    protected HalfEdge prev;
69  
70    /**
71     * Half-edge associated with the opposite triangle adjacent to this edge.
72     */
73    protected HalfEdge opposite;
74  
75    /**
76     * Constructs a HalfEdge with head vertex <code>v</code> and left-hand
77     * triangular face <code>f</code>.
78     *
79     * @param v head vertex
80     * @param f left-hand triangular face
81     */
82    public HalfEdge(Vertex v, Face f) {
83      vertex = v;
84      face = f;
85    }
86  
87    /**
88     * Constructs an uninitialized HalfEdge.
89     * Fields may be set later via mutators.
90     */
91    public HalfEdge() {
92    }
93  
94    /**
95     * Sets the value of the next edge adjacent (counter-clockwise) to this one
96     * within the triangle.
97     *
98     * @param edge next adjacent edge
99     */
100   public void setNext(HalfEdge edge) {
101     next = edge;
102   }
103 
104   /**
105    * Gets the value of the next edge adjacent (counter-clockwise) to this one
106    * within the triangle.
107    *
108    * @return next adjacent edge
109    */
110   public HalfEdge getNext() {
111     return next;
112   }
113 
114   /**
115    * Sets the value of the previous edge adjacent (clockwise) to this one
116    * within the triangle.
117    *
118    * @param edge previous adjacent edge
119    */
120   public void setPrev(HalfEdge edge) {
121     prev = edge;
122   }
123 
124   /**
125    * Gets the value of the previous edge adjacent (clockwise) to this one
126    * within the triangle.
127    *
128    * @return previous adjacent edge
129    */
130   public HalfEdge getPrev() {
131     return prev;
132   }
133 
134   /**
135    * Returns the triangular face located to the left of this half-edge.
136    *
137    * @return left-hand triangular face
138    */
139   public Face getFace() {
140     return face;
141   }
142 
143   /**
144    * Returns the half-edge opposite to this half-edge.
145    *
146    * @return opposite half-edge
147    */
148   public HalfEdge getOpposite() {
149     return opposite;
150   }
151 
152   /**
153    * Sets the half-edge opposite to this half-edge.
154    *
155    * @param edge opposite half-edge
156    */
157   public void setOpposite(HalfEdge edge) {
158     opposite = edge;
159     edge.opposite = this;
160   }
161 
162   /**
163    * Returns the head vertex associated with this half-edge.
164    *
165    * @return head vertex
166    */
167   public Vertex head() {
168     return vertex;
169   }
170 
171   /**
172    * Returns the tail vertex associated with this half-edge.
173    *
174    * @return tail vertex
175    */
176   public Vertex tail() {
177     return prev != null ? prev.vertex : null;
178   }
179 
180   /**
181    * Returns the opposite triangular face associated with this half-edge.
182    *
183    * @return opposite triangular face
184    */
185   public Face oppositeFace() {
186     return opposite != null ? opposite.face : null;
187   }
188 
189   /**
190    * Produces a string identifying this half-edge by the point index values of
191    * its tail and head vertices.
192    *
193    * @return identifying string
194    */
195   public String getVertexString() {
196     if (tail() != null) {
197       return tail().index + "-" + head().index;
198     } else {
199       return "?-" + head().index;
200     }
201   }
202 
203   /**
204    * Returns the length of this half-edge.
205    *
206    * @return half-edge length
207    */
208   public double length() {
209     if (tail() != null) {
210       return head().pnt.distance(tail().pnt);
211     } else {
212       return -1;
213     }
214   }
215 
216   /**
217    * Returns the length squared of this half-edge.
218    *
219    * @return half-edge length squared
220    */
221   public double lengthSquared() {
222     if (tail() != null) {
223       return head().pnt.distanceSquared(tail().pnt);
224     } else {
225       return -1;
226     }
227   }
228 }