1 /**********************************************
2 * Copyright (C) 2009 Lukas Laag
3 * This file is part of Vectomatic.
4 *
5 * Vectomatic is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * Vectomatic is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with Vectomatic. If not, see http://www.gnu.org/licenses/
17 **********************************************/
18 package org.vectomatic.common.model.geometry;
19
20 import com.google.gwt.user.client.rpc.IsSerializable;
21
22
23 /**
24 * Base class for path segments (line segment, bezier spline segments)
25 * @author Lukas Laag
26 */
27 public abstract class Segment implements IsSerializable {
28 protected Point[] _pts;
29 protected BoundingBox _bbox; // bounding box of the segment
30
31 public Segment() {
32 // For GWT serialization
33 }
34
35 /**
36 * Constructor
37 * @param pts
38 * An array of points defining the segment
39 */
40 public Segment(Point[] pts) {
41 _pts = new Point[pts.length];
42 for (int i = 0; i < pts.length; i++) {
43 _pts[i] = new Point(pts[i]);
44 }
45 _bbox = new BoundingBox();
46 _updateBoundingBox();
47 }
48
49 /**
50 * Copy constuctor
51 * @param segment
52 * A segment to duplicate
53 */
54 public Segment(Segment segment) {
55 _pts = new Point[segment._pts.length];
56 for (int i = 0; i < _pts.length; i++) {
57 _pts[i] = new Point(segment._pts[i]);
58 }
59 _bbox = new BoundingBox(segment._bbox);
60 }
61
62 /**
63 * Returns the segment first point
64 * @return
65 */
66 public Point getStartPoint() {
67 return _pts[0];
68 }
69
70 /**
71 * Return the segment last point
72 * @return
73 */
74 public Point getEndPoint() {
75 return _pts[_pts.length - 1];
76 }
77
78 /**
79 * Gets the bounding box of the segment
80 * @return
81 * the bounding box of the segment
82 */
83 public BoundingBox getBoundingBox() {
84 return _bbox;
85 }
86
87 private void _updateBoundingBox() {
88 _bbox.xmin = _pts[0].x;
89 _bbox.ymin = _pts[0].y;
90 _bbox.xmax = _pts[0].x;
91 _bbox.ymax = _pts[0].y;
92 for (int i = 1; i < _pts.length; i++) {
93 if (_pts[i].x < _bbox.xmin) {
94 _bbox.xmin = _pts[i].x;
95 }
96 if (_pts[i].y < _bbox.ymin) {
97 _bbox.ymin = _pts[i].y;
98 }
99 if (_pts[i].x > _bbox.xmax) {
100 _bbox.xmax = _pts[i].x;
101 }
102 if (_pts[i].y > _bbox.ymax) {
103 _bbox.ymax = _pts[i].y;
104 }
105 }
106 }
107
108
109 /**
110 * Returns the squared distance from an arbitrary point p
111 * to the nearest point on the segment
112 * @param p
113 * An arbitrary point p
114 * @return
115 * The squared distance from the closest point on the segment to p
116 */
117 public float squaredDistanceToPoint(Point p) {
118 Point nearestPoint = new Point();
119 nearestPointOnSegment(p, nearestPoint);
120 return nearestPoint.squareDistance(p);
121 }
122
123 /**
124 * Returns the closest point on the segment to the specified point
125 * @param p
126 * An arbitrary point p
127 * @param dest
128 * The closest point on the segment to p
129 */
130 public abstract void nearestPointOnSegment(Point p, Point dest);
131
132 public abstract Segment clone();
133
134 public Point[] getVertices() {
135 return _pts;
136 }
137
138 }