Skip to content

Commit 5a76549

Browse files
Sushant NadavadeSushant Nadavade
authored andcommitted
all tests passed
1 parent a37b053 commit 5a76549

File tree

1 file changed

+33
-34
lines changed

1 file changed

+33
-34
lines changed

src/main/java/com/thealgorithms/geometry/RotatingCalipers.java

Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
import java.util.ArrayList;
44
import java.util.Collection;
55
import java.util.Collections;
6-
import java.util.HashSet;
76
import java.util.List;
8-
import java.util.Set;
97

108
/**
119
* A class implementing the Rotating Calipers algorithm for geometric computations on convex polygons.
@@ -137,62 +135,63 @@ public static double computeWidth(Collection<Point> points) {
137135
return 0.0;
138136
}
139137

140-
int n = hull.size();
141138
double minWidth = Double.MAX_VALUE;
139+
int n = hull.size();
142140

143-
// Generate all critical orientations for rotating calipers
144-
Set<Double> angles = new HashSet<>();
145-
146-
// Add orientations perpendicular to each edge
141+
// Method 1: Check orientations perpendicular to edges
147142
for (int i = 0; i < n; i++) {
148143
Point p1 = hull.get(i);
149144
Point p2 = hull.get((i + 1) % n);
150145

151146
double dx = p2.x() - p1.x();
152147
double dy = p2.y() - p1.y();
148+
double edgeLen = Math.sqrt(dx * dx + dy * dy);
149+
150+
if (edgeLen == 0) continue;
151+
152+
// Perpendicular to edge direction (measurement direction)
153+
double perpX = -dy / edgeLen;
154+
double perpY = dx / edgeLen;
155+
156+
double minProj = Double.MAX_VALUE;
157+
double maxProj = Double.MIN_VALUE;
153158

154-
if (dx != 0 || dy != 0) {
155-
// Angle of the perpendicular to this edge
156-
double angle = Math.atan2(-dx, dy); // perpendicular to (dx,dy) is (-dy,dx)
157-
angles.add(angle);
159+
for (Point p : hull) {
160+
double proj = p.x() * perpX + p.y() * perpY;
161+
minProj = Math.min(minProj, proj);
162+
maxProj = Math.max(maxProj, proj);
158163
}
164+
165+
minWidth = Math.min(minWidth, maxProj - minProj);
159166
}
160167

161-
// Add orientations defined by vertex pairs (for antipodal cases)
168+
// Method 2: Check orientations defined by vertex pairs
162169
for (int i = 0; i < n; i++) {
163170
for (int j = i + 1; j < n; j++) {
164171
Point p1 = hull.get(i);
165172
Point p2 = hull.get(j);
166173

167174
double dx = p2.x() - p1.x();
168175
double dy = p2.y() - p1.y();
176+
double len = Math.sqrt(dx * dx + dy * dy);
169177

170-
if (dx != 0 || dy != 0) {
171-
// Angle perpendicular to the line from p1 to p2
172-
double angle = Math.atan2(-dx, dy);
173-
angles.add(angle);
174-
}
175-
}
176-
}
178+
if (len == 0) continue;
177179

178-
// Test each critical orientation
179-
for (double angle : angles) {
180-
// Unit vector in the measurement direction
181-
double dirX = Math.sin(angle);
182-
double dirY = Math.cos(angle);
180+
// Direction perpendicular to the line p1-p2
181+
double perpX = -dy / len;
182+
double perpY = dx / len;
183183

184-
// Project all points onto this direction
185-
double minProj = Double.MAX_VALUE;
186-
double maxProj = Double.MIN_VALUE;
184+
double minProj = Double.MAX_VALUE;
185+
double maxProj = Double.MIN_VALUE;
187186

188-
for (Point p : hull) {
189-
double proj = p.x() * dirX + p.y() * dirY;
190-
minProj = Math.min(minProj, proj);
191-
maxProj = Math.max(maxProj, proj);
192-
}
187+
for (Point p : hull) {
188+
double proj = p.x() * perpX + p.y() * perpY;
189+
minProj = Math.min(minProj, proj);
190+
maxProj = Math.max(maxProj, proj);
191+
}
193192

194-
double width = maxProj - minProj;
195-
minWidth = Math.min(minWidth, width);
193+
minWidth = Math.min(minWidth, maxProj - minProj);
194+
}
196195
}
197196

198197
return minWidth;

0 commit comments

Comments
 (0)