| 223 | } |
| 224 | |
| 225 | fn write<W>(&self, writer: &mut W) -> eyre::Result<()> |
| 226 | where |
| 227 | W: std::io::Write, |
| 228 | { |
| 229 | let min_i = self.x2i(self.min_x); |
| 230 | let max_i = self.x2i(self.max_x); |
| 231 | let min_j = self.y2j(self.min_y); |
| 232 | let max_j = self.y2j(self.max_y); |
| 233 | |
| 234 | let is = min_i..=max_i; |
| 235 | let js = min_j..=max_j; |
| 236 | let vectors = js.flat_map(|j| { |
| 237 | is.clone().map(move |i| { |
| 238 | let x1 = self.i2x(i); |
| 239 | let y1 = self.j2y(j); |
| 240 | |
| 241 | let vector = (self.function)(x1, y1); |
| 242 | |
| 243 | // Vector field visualizations don't look good if the vectors use the same scale as the |
| 244 | // uniform grid they're drawn on. So we scale by the delta-h. |
| 245 | let dx = vector.0 * self.stride; |
| 246 | let dy = vector.1 * self.stride; |
| 247 | |
| 248 | let x2 = x1 + dx; |
| 249 | let y2 = y1 + dy; |
| 250 | |
| 251 | let line = Line::new(Coord { x: x1, y: y1 }, Coord { x: x2, y: y2 }); |
| 252 | Geometry::Line(line) |
| 253 | }) |
| 254 | }); |
| 255 | |
| 256 | write_geometries(writer, vectors) |
| 257 | } |
| 258 | } |
| 259 | |
| 260 | #[allow(clippy::too_many_arguments)] |