1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.vectomatic.common.model.geometry;
19
20 import com.google.gwt.user.client.rpc.IsSerializable;
21
22
23
24
25 public class LineSegment extends Segment implements IsSerializable {
26 public LineSegment() {
27
28 }
29
30 public LineSegment(Point[] pts) {
31 super(pts);
32 assert(pts.length == 2);
33 }
34 public LineSegment(LineSegment segment) {
35 super(segment);
36 }
37 @Override
38 public String toString() {
39 StringBuffer buffer = new StringBuffer();
40 buffer.append("LineSegment{");
41 buffer.append(_pts[0]);
42 buffer.append(", ");
43 buffer.append(_pts[1]);
44 buffer.append("}");
45 return buffer.toString();
46 }
47
48 @Override
49 public boolean equals(Object obj) {
50 if (obj instanceof LineSegment) {
51 LineSegment segment = (LineSegment)obj;
52 for (int i = 0; i < _pts.length; i++) {
53 if (!_pts[i].equals(segment._pts[i])) {
54 return false;
55 }
56 }
57 return true;
58 }
59 return false;
60 }
61
62 @Override
63 public int hashCode() {
64 int code = 0;
65 for (int i = 0; i < _pts.length; i++) {
66 code += _pts[i].hashCode();
67 }
68 return code;
69 }
70
71
72 @Override
73 public void nearestPointOnSegment(Point p, Point dest) {
74
75 float bax = _pts[1].x - _pts[0].x;
76 float bay = _pts[1].y - _pts[0].y;
77 float pax = p.x - _pts[0].x;
78 float pay = p.y - _pts[0].y;
79 float bpx = _pts[1].x - p.x;
80 float bpy = _pts[1].y - p.y;
81 if (pax * bax + pay * bay < 0) {
82
83 _pts[0].copyTo(dest);
84 } else if (bpx * bax + bpy * bay < 0) {
85
86 _pts[1].copyTo(dest);
87 } else {
88 float a = _pts[1].y - _pts[0].y;
89 float b = _pts[0].x - _pts[1].x;
90 float c = _pts[1].x * _pts[0].y - _pts[0].x * _pts[1].y;
91
92 float d = b * p.x -a * p.y;
93 dest.x = (b * d - a * c) / (a * a + b * b);
94 dest.y = (- a * d - b * c) / (a * a + b * b);
95 }
96 }
97
98 @Override
99 public Segment clone() {
100 return new LineSegment(this);
101 }
102 }