-
evenp authored1a08945e
scannerprovider.cpp 7.42 KiB
#include "scannerprovider.h"
#include "directionalscannero2.h"
#include "directionalscannero7.h"
#include "directionalscannero1.h"
#include "directionalscannero8.h"
#include "vhscannero2.h"
#include "vhscannero7.h"
#include "vhscannero1.h"
#include "vhscannero8.h"
DirectionalScanner *ScannerProvider::getScanner (Pt2i p1, Pt2i p2,
bool controlable)
{
// Enforces P1 to be lower than P2
// or to left of P2 in case of equality
lastScanReversed = (p1.y () > p2.y ())
|| ((p1.y () == p2.y ()) && (p1.x () > p2.x ()));
if (lastScanReversed)
{
Pt2i tmp (p1);
p1.set (p2);
p2.set (tmp);
}
// Computes the steps position array
int nbs = 0;
bool *steps = p1.stepsTo (p2, &nbs);
// Equation of the strip support lines : ax + by = c
int a = p2.x () - p1.x ();
int b = p2.y () - p1.y ();
if (a < 0 || (a == 0 && b < 0)) // Enforces a >= 0, then b > 0
{
a = -a;
b = -b;
}
int c2 = a * p2.x () + b * p2.y ();
// Builds and returns the appropriate scanner
if (b < 0)
if (-b > a)
{
if (isOrtho)
{
int repx = (p1.x () + p2.x ()) / 2; // central scan start
int repy = p1.y () - (int) ((p1.x () - repx) * (p1.x () - p2.x ())
/ (p2.y () - p1.y ()));
return (new VHScannerO1 (xmin, ymin, xmax, ymax,
a, b, c2, nbs, steps, repx, repy));
}
else return (controlable ?
(DirectionalScanner *)
new AdaptiveScannerO1 (xmin, ymin, xmax, ymax,
a, b, c2, nbs, steps, p1.x (), p1.y ()) :
new DirectionalScannerO1 (xmin, ymin, xmax, ymax,
a, b, c2, nbs, steps, p1.x (), p1.y ()));
}
else
{
if (isOrtho)
{
int repy = (p1.y () + p2.y ()) / 2; // central scan start
int repx = p1.x () + (int) ((repy - p1.y ()) * (p2.y () - p1.y ())
/ (p1.x () - p2.x ()));
return (new VHScannerO2 (xmin, ymin, xmax, ymax,
a, b, c2, nbs, steps, repx, repy));
}
else return (controlable ?
(DirectionalScanner *)
new AdaptiveScannerO2 (xmin, ymin, xmax, ymax,
a, b, c2, nbs, steps, p1.x (), p1.y ()) :
new DirectionalScannerO2 (xmin, ymin, xmax, ymax,
a, b, c2, nbs, steps, p1.x (), p1.y ()));
}
else
if (b > a)
{
if (isOrtho)
{
int repx = (p1.x () + p2.x ()) / 2; // central scan start
int repy = p1.y () - (int) ((repx - p1.x ()) * (p2.x () - p1.x ())
/ (p2.y () - p1.y ()));
return (new VHScannerO8 (xmin, ymin, xmax, ymax,
a, b, c2, nbs, steps, repx, repy));
}
else return (controlable ?
(DirectionalScanner *)
new AdaptiveScannerO8 (xmin, ymin, xmax, ymax,
a, b, c2, nbs, steps, p1.x (), p1.y ()) :
new DirectionalScannerO8 (xmin, ymin, xmax, ymax,
a, b, c2, nbs, steps, p1.x (), p1.y ()));
}
else
{
if (isOrtho)
{
int repy = (p1.y () + p2.y ()) / 2; // central scan start
int repx = p1.x () - (int) ((repy - p1.y ()) * (p2.y () - p1.y ())
/ (p2.x () - p1.x ()));
return (new VHScannerO7 (xmin, ymin, xmax, ymax,
a, b, c2, nbs, steps, repx, repy));
}
else return (controlable ?
(DirectionalScanner *)
new AdaptiveScannerO7 (xmin, ymin, xmax, ymax,
a, b, c2, nbs, steps, p1.x (), p1.y ()) :
new DirectionalScannerO7 (xmin, ymin, xmax, ymax,
a, b, c2, nbs, steps, p1.x (), p1.y ()));
}
}
DirectionalScanner *ScannerProvider::getScanner (Pt2i centre, Vr2i normal,
int length, bool controlable)
{
// Gets the steps position array
int nbs = 0;
bool *steps = centre.stepsTo (Pt2i (centre.x () + normal.x (),
centre.y () + normal.y ()), &nbs);
// Orients rightwards
int a = normal.x ();
int b = normal.y (); // as equation is (ax + by = c)
if (a < 0 || (a == 0 && b < 0))
{
a = -a;
b = -b;
}
// Builds and returns the appropriate scanner
if (b < 0)
if (-b > a)
return (controlable ?
(isOrtho ?
(DirectionalScanner *)
new VHScannerO1 (xmin, ymin, xmax, ymax,
a, b, nbs, steps,
centre.x (), centre.y (), length) :
(DirectionalScanner *)
new AdaptiveScannerO1 (xmin, ymin, xmax, ymax,
a, b, nbs, steps,
centre.x (), centre.y (), length)) :
(DirectionalScanner *)
new DirectionalScannerO1 (xmin, ymin, xmax, ymax,
a, b, nbs, steps,
centre.x (), centre.y (), length));
else
return (controlable ?
(isOrtho ?
(DirectionalScanner *)
new VHScannerO2 (xmin, ymin, xmax, ymax,
a, b, nbs, steps,
centre.x (), centre.y (), length) :
(DirectionalScanner *)
new AdaptiveScannerO2 (xmin, ymin, xmax, ymax,
a, b, nbs, steps,
centre.x (), centre.y (), length)) :
(DirectionalScanner *)
new DirectionalScannerO2 (xmin, ymin, xmax, ymax,
a, b, nbs, steps,
centre.x (), centre.y (), length));
else
if (b > a)
return (controlable ?
(isOrtho ?
(DirectionalScanner *)
new VHScannerO8 (xmin, ymin, xmax, ymax,
a, b, nbs, steps,
centre.x (), centre.y (), length) :
(DirectionalScanner *)
new AdaptiveScannerO8 (xmin, ymin, xmax, ymax,
a, b, nbs, steps,
centre.x (), centre.y (), length)) :
(DirectionalScanner *)
new DirectionalScannerO8 (xmin, ymin, xmax, ymax,
a, b, nbs, steps,
centre.x (), centre.y (), length));
else
return (controlable ?
(isOrtho ?
(DirectionalScanner *)
new VHScannerO7 (xmin, ymin, xmax, ymax,
a, b, nbs, steps,
centre.x (), centre.y (), length) :
(DirectionalScanner *)
new AdaptiveScannerO7 (xmin, ymin, xmax, ymax,
a, b, nbs, steps,
centre.x (), centre.y (), length)) :
(DirectionalScanner *)
new DirectionalScannerO7 (xmin, ymin, xmax, ymax,
a, b, nbs, steps,
centre.x (), centre.y (), length));
}