This (from the PDL::Dataflow doc, not yet updated to CPAN) is a complete, working example that demonstrates the use of enduring flowing relationships to model 3D entities, through a few transformations:
{package PDL::3Space; use PDL; sub new { my ($class, $parent) = @_; my $self = bless {basis_local=>identity(3), origin_local=>zeroes(3)} +, $class; if (defined $parent) { $self->{parent} = $parent; $self->{basis} = $self->{basis_local}->flowing x $parent->{basis}- +>flowing; $self->{origin} = ($self->{origin_local}->flowing x $self->{basis} +->flowing)->flowing + $parent->{origin}->flowing; } else { $self->{basis} = $self->{basis_local}; $self->{origin} = $self->{origin_local}->flowing x $self->{basis}- +>flowing; } $self; } use overload '""' => sub {$_[0]{basis}->glue(1,$_[0]{origin}).''}; sub basis_update { $_[0]{basis_local} .= $_[1] x $_[0]{basis_local} } sub origin_move { $_[0]{origin_local} += $_[1] } sub local { my $local = PDL::3Space->new; $local->{$_} .= $_[0]{$_} fo +r qw(basis_local origin_local); $local} }
This is the class, heavily inspired by Math::3Space, and following discussions on interoperation between that and PDL (see https://github.com/nrdvana/perl-Math-3Space/pull/8). The basis and origin members are "subscribed" to both their own local basis and origin, and their parent's if any. The basis_update and origin_move methods only update the local members, both in terms of previous values.

The demonstrating code has a boat, and a bird within its frame of reference. Note that the "local" origin still gets affected by its local basis.

The basis and origin are always in global coordinates, and thanks to dataflow, are only recalculated on demand.

$rot_90_about_z = PDL->pdl([0,1,0], [-1,0,0], [0,0,1]); $boat = PDL::3Space->new; print "boat=$boat"; $bird = PDL::3Space->new($boat); print "bird=$bird"; # boat= # [ # [1 0 0] # [0 1 0] # [0 0 1] # [0 0 0] # ] # bird= # [ # [1 0 0] # [0 1 0] # [0 0 1] # [0 0 0] # ] $boat->basis_update($rot_90_about_z); print "after boat rot:\nboat=$boat"; print "bird=$bird"; # after boat rot: # boat= # [ # [ 0 1 0] # [-1 0 0] # [ 0 0 1] # [ 0 0 0] # ] # bird= # [ # [ 0 1 0] # [-1 0 0] # [ 0 0 1] # [ 0 0 0] # ] $boat->origin_move(PDL->pdl(1,0,0)); print "after boat move:\nboat=$boat"; print "bird=$bird"; print "bird local=".$bird->local; # after boat move: # boat= # [ # [ 0 1 0] # [-1 0 0] # [ 0 0 1] # [ 0 1 0] # ] # bird= # [ # [ 0 1 0] # [-1 0 0] # [ 0 0 1] # [ 0 1 0] # ] # bird local= # [ # [1 0 0] # [0 1 0] # [0 0 1] # [0 0 0] # ] $bird->basis_update($rot_90_about_z); $bird->origin_move(PDL->pdl(1,0,1)); print "after bird rot and move:\nbird=$bird"; print "bird local=".$bird->local; # after bird rot and move: # bird= # [ # [-1 0 0] # [ 0 -1 0] # [ 0 0 1] # [-1 1 1] # ] # bird local= # [ # [ 0 1 0] # [-1 0 0] # [ 0 0 1] # [ 0 1 1] # ] $boat->basis_update(PDL::MatrixOps::identity(3) * 2); print "after boat expand:\nboat=$boat"; print "bird=$bird"; # after boat expand: # boat= # [ # [ 0 2 0] # [-2 0 0] # [ 0 0 2] # [ 0 2 0] # ] # bird= # [ # [-2 0 0] # [ 0 -2 0] # [ 0 0 2] # [-2 2 2] # ]

In reply to Example of PDL dataflow to implement 3D space calculations by etj

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.