File Coverage

lib/Panotools/Script/Line/Control.pm
Criterion Covered Total %
statement 42 44 95.4
branch 3 4 75.0
condition n/a
subroutine 12 12 100.0
pod 0 3 0.0
total 57 63 90.4


line stmt bran cond sub pod time code
1             package Panotools::Script::Line::Control;
2              
3 11     11   1609 use strict;
  11         24  
  11         413  
4 11     11   59 use warnings;
  11         22  
  11         269  
5 11     11   2965 use Math::Trig;
  11         81204  
  11         3825  
6 11     11   831 use Panotools::Script::Line;
  11         25  
  11         327  
7              
8 11     11   68 use vars qw /@ISA/;
  11         21  
  11         19682  
9             @ISA = qw /Panotools::Script::Line/;
10              
11             =head1 NAME
12              
13             Panotools::Script::Line::Control - Panotools control-point
14              
15             =head1 SYNOPSIS
16              
17             A pair of control-points forms a 'c' line
18              
19             =head1 DESCRIPTION
20              
21             One line per point pair.
22             about one pair of points per image per variable being optimized.
23             The more variables being optimized the more control points needed.
24              
25             n0 first image
26             N1 second image
27             x1066.5 first image x point position
28             y844.333 first image y point position
29             X239.52 second image x point position
30             Y804.64 second image y point position
31             t0 type of control point (optional)
32             0 - normal (default)
33             1 - optimize horizontally only
34             2 - optimize vertically only
35             3+ (all other numbers) - straight line
36              
37             =cut
38              
39             sub _defaults
40             {
41 209     209   710 my $self = shift;
42             }
43              
44 501     501   994 sub _valid { return '^([nNxXyYt])(.*)' }
45              
46             sub Identifier
47             {
48 85     85 0 120 my $self = shift;
49 85         938 return "c";
50             }
51              
52             =pod
53              
54             Get a simplified description of a control point useful for identifying
55             duplicates like so:
56              
57             print $point->Packed;
58              
59             Format is first image, x, y, second image, x, y, point type
60              
61             e.g: 2,123,456,3,234,567,0
62              
63             =cut
64              
65             sub Packed
66             {
67 83     83 0 108 my $self = shift;
68 83 100       280 if ($self->{n} < $self->{N})
69             {
70 71         1008 return join ',', $self->{n}, int ($self->{x}), int ($self->{y}),
71             $self->{N}, int ($self->{X}), int ($self->{Y}), $self->{t};
72             }
73             else
74             {
75 12         103 return join ',', $self->{N}, int ($self->{X}), int ($self->{Y}),
76             $self->{n}, int ($self->{x}), int ($self->{y}), $self->{t};
77             }
78             }
79              
80             =pod
81              
82             Get a value for control point error distance (measured in pixels in the panorama
83             output):
84              
85             print $point->Distance ($pto);
86              
87             Note that it is necessary to pass a Panotools::Script object to this method.
88             Note also that the values returned are approximately half those returned by
89             panotools itself, go figure.
90              
91             =cut
92              
93             sub Distance
94             {
95 5     5 0 9 my $self = shift;
96 5         10 my $p = shift;
97              
98 5         15 my $image_N = $p->Image->[$self->{N}];
99 5         18 my $image_n = $p->Image->[$self->{n}];
100              
101 5         26 my $vec_N = $image_N->To_Cartesian ($p, [$self->{X},$self->{Y}]);
102 5         50 my $vec_n = $image_n->To_Cartesian ($p, [$self->{x},$self->{y}]);
103              
104 5         15 $vec_N = _normalise ($vec_N);
105 5         10 $vec_n = _normalise ($vec_n);
106              
107 5         33 my $angle = acos (($vec_N->[0]->[0] * $vec_n->[0]->[0])
108             + ($vec_N->[1]->[0] * $vec_n->[1]->[0])
109             + ($vec_N->[2]->[0] * $vec_n->[2]->[0]));
110              
111 5 50       62 if ($p->Panorama->{f} == 0) # special case for rectilinear output
112             {
113 0         0 my $radius = $p->Panorama->{w} / 2 / tan (deg2rad ($p->Panorama->{v}/2));
114 0         0 return $radius * $angle;
115             }
116              
117 5         57 return $angle / pi() * $p->Panorama->{w} / 2;
118             }
119              
120             sub _normalise
121             {
122 10     10   12 my $vector = shift;
123              
124 10         36 my $magnitude = _magnitude ($vector->[0]->[0], $vector->[1]->[0], $vector->[2]->[0]);
125              
126 10         20 $vector->[0]->[0] = $vector->[0]->[0] / $magnitude;
127 10         19 $vector->[1]->[0] = $vector->[1]->[0] / $magnitude;
128 10         14 $vector->[2]->[0] = $vector->[2]->[0] / $magnitude;
129              
130 10         17 return $vector;
131             }
132              
133             sub _magnitude
134             {
135 10     10   18 my ($x, $y, $z) = @_;
136 10         24 sqrt ($x*$x + $y*$y + $z*$z);
137             }
138              
139             1;
140