module StraightSkeleton module Node attr_reader :point, :travel, :neighbours, :normals, :original def active? @nodes.include? self end def terminal? @neighbours.one? end def reflex? normals.inject(&:cross) * @nodes.direction <= 0 end def splits? terminal? || reflex? end def prev @neighbours[0] end def next @neighbours[1] end def index @index ||= @nodes.index self end # ########################################### # solve for vector p: # n0.(p - @point) = travel - @travel # n1.(p - @point) = travel - @travel # ########################################### def project(travel) det = normals.inject(&:cross) if normals.all? case when det&.nonzero? x = normals.map { |normal| travel - @travel + normal.dot(point) } (normals[0].perp * x[1] - normals[1].perp * x[0]) / det when normals[0] then normals[0] * (travel - @travel) + point when normals[1] then normals[1] * (travel - @travel) + point end end end end