1 package com.github.davidmoten.rtree.geometry.internal;
2
3 import com.github.davidmoten.guavamini.Preconditions;
4 import com.github.davidmoten.rtree.geometry.Geometry;
5 import com.github.davidmoten.rtree.geometry.Rectangle;
6 import com.github.davidmoten.rtree.internal.util.ObjectsHelper;
7
8 import java.util.Objects;
9 import java.util.Optional;
10
11 public final class RectangleDouble implements Rectangle {
12 private final double x1, y1, x2, y2;
13
14 private RectangleDouble(double x1, double y1, double x2, double y2) {
15 Preconditions.checkArgument(x2 >= x1);
16 Preconditions.checkArgument(y2 >= y1);
17 this.x1 = x1;
18 this.y1 = y1;
19 this.x2 = x2;
20 this.y2 = y2;
21 }
22
23 public static RectangleDouble create(double x1, double y1, double x2, double y2) {
24 return new RectangleDouble((double) x1, (double) y1, (double) x2, (double) y2);
25 }
26
27 @Override
28 public double x1() {
29 return x1;
30 }
31
32 @Override
33 public double y1() {
34 return y1;
35 }
36
37 @Override
38 public double x2() {
39 return x2;
40 }
41
42 @Override
43 public double y2() {
44 return y2;
45 }
46
47 @Override
48 public Rectangle add(Rectangle r) {
49 return new RectangleDouble(min(x1, r.x1()), min(y1, r.y1()), max(x2, r.x2()),
50 max(y2, r.y2()));
51 }
52
53 @Override
54 public boolean contains(double x, double y) {
55 return x >= x1 && x <= x2 && y >= y1 && y <= y2;
56 }
57
58 @Override
59 public boolean intersects(Rectangle r) {
60 if (r instanceof RectangleDouble) {
61 RectangleDouble rd = (RectangleDouble) r;
62 return intersects(rd);
63 } else {
64 return GeometryUtil.intersects(x1, y1, x2, y2, r.x1(), r.y1(), r.x2(), r.y2());
65 }
66 }
67
68 private boolean intersects(RectangleDouble rd) {
69 return GeometryUtil.intersects(x1, y1, x2, y2, rd.x1, rd.y1, rd.x2, rd.y2);
70 }
71
72 @Override
73 public double distance(Rectangle r) {
74 return GeometryUtil.distance(x1, y1, x2, y2, r.x1(), r.y1(), r.x2(), r.y2());
75 }
76
77 @Override
78 public Rectangle mbr() {
79 return this;
80 }
81
82 @Override
83 public String toString() {
84 return "Rectangle [x1=" + x1 + ", y1=" + y1 + ", x2=" + x2 + ", y2=" + y2 + "]";
85 }
86
87 @Override
88 public int hashCode() {
89 return Objects.hash(x1, y1, x2, y2);
90 }
91
92 @Override
93 public boolean equals(Object obj) {
94 Optional<RectangleDouble> other = ObjectsHelper.asClass(obj, RectangleDouble.class);
95 if (other.isPresent()) {
96 return Objects.equals(x1, other.get().x1) && Objects.equals(x2, other.get().x2)
97 && Objects.equals(y1, other.get().y1) && Objects.equals(y2, other.get().y2);
98 } else
99 return false;
100 }
101
102 @Override
103 public double intersectionArea(Rectangle r) {
104 if (!intersects(r))
105 return 0;
106 else {
107 return create(max(x1, r.x1()), max(y1, r.y1()), min(x2, r.x2()), min(y2, r.y2()))
108 .area();
109 }
110 }
111
112 @Override
113 public Geometry geometry() {
114 return this;
115 }
116
117 private static double max(double a, double b) {
118 if (a < b)
119 return b;
120 else
121 return a;
122 }
123
124 private static double min(double a, double b) {
125 if (a < b)
126 return a;
127 else
128 return b;
129 }
130
131 @Override
132 public double perimeter() {
133 return 2 * (x2 - x1) + 2 * (y2 - y1);
134 }
135
136 @Override
137 public double area() {
138 return (x2 - x1) * (y2 - y1);
139 }
140
141 @Override
142 public boolean isDoublePrecision() {
143 return true;
144 }
145
146 }