From: Breno G. de Oliveira Date: Sun, 4 Oct 2009 06:04:40 +0000 (-0300) Subject: implemented clip and clip_ip X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=74f8c25924136abe11d4214453b89e227511ba09;hp=57f262e845da701522b91e477ba7c819c0b90da6;p=sdlgit%2FSDL_perl.git implemented clip and clip_ip --- diff --git a/lib/SDL/Game/Rect.pm b/lib/SDL/Game/Rect.pm index 95332df..274c4b8 100644 --- a/lib/SDL/Game/Rect.pm +++ b/lib/SDL/Game/Rect.pm @@ -324,6 +324,93 @@ sub clamp_ip { return; } +sub _get_intersection_coordinates { + my ($self, $rect) = (@_); + my ($x, $y, $w, $h); + +INTERSECTION: + { + ### Left + if (($self->x >= $rect->x) && ($self->x < ($rect->x + $rect->w))) { + $x = $self->x; + } + elsif (($rect->x >= $self->x) && ($rect->x < ($self->x + $self->w))) { + $x = $rect->x; + } + else { + last INTERSECTION; + } + + ## Right + if ((($self->x + $self->w) > $rect->x) && (($self->x + $self->w) <= ($rect->x + $rect->w))) { + $w = ($self->x + $self->w) - $x; + } + elsif ((($rect->x + $rect->w) > $self->x) && (($rect->x + $rect->w) <= ($self->x + $self->w))) { + $w = ($rect->x + $rect->w) - $x; + } + else { + last INTERSECTION; + } + + ## Top + if (($self->y >= $rect->y) && ($self->y < ($rect->y + $rect->h))) { + $y = $self->y; + } + elsif (($rect->y >= $self->y) && ($rect->y < ($self->y + $self->h))) { + $y = $rect->y; + } + else { + last INTERSECTION; + } + + ## Bottom + if ((($self->y + $self->h) > $rect->y) && (($self->y + $self->h) <= ($rect->y + $rect->h))) { + $h = ($self->y + $self->h) - $y; + } + elsif ((($rect->y + $rect->h) > $self->y) && (($rect->y + $rect->h) <= ($self->y + $self->h))) { + $h = ($rect->y + $rect->h) - $y; + } + else { + last INTERSECTION; + } + + return ($x, $y, $w, $h); + } + + # if we got here, the two rects do not intersect + return ($self->x, $self->y, 0, 0); + +} + +sub clip { + my ($self, $rect) = (@_); + + unless ($rect->isa('SDL::Rect')) { + croak "must receive an SDL::Rect-based object"; + } + + my ($x, $y, $w, $h) = _get_intersection_coordinates($self, $rect); + + return $self->new($x, $y, $w, $h); +} + +sub clip_ip { + my ($self, $rect) = (@_); + + unless ($rect->isa('SDL::Rect')) { + croak "must receive an SDL::Rect-based object"; + } + + my ($x, $y, $w, $h) = _get_intersection_coordinates($self, $rect); + + $self->x($x); + $self->y($y); + $self->w($w); + $self->h($h); + + return; +} + 42; __END__ @@ -443,11 +530,11 @@ Same as C<> above, but moves the current Rect in place and returns nothin =head3 clip($rect) -Returns a new Rect with the intersection between the two Rect objects, that is, returns a new Rect cropped to be completely inside the Rect object passed as an argument. If the two rectangles do not overlap to begin with, a Rect with 0 size is returned. +Returns a new Rect with the intersection between the two Rect objects, that is, returns a new Rect cropped to be completely inside the Rect object passed as an argument. If the two rectangles do not overlap to begin with, a Rect with 0 size is returned, in the original Rect's (x,y) coordinates. =head3 clip_ip($rect) -Same as C<> above, but crops the current Rect in place and returns nothing. As the original method, the Rect becomes zero-sized if the two rectangles do not overlap to begin with. +Same as C<> above, but crops the current Rect in place and returns nothing. As the original method, the Rect becomes zero-sized if the two rectangles do not overlap to begin with, retaining its (x, y) coordinates. =head3 union($rect)