use Carp;
use Data::Dumper;
use Math::GSL::Vector;
-use Math::GSL::Matrix;
+use Math::GSL::Matrix qw/:all/;
+use Math::GSL::Const;
+use Math::GSL::CBLAS qw/:all/;
+use Math::GSL::Machine qw/:all/;
+
+use POSIX qw(M_PI);
BEGIN { unshift @INC, qw(.); }
+our %c;
require 'misc-data.pl';
use Parse;
our $facesf;
our %vxname2pos; # $vxname2pos{VXNAME} = Math::GSL::Vector
+sub TAU { M_PI * 2.0; }
+sub MM2PT { 72.0 / 25.4; }
+
# ----- region names from plag, incl. reverse mapping -----
our %prs2region;
$sum += $_->{Pos} foreach @$poly;
$rr->{Centre} = $sum * (1.0 / @$poly);
}
- # my $cnortn =
+}
+
+sub for_each_pos ($) {
+ my ($f) = @_;
+ foreach my $rr (values %region) {
+ $f->( \ $rr->{Centre} );
+ foreach my $vertex (@{ $rr->{Polygon} }) {
+ $f->( \ $vertex->{Pos} );
+ }
+ }
+}
+
+sub transform_coordinates () {
+ # Adjusts coordinates in graph to be [0,0] .. top right (scaled)
+ # until it's all in PostScript points
+ my @or = map { $region{$_}{Centre} } $c{OrientRegions};
+ my $dir = $or[1] - $or[0];
+ my $theta = atan2 $dir->[1], $dir->[0];
+ my $rotateby = (90 - $c{OrientBearing}) * TAU - $theta;
+ $rotateby += TAU*2;
+ $rotateby %= TAU;
+ my $s = sin($rotateby);
+ my $c = cos($rotateby);
+ my $transform = Math::GSL::Matrix->new([[ $c, $s ],
+ [ -$s, $c ]]);
+ my @lims;
+ foreach my $topend (qw(0 1)) {
+ my $v = $topend ? $GSL_DBL_MAX : $GSL_DBL_MIN;
+ push @lims, Math::GSL::new([$v,$v]);
+ }
+ for_each_pos(sub {
+ my ($pr) = @_;
+ my $y = Math::GSL::Vector->new(2);
+ gsl_blas_dgemv($CblasNoTrans, 1.0, $transform, $$pr, 0., $y) or confess;
+ gsl_blas_dcopy($$pr, $y) or confess;
+ foreach my $topend (qw(0 1)) {
+ foreach my $xy (qw(0 1)) {
+ my $now = $y->get($xy);
+ my $lim = $lims[$topend]->get($xy);
+ next if $topend ? ($now <= $lim) : ($now >= $lim);
+ $lims[$topend]->set($xy, $now);
+ }
+ }
+ });
+ my $translate = -$lims[0];
+ print STDERR "translate $translate\n";
+ my $scale = $c{GraphScale} * MM2PT;
+ for_each_pos(sub {
+ my ($pr) = @_;
+ gsl_vector_add($$pr, $translate) or confess;
+ gsl_vector_scale($$pr, $scale) or confess;
+ });
}
#----- main program -----
prep_region_rmap();
read_faces();
calculate_centres();
+transform_coordinates();
print Dumper(\%region);