Use iterators
This commit is contained in:
parent
f46196e903
commit
1faf395c34
|
|
@ -16,22 +16,27 @@ pub fn main() {
|
||||||
gc.canvas_height(1000.0);
|
gc.canvas_height(1000.0);
|
||||||
|
|
||||||
gc.new_path();
|
gc.new_path();
|
||||||
|
gc.circle(0.0, 0.0, space.coil_r + space.coil_w + space.coil_m);
|
||||||
gc.circle(0.0, 0.0, space.coil_r + space.coil_w);
|
gc.circle(0.0, 0.0, space.coil_r + space.coil_w);
|
||||||
gc.circle(0.0, 0.0, space.coil_r - space.coil_w);
|
gc.circle(0.0, 0.0, space.coil_r - space.coil_w);
|
||||||
gc.line_width(3.0);
|
gc.circle(0.0, 0.0, space.coil_r - space.coil_w - space.coil_m);
|
||||||
gc.stroke_color(Color::Rgba(0.8, 0.8, 0.8, 1.0));
|
gc.winding_rule(WindingRule::EvenOdd);
|
||||||
gc.stroke();
|
gc.fill_color(Color::Rgba(0.8, 0.8, 0.8, 1.0));
|
||||||
|
gc.fill();
|
||||||
|
|
||||||
gc.line_width(1.0);
|
gc.line_width(1.0);
|
||||||
gc.stroke_color(Color::Rgba(1.0, 0.5, 0.0, 1.0));
|
gc.stroke_color(Color::Rgba(1.0, 0.5, 0.0, 1.0));
|
||||||
for y in itertools_num::linspace(-1.0, 1.0, 101) {
|
for y in itertools_num::linspace(-1.0, 1.0, 101) {
|
||||||
let base = vec2(-500.0, 0.0);
|
let base = vec2(-500.0, 0.0);
|
||||||
let dir = vec2(1.0, y);
|
let dir = vec2(1.0, y);
|
||||||
let path = trace(&space, base, dir, 1000.0, 1.0);
|
let path = trace_iter(&space, base, dir, 1.0);
|
||||||
gc.new_path();
|
gc.new_path();
|
||||||
gc.move_to(base.x, base.y);
|
gc.move_to(base.x, base.y);
|
||||||
for pt in path {
|
for pt in path.take(10000) {
|
||||||
gc.line_to(pt.x, pt.y);
|
gc.line_to(pt.x, pt.y);
|
||||||
|
if any(greaterThan(abs(pt), Vec2::from_s(1000.0))) {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
gc.stroke();
|
gc.stroke();
|
||||||
}
|
}
|
||||||
|
|
@ -89,6 +94,24 @@ trait Metric {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct TraceIter<'a, M: Metric> {
|
||||||
|
space: &'a M,
|
||||||
|
p: Vec2,
|
||||||
|
v: Vec2,
|
||||||
|
dt: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, M: Metric> Iterator for TraceIter<'a, M> {
|
||||||
|
type Item = Vec2;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
let a: Vec2 = -convolute(krist(self.space, self.p), self.v);
|
||||||
|
self.v = self.v + a * self.dt;
|
||||||
|
self.p = self.p + self.v * self.dt;
|
||||||
|
Some(self.p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn trace(space: &impl Metric, base: Vec2, dir: Vec2, distance: f32, dt: f32) -> Vec<Vec2> {
|
fn trace(space: &impl Metric, base: Vec2, dir: Vec2, distance: f32, dt: f32) -> Vec<Vec2> {
|
||||||
let steps = floor(distance / dt) as usize;
|
let steps = floor(distance / dt) as usize;
|
||||||
let mut result = Vec::with_capacity(steps);
|
let mut result = Vec::with_capacity(steps);
|
||||||
|
|
@ -103,6 +126,32 @@ fn trace(space: &impl Metric, base: Vec2, dir: Vec2, distance: f32, dt: f32) ->
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn trace_iter<M: Metric>(space: &M, base: Vec2, dir: Vec2, dt: f32) -> TraceIter<M> {
|
||||||
|
TraceIter{
|
||||||
|
space: space,
|
||||||
|
p: base,
|
||||||
|
v: normalize(dir),
|
||||||
|
dt: dt,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn t_iter() {
|
||||||
|
let space = Coil {
|
||||||
|
coil_scale: 2.0,
|
||||||
|
coil_r: 300.0,
|
||||||
|
coil_w: 50.0,
|
||||||
|
coil_m: 10.0,
|
||||||
|
};
|
||||||
|
let base = vec2(-500.0, 0.0);
|
||||||
|
let dir = vec2(1.0, 0.3);
|
||||||
|
let dt = 1.0;
|
||||||
|
let steps = 1000;
|
||||||
|
let a = trace(&space, base, dir, dt * (steps as f32), dt);
|
||||||
|
let b: Vec<Vec2> = trace_iter(&space, base, dir, dt).take(steps).collect();
|
||||||
|
assert_eq!(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
fn krist(space: &impl Metric, pos: Vec2) -> Tens2 {
|
fn krist(space: &impl Metric, pos: Vec2) -> Tens2 {
|
||||||
// Γ^i_k_l = .5 * g^i^m * (g_m_k,l + g_m_l,k - g_k_l,m)
|
// Γ^i_k_l = .5 * g^i^m * (g_m_k,l + g_m_l,k - g_k_l,m)
|
||||||
let g = inverse(&space.metric(pos)); // с верхними индексами
|
let g = inverse(&space.metric(pos)); // с верхними индексами
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user