diff src/laser/rasterize.clj @ 19:3b255dcd6c50

getting closer
author Robert McIntyre <rlm@mit.edu>
date Mon, 30 Aug 2010 00:09:06 -0400
parents 962e223bab0d
children 6bed8ceb51a9
line wrap: on
line diff
     1.1 --- a/src/laser/rasterize.clj	Sun Aug 29 23:44:59 2010 -0400
     1.2 +++ b/src/laser/rasterize.clj	Mon Aug 30 00:09:06 2010 -0400
     1.3 @@ -3,11 +3,9 @@
     1.4  	 image-utils
     1.5  	 map-utils]
     1.6  	[clojure.contrib
     1.7 -	 [str-utils :only [str-join re-gsub]]
     1.8 +	 [str-utils :only [str-join re-gsub re-split]]
     1.9  	 [seq :only [indexed]]
    1.10 -	 [math]
    1.11 -	 [def]
    1.12 -	 ])
    1.13 +	 [math]])
    1.14    (:import [ij ImagePlus IJ]))
    1.15  
    1.16  ;(import '(java.io File))
    1.17 @@ -18,8 +16,7 @@
    1.18  (set! *print-length* 20)
    1.19  (def feed 120)
    1.20  (def  dpi [500, 500])
    1.21 -
    1.22 -(def paramaters {:x-dpi 500 :y-dpi 500 :margin 0 :x-offset 0 :y-offset 0})
    1.23 +(def paramaters {:x-dpi 500 :y-dpi 500 :margin 0 :x-offset 1 :y-offset 1})
    1.24  
    1.25  ;;; this process is divided into two tasks,
    1.26  ;;; creating the raster g-code, which sweeps back and forth
    1.27 @@ -28,19 +25,12 @@
    1.28  
    1.29  ;;; we'll be using frame-hashes, which represent picutres as
    1.30  ;;; a 3D vector field over 2D space, with the vectors representing
    1.31 -;;; the rgb values at that particular point. 
    1.32 +;;; the rgb values at that particulat point. 
    1.33  
    1.34  (defn select-row
    1.35    "returns a frame hash that is just a single line at the chosen y"
    1.36    [y window]
    1.37 -  (reduce  
    1.38 -   (fn [old-map number]
    1.39 -     (let [pixel (get window [number y] nil)]
    1.40 -       (if-not (nil? pixel)
    1.41 -	 (into old-map {[number y] pixel})
    1.42 -	 old-map)))
    1.43 -   {}
    1.44 -   (range (width window))))
    1.45 +  (filter-keys (comp (partial = y) last) window))
    1.46  
    1.47  (defn make-rows [pic]
    1.48    (map (partial sort #(< (first %1) (first %2)))
    1.49 @@ -48,80 +38,66 @@
    1.50  		     (sort (fn [[x1 y1][x2 y2]] (> y2 y1))
    1.51  			   (map first (filter-vals (partial = black) pic))))))
    1.52  
    1.53 +
    1.54  ;;; generate rastering g-code
    1.55  
    1.56  (defn raster-preamble []
    1.57 -  (str-join \newline ["M63 P0\nG61" (str "F" feed) "M101" "M3 S1\n"]))
    1.58 +  (str-join \newline
    1.59 +	    ["M63 P0\nG61"
    1.60 +	    (str "F" feed)
    1.61 +	    "M101"
    1.62 +	    "M3 S1\n"]))
    1.63  
    1.64  (defn raster-epilogue []
    1.65 -  (str-join \newline ["M63 P0" "M5" "M2\n"]))
    1.66 +  (str-join \newline
    1.67 +	    ["M63 P0"
    1.68 +	     "M5"
    1.69 +	     "M2\n"]))
    1.70  
    1.71 -(defn raster-comment
    1.72 -  "wrap a statement in PARENTHENSIS to make it a comment in gcode.
    1.73 -   parenthesis themselves aren't allowed in comments.
    1.74 -   Oh the humanity!!"
    1.75 -  [string]
    1.76 +(defn raster-comment [string]
    1.77    (str "(" (re-gsub #"[()]" "" string) ")"))
    1.78  
    1.79 -(defn rows
    1.80 -  "creates a sequence of one dimensional vector fields which
    1.81 -   represent the rows of a picture"
    1.82 -  [pic]
    1.83 -  (let [non-empty-rows (apply sorted-set (map (comp last first) pic))]
    1.84 -    (pmap (fn [n] (select-row n pic)) non-empty-rows)))
    1.85 -    
    1.86 +
    1.87 +;this is a sequence of rows
    1.88 +
    1.89 +;(defn span [row]
    1.90 +;  (let [sorted-row (sort #(< (first %1) (first %2)) row)]
    1.91 +;    (vector (first sorted-row) (last sorted-row))))
    1.92 +
    1.93 +
    1.94 +
    1.95 +(defn row->gcode [{:keys [x-dpi y-dpi margin x-offset y-offset]} forward? row]
    1.96    
    1.97 +  (let [[x1 y1] (if forward? (last row) (first row))
    1.98 +	[x2 y2] (if forward? (first row) (last row))]
    1.99  
   1.100 +    (let [x1 (* x1 (/ x-dpi))
   1.101 +	  x2 (* x2 (/ x-dpi))
   1.102 +	  y1 (* y1 (/ y-dpi))
   1.103 +	  y2  (* y2(/ y-dpi))]
   1.104  
   1.105 -
   1.106 -(defn row->gcode [{:keys [x-dpi y-dpi margin x-offset y-offset]} row]
   1.107 -  (let [pixels (keys row)
   1.108 -	x2 0
   1.109 -	[_ y2] (first pixels)
   1.110 -	[_ y1] (first pixels)
   1.111 -	x1 533]
   1.112 -
   1.113 -					;(let [ordered-row
   1.114 -;	(sort-map-by (fn [[x1 _] [x2 _]] (> x2 x1)) row)]
   1.115 -    
   1.116 -    (let [;[x1 y1] (last (keys ordered-row))
   1.117 -	  ;[x2 y2] (first (keys ordered-row))
   1.118 -	  [x1 y1 x2 y2] (if (odd? y1) [x2 y2 x1 y1] [x1 y1 x2 y2])]
   1.119 -      
   1.120 +    (let [x1 (+ x1 x-offset)
   1.121 +	  x2 (+ x2 x-offset)
   1.122 +	  y1 (+ y1 y-offset)
   1.123 +	  y2 (+ y2 y-offset)]
   1.124 +	  
   1.125 +          
   1.126        (str (format "G0 X%.3f Y%.3f\n"
   1.127 -		   (float (* x1 (/ x-dpi)))
   1.128 -		   (float (* y1 (/ y-dpi))))
   1.129 +		   (float x1 )
   1.130 +		   (float  y1))
   1.131  	   
   1.132  	   (format "G1 X%.3f Y%.3f\n"
   1.133 -		   (float (* x2 (/ x-dpi)))
   1.134 -		   (float (* y2 (/ y-dpi))))))))
   1.135 -
   1.136 -
   1.137 -(defn pic->gcode [paramaters pic]
   1.138 -  (reduce (fn [gcode current-height]
   1.139 -	    (let [current-row (select-row current-height pic)]
   1.140 -	      (if-not (empty? current-row)
   1.141 -		(let [new-code (row->gcode paramaters current-row)] 
   1.142 -		  (println new-code)
   1.143 -		  (str gcode new-code))
   1.144 -		gcode)))
   1.145 -	  ""
   1.146 -	  (range (height pic))))
   1.147 -
   1.148 -
   1.149 -
   1.150 -
   1.151 -(defn pic->gcode 
   1.152 -
   1.153 -
   1.154 -
   1.155 -;(defn pic->gcode [paramaters pic]
   1.156 +		   (float x2)
   1.157 +		   (float y2)))))))
   1.158    
   1.159 -
   1.160  (defn generate-gcode [pic]
   1.161    (str (raster-preamble)
   1.162 -       (row->gcode paramaters pic)
   1.163 -       (raster-epilogue)))
   1.164 +       (str-join ""
   1.165 +		 (map
   1.166 +		  (fn [[index row]]
   1.167 +		    (row->gcode paramaters (even? index) row))
   1.168 +		    (indexed (make-rows pic))))
   1.169 +		 (raster-epilogue)))
   1.170  
   1.171  
   1.172  
   1.173 @@ -212,27 +188,22 @@
   1.174  
   1.175  (defn update-state []
   1.176    (def sing "/home/r/kevin/sing.png")
   1.177 -  (def pic (frame-hash (ImagePlus. sing)))  
   1.178 -  (def pic (b&w pic))
   1.179 -  (def pic (filter-vals (partial = black) pic)))
   1.180 +  (def pic (frame-hash (rotate 180 (ImagePlus. sing))))  
   1.181 +  (def pic (b&w pic)))
   1.182  
   1.183 -(defn compare-gen-fn
   1.184 -  ([n f cmp]
   1.185 +(defn compare-gen-fn [n f cmp]
   1.186    (let [theirs (re-split #"\n" (slurp cmp))
   1.187  	ours   (re-split #"\n" (f pic))]
   1.188      (println (format "%1$-25s%2$s" "OURS" "THEIRS"))
   1.189      (println "_______________________________________")
   1.190      (dorun (map (fn [[us them]] (println
   1.191  			     (format "%1$-25s%2$s" us them)))
   1.192 -			     (take n (partition 2 (interleave  ours theirs))))))))
   1.193 +			     (take n (partition 2 (interleave  ours theirs)))))))
   1.194  
   1.195 -(defn compare-gcode
   1.196 -  ([] (compare-gcode 25))
   1.197 -  ([n] (compare-gen-fn n generate-gcode "/home/r/kevin/reference.ngc")))
   1.198 -
   1.199 -(defn compare-gmask
   1.200 -  ([] compare-gmask 25)
   1.201 -  ([n]  (compare-gen-fn n generate-gmask "/home/r/kevin/reference.gmask")))
   1.202 +(defn compare-gcode [n]
   1.203 +  (compare-gen-fn n generate-gcode "/home/r/kevin/reference.ngc"))
   1.204 +(defn compare-gmask [n]
   1.205 +  (compare-gen-fn n generate-gmask "/home/r/kevin/reference.gmask"))
   1.206    
   1.207  
   1.208