110 |
110 |
111 if (p.integral_norm() < min_distance as u32 * 3) || !map_box.contains_inside(mid_point) { |
111 if (p.integral_norm() < min_distance as u32 * 3) || !map_box.contains_inside(mid_point) { |
112 return None; |
112 return None; |
113 } |
113 } |
114 |
114 |
115 let full_box = Rect::at_origin(self.size).with_margin(min_distance); |
|
116 |
|
117 let mut dist_left = (self.size.width + self.size.height) as u32; |
115 let mut dist_left = (self.size.width + self.size.height) as u32; |
118 let mut dist_right = dist_left; |
116 let mut dist_right = dist_left; |
119 |
117 |
120 // find distances to map borders |
118 // find distances to map borders |
121 if p.x != 0 { |
119 if p.x != 0 { |
122 // check against left border |
120 // where the normal line intersects the left map border |
123 let iyl = (map_box.left() - mid_point.x) * p.y / p.x + mid_point.y; |
121 let left_intersection = Point::new( |
124 let dl = Point::new(mid_point.x - map_box.left(), mid_point.y - iyl).integral_norm(); |
122 map_box.left(), |
125 let t = p.dot(mid_point - Point::new(full_box.left(), iyl)); |
123 (map_box.left() - mid_point.x) * p.y / p.x + mid_point.y); |
126 |
124 dist_left = (mid_point - left_intersection).integral_norm(); |
127 if t > 0 { |
125 |
128 dist_left = dl; |
126 // same for the right border |
129 } else { |
127 let right_intersection = Point::new( |
130 dist_right = dl; |
128 map_box.right(), |
131 } |
129 (map_box.right() - mid_point.x) * p.y / p.x + mid_point.y); |
132 |
130 dist_right = (mid_point - right_intersection).integral_norm(); |
133 // right border |
131 |
134 let iyr = (map_box.right() - mid_point.x) * p.y / p.x + mid_point.y; |
132 if p.dot(mid_point - left_intersection) < 0 { |
135 let dr = Point::new(mid_point.x - full_box.right(), mid_point.y - iyr).integral_norm(); |
133 std::mem::swap(&mut dist_left, &mut dist_right); |
136 |
|
137 if t > 0 { |
|
138 dist_right = dr; |
|
139 } else { |
|
140 dist_left = dr; |
|
141 } |
134 } |
142 } |
135 } |
143 |
136 |
144 if p.y != 0 { |
137 if p.y != 0 { |
145 // top border |
138 // where the normal line intersects the top map border |
146 let ixl = (map_box.top() - mid_point.y) * p.x / p.y + mid_point.x; |
139 let top_intersection = Point::new( |
147 let dl = Point::new(mid_point.y - map_box.top(), mid_point.x - ixl).integral_norm(); |
140 (map_box.top() - mid_point.y) * p.x / p.y + mid_point.x, |
148 let t = p.dot(mid_point - Point::new(ixl, full_box.top())); |
141 map_box.top()); |
149 |
142 let dl = (mid_point - top_intersection).integral_norm(); |
150 if t > 0 { |
143 |
|
144 // same for the bottom border |
|
145 let bottom_intersection = Point::new( |
|
146 (map_box.bottom() - mid_point.y) * p.x / p.y + mid_point.x, |
|
147 map_box.bottom()); |
|
148 let dr = (mid_point - bottom_intersection).integral_norm(); |
|
149 |
|
150 if p.dot(mid_point - top_intersection) > 0 { |
151 dist_left = min(dist_left, dl); |
151 dist_left = min(dist_left, dl); |
152 } else { |
|
153 dist_right = min(dist_right, dl); |
|
154 } |
|
155 |
|
156 // bottom border |
|
157 let ixr = (map_box.bottom() - mid_point.y) * p.x / p.y + mid_point.x; |
|
158 let dr = Point::new(mid_point.y - full_box.bottom(), mid_point.x - ixr).integral_norm(); |
|
159 |
|
160 if t > 0 { |
|
161 dist_right = min(dist_right, dr); |
152 dist_right = min(dist_right, dr); |
162 } else { |
153 } else { |
163 dist_left = min(dist_left, dr); |
154 dist_left = min(dist_left, dr); |
|
155 dist_right = min(dist_right, dl); |
164 } |
156 } |
165 } |
157 } |
166 |
158 |
167 // now go through all other segments |
159 // now go through all other segments |
168 for s in self.segments_iter() { |
160 for s in self.segments_iter() { |