File: Surface.pm

package info (click to toggle)
libmath-polygon-perl 2.00-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 256 kB
  • sloc: perl: 1,618; makefile: 2
file content (125 lines) | stat: -rw-r--r-- 2,660 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# This code is part of Perl distribution Math-Polygon version 2.00.
# The POD got stripped from this file by OODoc version 3.03.
# For contributors see file ChangeLog.

# This software is copyright (c) 2004-2025 by Mark Overmeer.

# This is free software; you can redistribute it and/or modify it under
# the same terms as the Perl 5 programming language system itself.
# SPDX-License-Identifier: Artistic-1.0-Perl OR GPL-1.0-or-later

#oodist: *** DO NOT USE THIS VERSION FOR PRODUCTION ***
#oodist: This file contains OODoc-style documentation which will get stripped
#oodist: during its release in the distribution.  You can use this file for
#oodist: testing, however the code of this development version may be broken!

package Math::Polygon::Surface;{
our $VERSION = '2.00';
}


use strict;
use warnings;

use Log::Report   'math-polygon';
use Scalar::Util  qw/blessed/;

use Math::Polygon ();

#--------------------

sub new(@)
{	my $thing = shift;
	my $class = ref $thing || $thing;
	my (@poly, %options);

	while(@_)
	{	if(!ref $_[0]) { my $k = shift; $options{$k} = shift }
		elsif(ref $_[0] eq 'ARRAY')        { push @poly, shift }
		elsif(blessed $_[0] && $_[0]->isa('Math::Polygon')) { push @poly, shift }
		else { panic "illegal argument $_[0]" }
	}

	$options{_poly} = \@poly if @poly;
	(bless {}, $class)->init(\%options);
}

sub init($$)
{	my ($self, $args)  = @_;
	my ($outer, @inner);

	if($args->{_poly})
	{	($outer, @inner) = @{$args->{_poly}};
	}
	else
	{	$outer = $args->{outer} or error __"surface requires outer polygon";
		@inner = @{$args->{inner}} if defined $args->{inner};
	}

	foreach ($outer, @inner)
	{	next unless ref $_ eq 'ARRAY';
		$_ = Math::Polygon->new(points => $_);
	}

	$self->{MS_outer} = $outer;
	$self->{MS_inner} = \@inner;
	$self;
}

#--------------------

sub outer() { $_[0]->{MS_outer} }


sub inner() { @{$_[0]->{MS_inner}} }

#--------------------

sub bbox() { $_[0]->outer->bbox }


sub area()
{	my $self = shift;
	my $area = $self->outer->area;
	$area   -= $_->area for $self->inner;
	$area;
}


sub perimeter()
{	my $self = shift;
	my $per  = $self->outer->perimeter;
	$per    += $_->perimeter for $self->inner;
	$per;
}

#--------------------

sub lineClip($$$$)
{	my ($self, @bbox) = @_;
	map { $_->lineClip(@bbox) } $self->outer, $self->inner;
}


sub fillClip1($$$$)
{	my ($self, @bbox) = @_;
	my $outer = $self->outer->fillClip1(@bbox);
	return () unless defined $outer;

	$self->new(
		outer => $outer,
		inner => [ map {$_->fillClip1(@bbox)} $self->inner ],
	);
}


sub string()
{	my $self = shift;
	  "["
	. join( "]\n-[",
			$self->outer->string,
			map $_->string, $self->inner)
	. "]";
}

1;