Class: FlameChannelParser::Segments::HermiteSegment

Inherits:
LinearSegment show all
Defined in:
lib/segments.rb

Overview

This segment does Hermite interpolation using the Flame algo.

Constant Summary collapse

HERMATRIX =

In Ruby matrix columns are arrays, so here we go

Matrix[
  [2,  -3,   0,  1],
  [-2,  3,   0,  0],
  [1,   -2,  1,  0],
  [1,   -1,  0,  0]
].transpose

Constants inherited from ConstantSegment

ConstantSegment::NEG_INF, ConstantSegment::POS_INF

Instance Attribute Summary

Attributes inherited from ConstantSegment

#end_frame, #start_frame

Instance Method Summary collapse

Methods inherited from ConstantSegment

#defines?

Constructor Details

#initialize(from_frame, to_frame, value1, value2, tangent1, tangent2) ⇒ HermiteSegment

Returns a new instance of HermiteSegment.



57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/segments.rb', line 57

def initialize(from_frame, to_frame, value1, value2, tangent1, tangent2)
  
  @start_frame, @end_frame = from_frame, to_frame
  
  frame_interval = (@end_frame - @start_frame)
  
  # Default tangents in flame are 0, so when we do nil.to_f this is what we will get
  # CC = {P1, P2, T1, T2}
  p1, p2, t1, t2 = value1, value2, tangent1.to_f * frame_interval, tangent2.to_f * frame_interval
  @hermite = Vector[p1, p2, t1, t2]
  @basis = HERMATRIX * @hermite
end

Instance Method Details

#value_at(frame) ⇒ Object

P = S.h.CC where s is 0..1 float interpolant on T (interval)



71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/segments.rb', line 71

def value_at(frame)
  return @hermite[0] if frame == @start_frame
  
  # Get the 0 < T < 1 interval we will interpolate on
  # Q[frame_] = P[ ( frame - 149 ) / (time_to - time_from)]
  t = (frame - @start_frame).to_f / (@end_frame - @start_frame)

  # S[s_] = {s^3, s^2, s^1, s^0}
  multipliers_vec = Vector[t ** 3,  t ** 2, t ** 1, t ** 0]

  # P[s_] = S[s].h.CC --> Kaboom!
  interpolated_scalar = dot_product(@basis, multipliers_vec)
end