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   736 use strict;
  11         20  
  11         306  
4 11     11   59 use warnings;
  11         28  
  11         291  
5 11     11   660 use Math::Trig;
  11         13888  
  11         1901  
6 11     11   518 use Panotools::Script::Line;
  11         20  
  11         341  
7              
8 11     11   58 use vars qw /@ISA/;
  11         35  
  11         6482  
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   332 my $self = shift;
42             }
43              
44 501     501   735 sub _valid { return '^([nNxXyYt])(.*)' }
45              
46             sub Identifier
47             {
48 85     85 0 109 my $self = shift;
49 85         312 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 93 my $self = shift;
68 83 100       147 if ($self->{n} < $self->{N})
69             {
70             return join ',', $self->{n}, int ($self->{x}), int ($self->{y}),
71 71         324 $self->{N}, int ($self->{X}), int ($self->{Y}), $self->{t};
72             }
73             else
74             {
75             return join ',', $self->{N}, int ($self->{X}), int ($self->{Y}),
76 12         63 $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 10 my $self = shift;
96 5         7 my $p = shift;
97              
98 5         12 my $image_N = $p->Image->[$self->{N}];
99 5         12 my $image_n = $p->Image->[$self->{n}];
100              
101 5         21 my $vec_N = $image_N->To_Cartesian ($p, [$self->{X},$self->{Y}]);
102 5         22 my $vec_n = $image_n->To_Cartesian ($p, [$self->{x},$self->{y}]);
103              
104 5         18 $vec_N = _normalise ($vec_N);
105 5         18 $vec_n = _normalise ($vec_n);
106              
107 5         28 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       55 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         14 return $angle / pi() * $p->Panorama->{w} / 2;
118             }
119              
120             sub _normalise
121             {
122 10     10   16 my $vector = shift;
123              
124 10         21 my $magnitude = _magnitude ($vector->[0]->[0], $vector->[1]->[0], $vector->[2]->[0]);
125              
126 10         28 $vector->[0]->[0] = $vector->[0]->[0] / $magnitude;
127 10         16 $vector->[1]->[0] = $vector->[1]->[0] / $magnitude;
128 10         12 $vector->[2]->[0] = $vector->[2]->[0] / $magnitude;
129              
130 10         16 return $vector;
131             }
132              
133             sub _magnitude
134             {
135 10     10   18 my ($x, $y, $z) = @_;
136 10         23 sqrt ($x*$x + $y*$y + $z*$z);
137             }
138              
139             1;
140