-
even authored8c4e6986
directionalscannero8.cpp 6.17 KiB
#include <cstdlib>
#include "directionalscannero8.h"
DirectionalScannerO8::DirectionalScannerO8 (
int xmin, int ymin, int xmax, int ymax,
int a, int b, int c,
int nbs, bool *steps, int sx, int sy)
: DirectionalScanner (xmin, ymin, xmax, ymax,
nbs, steps, sx, sy)
{
this->dla = a;
this->dlb = b;
this->dlc2 = c;
lst1 = steps;
rst1 = steps;
lst2 = steps;
rst2 = steps;
fs = steps + nbs;
ltransition = false;
rtransition = false;
}
DirectionalScannerO8::DirectionalScannerO8 (
int xmin, int ymin, int xmax, int ymax,
int a, int b, int c1, int c2,
int nbs, bool *steps, int cx, int cy)
: DirectionalScanner (xmin, ymin, xmax, ymax,
nbs, steps, cx, cy)
{
this->dla = a;
this->dlb = b;
if (c2 < c1)
{
this->dlc2 = c1;
c1 = c2;
}
else this->dlc2 = c2;
// Looking for the central scan start position
bool *st = steps + nbs;
do
{
if (--st < steps) st = steps + nbs - 1;
if (*st) lcx --;
lcy --;
}
while (dla * lcx + dlb * lcy > c1);
rcx = lcx;
rcy = lcy;
/** ZZZ */
ccx = lcx;
ccy = lcy;
/** ZZZ */
lst1 = steps;
rst1 = steps;
lst2 = steps;
rst2 = steps;
fs = steps + nbs;
ltransition = false;
rtransition = false;
}
DirectionalScannerO8::DirectionalScannerO8 (
int xmin, int ymin, int xmax, int ymax,
int a, int b,
int nbs, bool *steps, int cx, int cy, int length)
: DirectionalScanner (xmin, ymin, xmax, ymax,
nbs, steps, cx, cy)
{
this->dla = a;
this->dlb = b;
fs = steps + nbs;
int w_2 = (length + 1) / 2;
// Looking for the central scan start position
bool *st = steps + nbs;
for (int i = 0; i < w_2; i++)
{
if (--st < steps) st = steps + nbs - 1;
if (*st) lcx --;
lcy --;
}
// Looking for the upper leaning line
st = steps;
while (w_2-- > 0)
{
if (*st) cx++;
cy++;
if (++st >= fs) st = steps;
}
dlc2 = dla * cx + dlb * cy;
rcx = lcx;
rcy = lcy;
/** ZZZ */
ccx = lcx;
ccy = lcy;
/** ZZZ */
lst1 = steps;
rst1 = steps;
lst2 = steps;
rst2 = steps;
ltransition = false;
rtransition = false;
}
int DirectionalScannerO8::first (vector<Pt2i> &scan)
{
int x = lcx, y = lcy; // Current position coordinates
bool *nst = steps; // Current step in scan direction (jpts)
while ((x < xmin || y < ymin) && dla * x + dlb * y <= dlc2)
{
if (*nst) x++;
y++;
if (++nst >= fs) nst = steps;
}
while (dla * x + dlb * y <= dlc2 && x < xmax && y < ymax)
{
scan.push_back (Pt2i (x, y));
if (*nst) x++;
y++;
if (++nst >= fs) nst = steps;
}
return ((int) (scan.size ()));
}
int DirectionalScannerO8::nextOnLeft (vector<Pt2i> &scan)
{
// Prepares the next scan
scan.clear ();
if (ltransition)
{
lcx --;
ltransition = false;
}
else
{
if (--lst1 < steps) lst1 = fs - 1;
lcx --;
if (*lst1)
{
lcy ++;
if (*lst2)
{
lcx ++;
ltransition = true;
}
if (++lst2 >= fs) lst2 = steps;
}
}
// Computes the next scan
int x = lcx;
int y = lcy;
bool *nst = lst2;
while ((x < xmin || y < ymin) && dla * x + dlb * y <= dlc2)
{
if (*nst) x++;
y++;
if (++nst >= fs) nst = steps;
}
while (dla * x + dlb * y <= dlc2 && x < xmax && y < ymax)
{
scan.push_back (Pt2i (x, y));
if (*nst) x++;
y++;
if (++nst >= fs) nst = steps;
}
return ((int) (scan.size ()));
}
int DirectionalScannerO8::nextOnRight (vector<Pt2i> &scan)
{
// Prepares the next scan
scan.clear ();
if (rtransition)
{
rcy --;
if (--rst2 < steps) rst2 = fs - 1;
rtransition = false;
}
else
{
rcx ++;
if (*rst1)
{
if (--rst2 < steps) rst2 = fs - 1;
if (*rst2)
{
if (++rst2 >= fs) rst2 = steps;
rtransition = true;
}
else rcy --;
}
if (++rst1 >= fs) rst1 = steps;
}
// Computes the next scan
int x = rcx;
int y = rcy;
bool *nst = rst2;
while ((x < xmin || y < ymin) && dla * x + dlb * y <= dlc2)
{
if (*nst) x++;
y++;
if (++nst >= fs) nst = steps;
}
while (dla * x + dlb * y <= dlc2 && x < xmax && y < ymax)
{
scan.push_back (Pt2i (x, y));
if (*nst) x++;
y++;
if (++nst >= fs) nst = steps;
}
return ((int) (scan.size ()));
}
Pt2i DirectionalScannerO8::locate (const Pt2i &pt) const
{
int x = ccx, y = ccy; // Current position coordinates
bool *nst = steps; // Current step in scan direction (jpts)
int cx = 0, cy = pt.y () - y;
bool *st1 = steps;
bool *st2 = steps;
if (cy >= 0)
{
// Climbs the first scan up
while (y < pt.y ())
{
if (*nst) x++;
y++;
if (++nst >= fs) nst = steps;
}
}
else
{
// Climbs the first scan down
while (y > pt.y ())
{
y--;
if (--nst < steps) nst = fs -1;
if (*nst) x--;
}
}
cx = pt.x () - x;
// Comes back to scan origin
x = ccx;
y = ccy;
int nx = cx;
bool trans = false;
while (nx != 0)
{
// Jumps leftwards along scan bound
if (cx < 0)
{
if (trans)
{
x --;
trans = false;
}
else
{
if (--st1 < steps) st1 = fs - 1;
x --;
if (*st1)
{
y ++;
if (*st2)
{
x ++;
trans = true;
}
if (++st2 >= fs) st2 = steps;
}
}
nx ++;
}
else
// Jumps rightwards along scan bound
{
if (trans)
{
y --;
if (--st2 < steps) st2 = fs - 1;
trans = false;
}
else
{
x ++;
if (*st1)
{
if (--st2 < steps) st2 = fs - 1;
if (*st2)
{
if (++st2 >= fs) st2 = steps;
trans = true;
}
else y --;
}
if (++st1 >= fs) st1 = steps;
}
nx --;
}
}
return (Pt2i (cx, pt.y () - y));
}