 stations atop mountain peaks. Those stations helped firefighters to communicate by radio when they’re thick in the action – a key for safety.
Then firefighters used information gleaned from an airborne infrared camera to create a plan of attack.
Such cameras take large pictures of land tracts to document buildings, access roads or specific stands of trees. In some cases, airborne cameras have detected endangered species or precious stands of mesquite to be saved.
Some workers employed personal digital assistants to access reference guides on scene.
Boulder-based Pocket Mobility has developed software that stores safety guidelines, map scale conversions and fire behavior patterns in the hand-held devices.
In the past, operations managers had to page through stacks of books, reference papers and laptop computers to find the same data.
Using Pocket Mobility, field crews on the scene could input the temperature, slope, weather, time and surrounding fuels. The PDA predicted how fast and high the flames would move.
“It’s kind of like magic when you punch that in, and it comes up with numbers,” said John Covele, president of Pocket Mobility and a firefighter himself.
His company has 5,000 customers, and his software is used, he estimates, on every major wildland fire.
Dombrowski, who works alongside Covele in the Boulder Rural Fire Department, says he appreciates how technology speeds decisions. But what happens if a phone, radio or PDA fails?
Boulder Rural is among the Colorado departments that employs another uncommon, low-tech method to protect structures: triple-strength dishwashing soap mixed with water, or compressed air foam.
CAFS, as it is known, has been around since World War II. The British used it to protect floating wood bridges.
A thermal-imaging camera under the RAM Systems helicopter.
Despite its history, the technology has been slow to gain acceptance. Just 8 percent of new fire trucks come with CAFS equipment, and just 5 percent of city fire departments use it.
“There are times when the fire services says, ‘tradition, tradition, we’ve always done it this way,’ ” said Boulder Rural Fire Marshall Jeff Webb.
The foam can resemble marshmallows or shaving cream.
It works because detergent and air reduce water’s surface tension so it more efficiently attacks fires. While about 80 percent of plain water runs off, 80 percent of foam sticks to its target.
What’s more, the air that’s injected into the water allows it to spray 100 to 120 feet away – farther than undoctored water. Foam’s milky color deflects heat and cools the fire.
CAFS wasn’t used in the Mason Gulch Fire, but was employed two years ago to protect dozens of homes in Los Angeles that were threatened by Southern California wildfires.
 Personal digital assistant: Field crews on scene can input temperature, slope, weather, time and surrounding fuels, then receive a prediction of where the flames are headed.
 Compressed air foam systems: Detergent and air reduce water’s surface tension, so foam more efficiently attacks fires. It also sprays farther than water.<reponame>postspectacular/ws-ldn-10<filename>src/clj/ws_ldn_10/ex06.clj
(ns ws-ldn-10.ex06
  (:require
   [thi.ng.math.core :as m]
   [thi.ng.geom.core :as g]
   [thi.ng.geom.vector :as v]
   [thi.ng.geom.svg.core :as svg]
   [thi.ng.color.core :as col]))

(def default-rules
  {:fwd   [:fwd]
   :left  [:left]
   :right [:right]
   :push  [:push]
   :pop   [:pop]})

(def forward-aliases #{:a :b :c :d})

(def dragon-rules
  {:start [:a]
   :a     [:a :right :b :right]
   :b     [:left :a :left :b]})

(def gasket
  {:start [:fwd :left
           :fwd :left
           :fwd :left
           :fwd :left
           :fwd]
   :fwd   [:fwd :left
           :fwd :right :right :fwd :right
           :fwd :left :fwd :left :fwd]})

(def tree-rules
  {:start [:fwd
           :left
           :push :push :start :pop :right :start :pop
           :right
           :fwd
           :push :right :fwd :start :pop
           :left
           :start]
   :fwd   [:fwd :fwd]})

(def penrose
  {:start [:push :b :pop
           :left :left
           :push :b :pop
           :left :left
           :push :b :pop
           :left :left
           :push :b :pop
           :left :left
           :push :b :pop]
   :a     [:c :left :left :d :right :right :right :right :b
           :push :right :c :right :right :right :right :a :pop
           :left :left]
   :b     [:left :c :right :right :d
           :push :right :right :right :a :right :right :b :pop
           :left]
   :c     [:right :a :left :left :b
           :push :left :left :left :c :left :left :d :pop
           :right]
   :d     [:right :right :c :left :left :left :left :a
           :push :left :d :left :left :left :left :b :pop
           :right :right :b]})

(defn rewrite-symbols
  [rules symbols]
  (mapcat (merge default-rules rules) symbols))

(defn make-agent
  [pos theta length branch-theta]
  {:pos          pos
   :theta        theta
   :branch-theta branch-theta
   :length       length
   :path         []
   :stack        []})

(defn save-agent
  [agent]
  (-> agent
      (update :stack conj (dissoc agent :stack))
      (assoc :path [])))

(defn restore-agent
  [agent]
  {:pre [(pos? (count (:stack agent)))]}
  (let [agent' (peek (:stack agent))]
    (assoc agent'
           :stack (pop (:stack agent))
           :path  (into (:path agent') (:path agent)))))

(defmulti interpret
  (fn [agent sym & _] (if (forward-aliases sym) :fwd sym)))

(defmethod interpret :start
  [agent _]
  agent)

(defmethod interpret :fwd
  [agent _]
  (let [pos  (:pos agent)
        pos' (m/+ pos (g/as-cartesian
                       (v/vec2 (:length agent)
                               (:theta agent))))]
    (-> agent
        (assoc :pos pos')
        (update :path conj [pos pos' (count (:stack agent))]))))

(defmethod interpret :left
  [agent _]
  (update agent :theta - (:branch-theta agent)))

(defmethod interpret :right
  [agent _]
  (update agent :theta + (:branch-theta agent)))

(defmethod interpret :push
  [agent _]
  (save-agent agent))

(defmethod interpret :pop
  [agent _]
  (restore-agent agent))

(defmethod interpret :default
  [agent sym]
  #_(prn "no impl for symbol:" sym)
  agent)

(defn interpret-symbols
  [agent syms]
  (reduce interpret agent syms))

(defn visualize-agent
  [path agent]
  (->> agent
       :path
       (map-indexed
        (fn [i [a b depth]]
          (svg/line a b {:stroke (col/hsva (/ i (count (:path agent))) 1 1)})))
       (svg/svg {:width 1000 :height 1000})
       (svg/serialize)
       (spit path)))

(visualize-agent
 "lsys-dragon.svg"
 (interpret-symbols
  (make-agent (v/vec2 500 750) 0 5 m/HALF_PI)
  (last (take 16 (iterate (partial rewrite-symbols dragon-rules) [:start])))))

(visualize-agent
 "lsys-gasket.svg"
 (interpret-symbols
  (make-agent (v/vec2 500 100) 0 10 (m/radians 72))
  (last (take 6