Math-Zap

 view release on metacpan or  search on metacpan

lib/Math/Zap/Triangle2.pm  view on Meta::CPAN

Check whether triangle T is completely contained within triangle t.                                   

=cut


sub contains($$)
 {my ($t, $T) = @_; 
  check(@_) if debug; # Triangles

  return 1 if $t->containsPoint($T->a) and
              $t->containsPoint($T->b) and
              $t->containsPoint($T->c);   
  0;
 }


=head3 pointsInCommon

Find points in common to two triangles.  A point in common is a point
on the border of one triangle touched by the border of the other
triangle.

=cut


sub pointsInCommon($$)
 {my ($t, $T) = @_; 
  check(@_) if debug; # Triangles

  return ($T->a, $T->b, $T->c) if $t->contains($T);
  return ($t->a, $t->b, $t->c) if $T->contains($t);

  my @p = ();
  push @p, $t->a if $T->containsPoint($t->a);  
  push @p, $t->b if $T->containsPoint($t->b);  
  push @p, $t->c if $T->containsPoint($t->c);

  push @p, $T->a if $t->containsPoint($T->a);  
  push @p, $T->b if $t->containsPoint($T->b);  
  push @p, $T->c if $t->containsPoint($T->c);
  
  push @p, $t->lab->intersect($T->lab) if $t->lab->crossOver($T->lab); 
  push @p, $t->lab->intersect($T->lac) if $t->lab->crossOver($T->lac); 
  push @p, $t->lab->intersect($T->lbc) if $t->lab->crossOver($T->lbc); 
  push @p, $t->lac->intersect($T->lab) if $t->lac->crossOver($T->lab); 
  push @p, $t->lac->intersect($T->lac) if $t->lac->crossOver($T->lac); 
  push @p, $t->lac->intersect($T->lbc) if $t->lac->crossOver($T->lbc);
  push @p, $t->lbc->intersect($T->lab) if $t->lbc->crossOver($T->lab); 
  push @p, $t->lbc->intersect($T->lac) if $t->lbc->crossOver($T->lac); 
  push @p, $t->lbc->intersect($T->lbc) if $t->lbc->crossOver($T->lbc);

# Remove duplicate points caused by splitting the vertices - inefficient and unreliable
  my %p;
  $p{"$_"}=$_ for(@p);
  values(%p); 
 }


=head3 ring

Ring of points formed by overlaying triangle t and T

=cut


sub ring($$)
 {my ($t, $T) = @_; 
  check(@_) if debug; # Triangles

  my @p = $t->pointsInCommon($T);
# scalar(@p) == 1 and warn "Only one point in common";
# scalar(@p) == 2 and warn "Only two points in common";
  return () unless scalar(@p) > 2;

# Find center
  my $c = vector2(0,0);
  $c += $_ for(@p);
  $c /= scalar(@p);

# Split by y coord   
  my (@yp, @yn);
  for my $p(0..@p-1)
   {return () if ($p[$p]-$c)->length < $accuracy;
    if (($p[$p]-$c)->y >= 0)
     {push @yp, $p;
     }
    else
     {push @yn, $p;
     }
   }

  @yp = sort {($p[$a]-$c)->norm->x <=> ($p[$b]-$c)->norm->x} @yp;
  @yn = sort {($p[$b]-$c)->norm->x <=> ($p[$a]-$c)->norm->x} @yn;

  my @a;
  push @a, $p[$_] for(@yp);
  push @a, $p[$_] for(@yn);
  @a;
 }


=head3 convertPlaneToSpace

Convert plane to space coordinates                                   

=cut


sub convertPlaneToSpace($$)
 {my ($t, $p) = @_;                               
           check(@_[0..0]) if debug; # Triangle  
  vector2Check(@_[1..1]) if debug; # Vector in plane
   
  $t->a + ($p->x * $t->ab) + ($p->y * $t->ac);
 }


=head3 split

Split a triangle into 4 sub triangles unless the sub triangles would
be too small



( run in 1.526 second using v1.01-cache-2.11-cpan-39bf76dae61 )