our
$Version
=
'0.11'
;
class Math{
field
$pi
:reader;
field
$e
:reader;
BUILD{
$pi
=4
*atan2
(1,1);
$e
=
exp
(1);
}
method mirrorrotate{
my
(
$point
,
$angle
)=
@_
;
return
[
$point
->[0]
*cos
(
$angle
)+
$point
->[1]
*sin
(
$angle
),
-
$point
->[1]
*cos
(
$angle
)+
$point
->[0]
*sin
(
$angle
)];
}
method rotate{
my
(
$point
,
$angle
)=
@_
;
if
(
ref
$point
->[0] ne
"ARRAY"
){
if
(
scalar
@$point
==2){
return
[
$point
->[0]
*cos
(
$angle
)-
$point
->[1]
*sin
(
$angle
),
$point
->[1]
*cos
(
$angle
)+
$point
->[0]
*sin
(
$angle
)];
}
else
{
my
$result
=
$self
->rotx(
$point
,
$angle
->[0]);
$result
=
$self
->roty(
$result
,
$angle
->[1]);
$result
=
$self
->rotz(
$result
,
$angle
->[2]);
return
$result
;
}
}
else
{
my
$tmp
=[
@$point
];
foreach
(0..
$#$tmp
){
$tmp
->[
$_
]=
$self
->rotate(
$tmp
->[
$_
],
$angle
);
}
return
$tmp
;
}
}
method roty{
my
(
$point
,
$angle
)=
@_
;
my
$matrix
=[
[
cos
(
$angle
),0,
sin
(
$angle
)],
[0,1,0],
[-
sin
(
$angle
),0,
cos
(
$angle
)],
];
return
$self
->matrixTransform(
$point
,
$matrix
);
}
method rotz{
my
(
$point
,
$angle
)=
@_
;
my
$matrix
=[
[
cos
(
$angle
),-
sin
(
$angle
),0],
[
sin
(
$angle
),
cos
(
$angle
),0],
[0,0,1],
];
return
$self
->matrixTransform(
$point
,
$matrix
);
}
method matrixTransform{
my
(
$point
,
$matrix
)=
@_
;
if
(
ref
$point
->[0] ne
"ARRAY"
){
my
$output
=[];
foreach
my
$c
(0..$
my
$sum
=0;
foreach
my
$r
(0..
$#$matrix
){
$sum
+=
$point
->[
$r
]
*$matrix
->[
$c
]->[
$r
];
}
$output
->[
$c
]=
$sum
;
}
return
$output
;
}
else
{
my
$tmp
=[
@$point
];
foreach
(0..
$#$tmp
){
$tmp
->[
$_
]=
$self
->matrixTransform(
$tmp
->[
$_
],
$matrix
);
}
return
$tmp
;
}
}
method add{
my
(
$point1
,
$point2
)=
@_
;
if
((
scalar
@$point1
==
scalar
@$point2
) && (!
ref
$point1
->[0])){;
return
[
map
{
$point1
->[
$_
]+
$point2
->[
$_
]} (0..
$#$point1
)]
}
elsif
(
ref
$point1
->[0] eq
"ARRAY"
){
my
$tmp
=[
@$point1
];
foreach
(0..
$#$tmp
){
$tmp
->[
$_
]=
$self
->add(
$tmp
->[
$_
],
$point2
);
}
return
$tmp
;
};
}
method angle{
my
(
$p1
,
$p2
)=
@_
;
$p2
=[1,0]
unless
$p2
;
return
atan2
(
$p1
->[0],
$p1
->[1])-
atan2
(
$p2
->[0],
$p2
->[1]);
}
method deg2rad{
my
(
$deg
)=
@_
;
return
$deg
*$pi
/180;
}
method rad2deg{
my
(
$rad
)=
@_
;
return
$rad
*180/
$pi
;
}
method distance{
my
(
$p1
,
$p2
)=
@_
;
$p2
=[0,0]
unless
$p2
;
return
sqrt
((
$p1
->[0]-
$p2
->[0])**2+(
$p1
->[1]-
$p2
->[1])**2);
}
method tan{
my
(
$ang
)=
@_
;
return
sin
(
$ang
)/
cos
(
$ang
);
}
method serialise{
my
$st
=
shift
;
if
(
ref
$st
eq
"ARRAY"
){
return
"["
.
join
(
","
,
map
{serialise(
$_
)}
@$st
).
"]"
}
elsif
(
ref
$st
eq
"HASH"
){
return
"{"
.
join
(
","
,
map
{
$_
.
"=>"
.serialise(
$st
->{
$_
})}
keys
%$st
).
"}"
}
else
{
return
$st
=~/^[\d+-\.]/?
$st
:
"\"$st\""
;
};
}
}