Skip to content

Commit 77806f8

Browse files
committed
introduced connected intervals
1 parent 5636b26 commit 77806f8

File tree

5 files changed

+108
-1
lines changed

5 files changed

+108
-1
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package net.itarray.automotion.internal.geometry;
2+
3+
import com.google.common.collect.Lists;
4+
5+
import java.util.ArrayList;
6+
import java.util.Collections;
7+
import java.util.Comparator;
8+
import java.util.List;
9+
10+
import static java.lang.String.format;
11+
12+
public class ConnectedIntervals {
13+
private final List<Interval> components;
14+
15+
public ConnectedIntervals(List<Interval> intervals) {
16+
this.components = Lists.newArrayList();
17+
ArrayList<Interval> sorted = new ArrayList<>(intervals);
18+
Comparator<Interval> comparator = Interval.comparator();
19+
Collections.sort(sorted, comparator);
20+
int i = 0;
21+
while (i < sorted.size()) {
22+
Interval interval = sorted.get(i);
23+
i++;
24+
while (i < sorted.size() && !interval.intersect(sorted.get(i)).isEmpty()) {
25+
interval = interval.span(sorted.get(i));
26+
i++;
27+
}
28+
components.add(interval);
29+
}
30+
}
31+
32+
public int size() {
33+
return components.size();
34+
}
35+
36+
public int indexOf(Interval interval) {
37+
for (int i = 0; i < components.size(); i++) {
38+
Interval component = components.get(i);
39+
if (!component.intersect(interval).isEmpty()) {
40+
return i;
41+
}
42+
}
43+
throw new RuntimeException(format("interval %s is not in connected intervals", interval));
44+
}
45+
}

src/main/java/net/itarray/automotion/internal/geometry/Interval.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package net.itarray.automotion.internal.geometry;
22

3+
import org.jetbrains.annotations.NotNull;
4+
5+
import java.util.Comparator;
36
import java.util.Objects;
47

58
import static net.itarray.automotion.internal.geometry.Scalar.scalar;
@@ -43,6 +46,15 @@ private static String format(String begin, String end) {
4346

4447
public abstract Interval spanWithNonEmpty(NonEmpty interval);
4548

49+
public static Comparator<Interval> comparator() {
50+
return new Comparator<Interval>() {
51+
@Override
52+
public int compare(Interval o1, Interval o2) {
53+
return ((NonEmpty)o1).compareTo((NonEmpty)o2);
54+
}
55+
};
56+
}
57+
4658
private static class Empty extends Interval {
4759
private Empty() {
4860
}
@@ -85,7 +97,7 @@ public Interval spanWithNonEmpty(NonEmpty interval) {
8597
}
8698
}
8799

88-
private static class NonEmpty extends Interval {
100+
private static class NonEmpty extends Interval implements Comparable<NonEmpty> {
89101
private final Scalar begin;
90102
private final Scalar end;
91103

@@ -140,5 +152,14 @@ public Interval spanWithNonEmpty(NonEmpty interval) {
140152
begin.min(interval.begin),
141153
end.max(interval.end));
142154
}
155+
156+
@Override
157+
public int compareTo(NonEmpty other) {
158+
int c = begin.compareTo(other.begin);
159+
if (c != 0) {
160+
return c;
161+
}
162+
return end.compareTo(other.end);
163+
}
143164
}
144165
}

src/test/java/net/itarray/automotion/tests/geometry/DisjointIntervalsTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package net.itarray.automotion.tests.geometry;
22

3+
import net.itarray.automotion.internal.geometry.ConnectedIntervals;
34
import net.itarray.automotion.internal.geometry.Interval;
45
import org.junit.Test;
56

7+
import java.util.List;
8+
69
import static net.itarray.automotion.internal.geometry.Interval.interval;
710
import static org.assertj.core.api.Assertions.assertThat;
811

@@ -27,4 +30,13 @@ public void haveSpanFromSmallestBeginToLargestEnd() {
2730
assertThat(right().span(left())).isEqualTo(span);
2831
assertThat(left().span(right())).isEqualTo(span);
2932
}
33+
34+
@Test
35+
public void areNotConnected() {
36+
assertComponentIndex(leftAndRight(), left(), 0);
37+
assertComponentIndex(leftAndRight(), right(), 1);
38+
assertComponentIndex(rightAndLeft(), left(), 0);
39+
assertComponentIndex(rightAndLeft(), right(), 1);
40+
}
41+
3042
}

src/test/java/net/itarray/automotion/tests/geometry/OverlappingIntervalsTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,14 @@ public void haveSpanFromSmallestBeginToLargestEnd() {
2626
assertThat(right().span(left())).isEqualTo(span);
2727
assertThat(left().span(right())).isEqualTo(span);
2828
}
29+
30+
31+
@Test
32+
public void areNotConnected() {
33+
assertComponentIndex(leftAndRight(), left(), 0);
34+
assertComponentIndex(leftAndRight(), right(), 0);
35+
assertComponentIndex(rightAndLeft(), left(), 0);
36+
assertComponentIndex(rightAndLeft(), right(), 0);
37+
}
38+
2939
}

src/test/java/net/itarray/automotion/tests/geometry/TwoIntervalsTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
package net.itarray.automotion.tests.geometry;
22

3+
import com.google.common.collect.Lists;
4+
import net.itarray.automotion.internal.geometry.ConnectedIntervals;
35
import net.itarray.automotion.internal.geometry.Interval;
46
import net.itarray.automotion.internal.geometry.Scalar;
57
import org.junit.Test;
68

9+
import java.util.List;
10+
711
import static org.assertj.core.api.Assertions.assertThat;
812

913
public abstract class TwoIntervalsTest {
@@ -12,6 +16,14 @@ public abstract class TwoIntervalsTest {
1216

1317
public abstract Interval right();
1418

19+
public List<Interval> leftAndRight() {
20+
return Lists.newArrayList(left(), right());
21+
}
22+
23+
public List<Interval> rightAndLeft() {
24+
return Lists.newArrayList(right(), left());
25+
}
26+
1527
@Test
1628
public void intersectIsSymmetric() {
1729
assertThat(left().intersect(right())).isEqualTo(right().intersect(left()));
@@ -21,4 +33,11 @@ public void intersectIsSymmetric() {
2133
public void spanIsSymmetric() {
2234
assertThat(left().span(right())).isEqualTo(right().span(left()));
2335
}
36+
37+
protected void assertComponentIndex(List<Interval> intervals, Interval interval, int expected) {
38+
ConnectedIntervals connectedIntervals = new ConnectedIntervals(intervals);
39+
int leftIndex = connectedIntervals.indexOf(interval);
40+
assertThat(leftIndex).isEqualTo(expected);
41+
}
42+
2443
}

0 commit comments

Comments
 (0)