lib/beziertools.rb in xrvg-0.0.5 vs lib/beziertools.rb in xrvg-0.0.6

- old
+ new

@@ -61,11 +61,34 @@ return result end end +# +# Interpolation extension with SimpleBezier +# +module Interpolation + def compute_simplebezier + points = self.samplelist.foreach(2).map { |index, value| V2D[index,value] } + @simplebezier = SimpleBezier[ :support, points ] + end + + def getcurve + if not @simplebezier + self.compute_simplebezier + end + return @simplebezier + end + + def simplebezier( dindex ) + return self.getcurve.sample( dindex ).y + end + +end + + # = Offset bezier builder # == Content # Generic offset bezier builder. # == Attributes # attribute :support, nil, Curve @@ -177,32 +200,43 @@ attribute :support, nil, Curve attribute :ampl, 0.5, :samplable attribute :abscissasampler, (0.0..1.0), Samplable attribute :freq, 10 + # atomic pattern computation + # + def compute_arc( abs1, abs2, amplitude, sens ) + mabs = (abs1 + abs2)/2.0 + p1, halfpoint, p2 = self.support.points( [abs1, mabs, abs2] ) + # Trace("mabs #{mabs} abs1 #{abs1} abs2 #{abs2} halfpoint #{halfpoint.inspect} p1 #{p1.inspect} p2 #{p2.inspect}") + # Trace("normal #{@support.normal( mabs )}") + halfnormal = self.support.normal( mabs ).norm * ( sens * amplitude * (p2 - p1).length) + # Trace("halfnormal #{halfnormal.inspect}") + newpoint = halfpoint + halfnormal + tpoint = halfpoint + halfnormal * 3.0 + t1 = (tpoint - p1 ) / 6.0 + t2 = (tpoint - p2 ) / 6.0 + # Trace("newpoint #{newpoint.inspect} p1 #{p1.inspect} (newpoint - p1) #{(newpoint - p1).inspect}") + halftangent = self.support.tangent( mabs ).norm * (newpoint - p1).length / 3.0 + # halftangent = self.support.tangent( mabs ).norm * (p2 - p1).length / 3.0 + return [[:vector, p1, t1, newpoint, -halftangent], [:vector, newpoint, halftangent, p2, t2]] + end + def compute_interpol( abs1, abs2, amplitude, sens ) + arc = Bezier.multi( self.compute_arc( abs1, abs2, 1.0, sens ) ) + subsupport = self.support.subbezier( abs1, abs2 ) + return InterBezier[ :bezierlist, [0.0, subsupport, 1.0, arc] ].sample( amplitude ).data + end + # algo : for each abscissa, 0.0 of the curve (given the normal) # and for each mean abscissa, :amp normal def compute abscissas = self.abscissasampler.samples( self.freq + 1 ) sens = 1.0 pieces = [] [abscissas.pairs, self.ampl.samples( self.freq )].forzip do |abspair, amplitude| abs1, abs2 = abspair - mabs = (abs1 + abs2)/2.0 - p1, halfpoint, p2 = self.support.points( [abs1, mabs, abs2] ) - # Trace("mabs #{mabs} abs1 #{abs1} abs2 #{abs2} halfpoint #{halfpoint.inspect} p1 #{p1.inspect} p2 #{p2.inspect}") - # Trace("normal #{@support.normal( mabs )}") - halfnormal = self.support.normal( mabs ).norm * ( sens * amplitude * (p2 - p1).length) - # Trace("halfnormal #{halfnormal.inspect}") - newpoint = halfpoint + halfnormal - tpoint = halfpoint + halfnormal * 3.0 - t1 = (tpoint - p1 ) / 6.0 - t2 = (tpoint - p2 ) / 6.0 - # Trace("newpoint #{newpoint.inspect} p1 #{p1.inspect} (newpoint - p1) #{(newpoint - p1).inspect}") - halftangent = self.support.tangent( mabs ).norm * (newpoint - p1).length / 3.0 - # halftangent = self.support.tangent( mabs ).norm * (p2 - p1).length / 3.0 - pieces += [[:vector, p1, t1, newpoint, -halftangent], [:vector, newpoint, halftangent, p2, t2]] + pieces += self.compute_interpol( abs1, abs2, amplitude, sens ) sens *= -1.0 end return pieces end end