Panotools::Script::Line::Control - Panotools control-point


Panotools-Script documentation Contained in the Panotools-Script distribution.

Index


Code Index:

NAME

Top

Panotools::Script::Line::Control - Panotools control-point

SYNOPSIS

Top

A pair of control-points forms a 'c' line

DESCRIPTION

Top

One line per point pair. about one pair of points per image per variable being optimized. The more variables being optimized the more control points needed.

  n0           first image
  N1           second image
  x1066.5      first image x point position
  y844.333     first image y point position
  X239.52      second image x point position
  Y804.64      second image y point position
  t0           type of control point (optional)
                 0 - normal (default)
                 1 - optimize horizontally only
                 2 - optimize vertically only
                 3+ (all other numbers) - straight line

Get a simplified description of a control point useful for identifying duplicates like so:

  print $point->Packed;

Format is first image, x, y, second image, x, y, point type

e.g: 2,123,456,3,234,567,0

Get a value for control point error distance (measured in pixels in the panorama output):

  print $point->Distance ($pto);

Note that it is necessary to pass a Panotools::Script object to this method. Note also that the values returned are approximately half those returned by panotools itself, go figure.


Panotools-Script documentation Contained in the Panotools-Script distribution.
package Panotools::Script::Line::Control;

use strict;
use warnings;
use Math::Trig;
use Panotools::Script::Line;

use vars qw /@ISA/;
@ISA = qw /Panotools::Script::Line/;

sub _defaults
{
    my $self = shift;
}

sub _valid { return '^([nNxXyYt])(.*)' }

sub Identifier
{
    my $self = shift;
    return "c";
}

sub Packed
{
    my $self = shift;
    if ($self->{n} < $self->{N})
    {
        return join ',', $self->{n}, int ($self->{x}), int ($self->{y}),
                         $self->{N}, int ($self->{X}), int ($self->{Y}), $self->{t};
    }
    else
    {
        return join ',', $self->{N}, int ($self->{X}), int ($self->{Y}),
                         $self->{n}, int ($self->{x}), int ($self->{y}), $self->{t};
    }
}

sub Distance
{
    my $self = shift;
    my $p = shift;

    my $image_N = $p->Image->[$self->{N}];
    my $image_n = $p->Image->[$self->{n}];

    my $vec_N = $image_N->To_Cartesian ($p, [$self->{X},$self->{Y}]);
    my $vec_n = $image_n->To_Cartesian ($p, [$self->{x},$self->{y}]);

    $vec_N = _normalise ($vec_N);
    $vec_n = _normalise ($vec_n);

    my $angle = acos (($vec_N->[0]->[0] * $vec_n->[0]->[0])
                    + ($vec_N->[1]->[0] * $vec_n->[1]->[0])
                    + ($vec_N->[2]->[0] * $vec_n->[2]->[0]));

    if ($p->Panorama->{f} == 0) # special case for rectilinear output
    {
        my $radius = $p->Panorama->{w} / 2 / tan (deg2rad ($p->Panorama->{v}/2));
        return $radius * $angle;
    }

    return $angle / pi() * $p->Panorama->{w} / 2;
}

sub _normalise
{
    my $vector = shift;

    my $magnitude = _magnitude ($vector->[0]->[0], $vector->[1]->[0], $vector->[2]->[0]);

    $vector->[0]->[0] = $vector->[0]->[0] / $magnitude;
    $vector->[1]->[0] = $vector->[1]->[0] / $magnitude;
    $vector->[2]->[0] = $vector->[2]->[0] / $magnitude;

    return $vector;
}

sub _magnitude
{
    my ($x, $y, $z) = @_;
    sqrt ($x*$x + $y*$y + $z*$z);
}

1;