Class: Graph
- Inherits:
-
Object
- Object
- Graph
- Defined in:
- lib/graph.rb
Instance Attribute Summary collapse
-
#deltas ⇒ Object
Returns the value of attribute deltas.
-
#points ⇒ Object
Returns the value of attribute points.
Instance Method Summary collapse
-
#build_points ⇒ Object
build the points array we’ll use later on to draw the graph.
-
#build_timestamps ⇒ Object
build an array with all occuring timestamps.
-
#compute_deltas(hand, values, t = 0) ⇒ Object
compute deltas for plotting.
-
#compute_euler_angles(values) ⇒ Object
compute euler angles for plotting en.wikipedia.org/wiki/Euler_angles.
-
#fill_values ⇒ Object
fill values with parsed data.
-
#get_missing_values ⇒ Object
in case values are missing for timestamps (no tracker data), we’ll supply values.
-
#initialize(trial, deltas, hfrac, test = false) ⇒ Graph
constructor
A new instance of Graph.
Constructor Details
#initialize(trial, deltas, hfrac, test = false) ⇒ Graph
Returns a new instance of Graph.
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/graph.rb', line 16 def initialize trial,deltas,hfrac,test=false #deltas we will compute @deltas = deltas ilog "Will compute deltas for #{@deltas.inspect}." #in case the deltas are to small/big change this factor @delta_factor = 256 #in case the angles are to small/big change this factor @euler_factor = hfrac #this factor governs how many pixels the points are away from another @x_factor = 4 #get the data from the database parser = TrackerDataParser.new trial,test @data = parser.data #generate unique array with all occuring timestamps and prepare @values @timestamps = #fill values (deltas,etc.) @previous = {:left => NMatrix.float(4,4), :right => NMatrix.float(4,4)} fill_values #build the points array (this will be used later on to draw the graph) @points = build_points end |
Instance Attribute Details
#deltas ⇒ Object
Returns the value of attribute deltas.
14 15 16 |
# File 'lib/graph.rb', line 14 def deltas @deltas end |
#points ⇒ Object
Returns the value of attribute points.
14 15 16 |
# File 'lib/graph.rb', line 14 def points @points end |
Instance Method Details
#build_points ⇒ Object
build the points array we’ll use later on to draw the graph
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/graph.rb', line 140 def build_points @timestamps.each_index do |i| ts = @timestamps[i] #do the following for both hands [:left,:right].each do |h| #if tracker data are missing we substitute if @values.has_key? ts @values[ts][h] = get_missing_values if @values[ts][h].empty? end #set index and x position @values[ts][h][:i] = i x = i*@x_factor @values[ts][h][:x] = x #now we create a Qt::PointF.new(x,y) for each euler angle @values[ts][h][:euler].each do |name,a| #create Point, mirror hands on x axis and apply y-scaling y = 0 unless @values[ts][h][:blackout] y += @euler_factor-a[:value]*@euler_factor/Math::PI y *= -1.0 if h.eql? :left end #and add the point to the euler values @values[ts][h][:euler][name][:point] = Qt::PointF.new(x,y) end #now we create a Qt::PointF.new(x,y) for every delta type @values[ts][h][:deltas].each do |type,delta| #create Point, mirror hands on x axis and apply y-scaling y = delta[:value]*@delta_factor y *= -1.0 if h.eql? :left #and add the point to the delta values @values[ts][h][:deltas][type][:point] = Qt::PointF.new(x,y) end end end dlog "Processed #{@values.length} timestamps." points = @values.sort dlog "points array has #{points.length} entries." return points end |
#build_timestamps ⇒ Object
build an array with all occuring timestamps
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/graph.rb', line 39 def @values = {} tss = [] @data[:reference].each { |t,v| tss << t } @data[:left].each { |t,v| tss << t } @data[:right].each { |t,v| tss << t } dlog "tss count: #{tss.length}" = (tss.uniq).sort dlog "Unique timestamps: #{.length}" dlog "Unique timestamps first: #{.first}" #now preparing @values .each do |t| @values[t] = {:left => {}, :right => {}} end return end |
#compute_deltas(hand, values, t = 0) ⇒ Object
compute deltas for plotting
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/graph.rb', line 99 def compute_deltas hand,values,t=0 #we'll put the deltas in here ds = {} #get the matrix m = values[:relative] #to reduce computation time we only compute what's needed if @deltas.include? :simple #compute simple delta over the complete 4x4 matrix value = (m-@previous[hand]).abs.sum ds[:simple] = { :value => value } end if @deltas.include? :pos #compute simple delta over the position vector value = (m[3,0..2]-@previous[hand][3,0..2]).abs.sum ds[:pos] = { :value => value } end if @deltas.include? :rot #compute simple delta over the 3x3 rotation matrix value = (m[0..2,0..2]-@previous[hand][0..2,0..2]).abs.sum ds[:rot] = { :value => value } end if @deltas.include? :xrot #compute simple delta over the x-rotation axis vector value = (m[0,0..2]-@previous[hand][0,0..2]).abs.sum ds[:xrot] = { :value => value } end if @deltas.include? :yrot #compute simple delta over the y-rotation axis vector value = (m[1,0..2]-@previous[hand][1,0..2]).abs.sum ds[:yrot] = { :value => value } end if @deltas.include? :zrot #compute simple delta over the z-rotation axis vector value = (m[2,0..2]-@previous[hand][2,0..2]).abs.sum ds[:zrot] = { :value => value } end #and return the computed deltas return ds end |
#compute_euler_angles(values) ⇒ Object
compute euler angles for plotting en.wikipedia.org/wiki/Euler_angles
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/graph.rb', line 82 def compute_euler_angles values #we'll put the angles in here e = {} #get the hand matrix m = values[:relative] #alpha = atan2(-Z2, Z1) e[:alpha] = { :value => Math.atan2(-1.0*m[2,1],m[2,0]) } #beta = atan2(Z3, sqrt(Z1^2+Z2^2)) e[:beta] = { :value => Math.atan2(m[2,2],Math.sqrt(m[2,0]**2+m[2,1]**2)) } #gamma = -atan2(Y3,-X3) if Z3 < 0 e[:gamma] = { :value => -1.0*Math.atan2(m[1,2],-1.0*m[0,2]) } if m[2,2] <= 0.0 #gamma = atan2(Y3,X3) if Z3 > 0 e[:gamma] = { :value => Math.atan2(m[1,2],m[0,2]) } if m[2,2] > 0.0 return e end |
#fill_values ⇒ Object
fill values with parsed data
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/graph.rb', line 57 def fill_values [:left,:right].each do |hand| dlog "Data for #{hand.inspect} has #{@data[hand].length} entries." #it's crucial to do sort here, otherwise the timestamps are mixed up @data[hand].sort.each do |t,v| wlog "Empty or nil value hash!" if v.nil? or v.empty? #we have tracker data v[:blackout] = false #will only happen the first time @previous[hand] = v[:relative] if @previous[hand].abs.sum == 0.0 #compute euler angles v[:euler] = compute_euler_angles(v) #compute deltas for plotting v[:deltas] = compute_deltas(hand,v) #for next delta computation @previous[hand] = v[:relative] #put values into @values @values[t][hand] = v end end dlog "Processed #{@values.length} values." end |
#get_missing_values ⇒ Object
in case values are missing for timestamps (no tracker data), we’ll supply values
181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/graph.rb', line 181 def get_missing_values #we'll put the deltas in here missing_deltas = {} #put 0.0 to deltas @deltas.each { |d| missing_deltas[d] = { :value => 0.0 } } #we'll put the euler angles in here missing_euler = {} #put 0.0 to euler angles [:alpha,:beta,:gamma].each { |a| missing_euler[a] = { :value => 0.0 } } #and build the values array v = { :deltas => missing_deltas, :euler => missing_euler, :blackout => true } return v end |