Ok. I'm not asking for a plssendcodezkthx. But I am somewhat new to FP and I'm trying to figure out how to do this, because I know the code I have won't accomplish what I'd like to achieve. So all arguments about optimization aside, here is my code Then I'll explain.
let moveBoids boids =
boids |> List.map (fun(boid) ->
let others = List.filter (fun(b) -> b.Id <> boid.Id) boids
let positions = others |> List.map(fun(b2) -> b2.Position)
let velocities = others |> List.map(fun(b3) -> b3.Velocity)
let c = centerWithFlock (boid, positions)
let d = distanceFromFlock (boid, positions)
let v = matchVelocityWithFlock (boid, velocities)
let v2 = List.fold_right (addVector) [c; d; v] {X=0.; Y=0.; Z=0.}
let p = addVector boid.Position v2
{boid with Position=p; Velocity=v2})
I'm trying to map my list of boids to a new list of boids. Sounds easy, except I'm pretty sure if I run this, each boid will only change according to the original list, not to the list as each boid updates itself. How the hell can I do that using a map style call? Should I not even be using a map style call? I know my function is closed over my boids list, so how can I pass the updated list to the next call?
Word.
-
I think this may fix it..
let rec foo boids newboids = match boids with | h :: t -> let others = List.filter (fun(b) -> b.Id <> h.Id) newboids let positions = others |> List.map(fun(b2) -> b2.Position) let velocities = others |> List.map(fun(b3) -> b3.Velocity) let c = centerWithFlock (h, positions) let d = distanceFromFlock (h, positions) let v = matchVelocityWithFlock (h, velocities) let v2 = List.fold_right (addVector) [c; d; v] {X=0.; Y=0.; Z=0.} let p = addVector h.Position v2 let list = [{h with Position=p; Velocity=v2}] @ others foo t list | [] -> newboids -
Yeah, a map does not seems too good for this... you can do it with a fold (where you accumulate the 'news' as you process the 'olds' and compute 'others' as 'news' + non-me 'olds') or you could covert to an array and use a loop to in-place update (and then convert back to a list when done if needed).
-
Hi Nicholas,
that's an interesting problem - the solution you posted looks good, but I was just wondering (aside question) why do you need to take into account previous changes during the processing? Even with this behavior, the first boid in the list will not reflect changes done later in the processing...
Does it make a big difference whether the calculation uses the updated state instead of the original?
Thanks, T.
Nicholas Mancuso : the head of "list" is the updated boid for each iteration, no? So this would reflection that? I'm trying to doing the "Boids" simulation in F# and WPF. All three are new to me, and it sounded like fun. But I would imagine if each boid only remapped itself to old data, instead of as its updated...Nicholas Mancuso : then it wouldn't have proper flocking emerge.Tomas Petricek : Hmm, it can probably make a difference, but I'm still not completely sure. It would be interesting to try that after you'll have the example running!
0 comments:
Post a Comment