|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "trop.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=======================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
class HalfCord
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int *m_array;
|
|
Toshihiro Shimizu |
890ddd |
int m_radius;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Toshihiro Shimizu |
890ddd |
HalfCord(int radius)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(radius >= 0);
|
|
Toshihiro Shimizu |
890ddd |
m_radius = radius;
|
|
Toshihiro Shimizu |
890ddd |
m_array = new int[m_radius + 1];
|
|
Toshihiro Shimizu |
890ddd |
memset(m_array, 0, (m_radius + 1) * sizeof(int));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
float dCircle = 1.25f - m_radius; // inizializza decision variable
|
|
Toshihiro Shimizu |
890ddd |
int y = m_radius; // inizializzazione indice scanline
|
|
Toshihiro Shimizu |
890ddd |
int x = 0; // inizializzazione indice colonna
|
|
Toshihiro Shimizu |
890ddd |
do {
|
|
Toshihiro Shimizu |
890ddd |
m_array[y] = tmax(x, m_array[y]);
|
|
Toshihiro Shimizu |
890ddd |
m_array[x] = y;
|
|
Toshihiro Shimizu |
890ddd |
if (dCircle <= 0) {
|
|
Toshihiro Shimizu |
890ddd |
dCircle = dCircle + 2 * x + 3;
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
y--;
|
|
Toshihiro Shimizu |
890ddd |
dCircle = dCircle + 2 * (x - y) + 5;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
x++;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
} while (y >= x);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
~HalfCord()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
delete[] m_array;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
inline int getCord(int x)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(0 <= x && x <= m_radius);
|
|
Toshihiro Shimizu |
890ddd |
return m_array[x];
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Toshihiro Shimizu |
890ddd |
// not implemented
|
|
Toshihiro Shimizu |
890ddd |
HalfCord(const HalfCord &);
|
|
Toshihiro Shimizu |
890ddd |
HalfCord &operator=(const HalfCord &);
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=======================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TRop::brush(
|
|
Toshihiro Shimizu |
890ddd |
TRaster32P ras,
|
|
Toshihiro Shimizu |
890ddd |
const TPoint &aa,
|
|
Toshihiro Shimizu |
890ddd |
const TPoint &bb,
|
|
Toshihiro Shimizu |
890ddd |
int radius,
|
|
Toshihiro Shimizu |
890ddd |
const TPixel32 &col)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPoint a = aa;
|
|
Toshihiro Shimizu |
890ddd |
TPoint b = bb;
|
|
Toshihiro Shimizu |
890ddd |
if (a.y > b.y)
|
|
Toshihiro Shimizu |
890ddd |
tswap(a, b); // a e' piu' in basso di b
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int lx = ras->getLx();
|
|
Toshihiro Shimizu |
890ddd |
int ly = ras->getLy();
|
|
Toshihiro Shimizu |
890ddd |
ras->lock();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// ----- radius = 0
|
|
Toshihiro Shimizu |
890ddd |
if (radius == 0) {
|
|
Toshihiro Shimizu |
890ddd |
// k = +1/-1 se il rettangolo e' inclinato positivamente (0<=m)/negativamente (m<0)
|
|
Toshihiro Shimizu |
890ddd |
// (se k<0 viene fatta una riflessione sulle ascisse prima di tornare alle
|
|
Toshihiro Shimizu |
890ddd |
// coordinate "di schermo")
|
|
Toshihiro Shimizu |
890ddd |
int k = 1;
|
|
Toshihiro Shimizu |
890ddd |
int dy = b.y - a.y;
|
|
Toshihiro Shimizu |
890ddd |
int dx = b.x - a.x;
|
|
Toshihiro Shimizu |
890ddd |
if (dx < 0) {
|
|
Toshihiro Shimizu |
890ddd |
dx = -dx;
|
|
Toshihiro Shimizu |
890ddd |
k = -1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(dx >= 0);
|
|
Toshihiro Shimizu |
890ddd |
assert(dy >= 0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double m; // m sara' definita solo per dx!=0)
|
|
Toshihiro Shimizu |
890ddd |
if (dx > 0) {
|
|
Toshihiro Shimizu |
890ddd |
m = dy / (double)dx;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//double length = sqrt(dx*dx + dy*dy);
|
|
Toshihiro Shimizu |
890ddd |
const int alpha = dy, beta = -dx;
|
|
Toshihiro Shimizu |
890ddd |
const int incE = alpha;
|
|
Toshihiro Shimizu |
890ddd |
const int incNE = alpha + beta;
|
|
Toshihiro Shimizu |
890ddd |
const int incN = beta;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// N.B. le coordinate sono relative ad un sist. di rif. con l'origine in a
|
|
Toshihiro Shimizu |
890ddd |
// l'eq. della retta e' alpha * x + beta * y = 0
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int yMin = tmax(a.y, 0) - a.y; // clipping y + cambio riferimento
|
|
Toshihiro Shimizu |
890ddd |
int yMax = tmin(b.y, ly - 1) - a.y; // (trasporto dell'origine in a)
|
|
Toshihiro Shimizu |
890ddd |
if (dx > 0 && m <= 1) {
|
|
Toshihiro Shimizu |
890ddd |
// midpoint algorithm
|
|
Toshihiro Shimizu |
890ddd |
TPoint segm;
|
|
Toshihiro Shimizu |
890ddd |
if (dy == 0) // segmento orizzontale: inizializza segm
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
segm.x = 0;
|
|
Toshihiro Shimizu |
890ddd |
segm.y = yMin;
|
|
Toshihiro Shimizu |
890ddd |
} else // 0
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
segm.x = tceil((yMin - 0.5) / m);
|
|
Toshihiro Shimizu |
890ddd |
segm.y = yMin;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int dSegm = tfloor(alpha * (segm.x + 1) + beta * (segm.y + 0.5));
|
|
Toshihiro Shimizu |
890ddd |
while (segm.y <= yMax) {
|
|
Toshihiro Shimizu |
890ddd |
int count = 0; // i trati orizzontali di segm vengono disegnati in "blocco"
|
|
Toshihiro Shimizu |
890ddd |
while (dSegm < 0 && segm.x <= dx) // Est: segm.x<=dx evita il ciclo
|
|
Toshihiro Shimizu |
890ddd |
{ // infinito quando m=0 (incE=0)
|
|
Toshihiro Shimizu |
890ddd |
dSegm = dSegm + incE;
|
|
Toshihiro Shimizu |
890ddd |
segm.x++;
|
|
Toshihiro Shimizu |
890ddd |
count++;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
// NordEst
|
|
Toshihiro Shimizu |
890ddd |
int xMin, xMax;
|
|
Toshihiro Shimizu |
890ddd |
if (k > 0) {
|
|
Toshihiro Shimizu |
890ddd |
xMin = tmax(a.x + segm.x - count, a.x, 0); // clipping x + ritorno alle
|
|
Toshihiro Shimizu |
890ddd |
xMax = tmin(a.x + segm.x, b.x, lx - 1); // coordinate "di schermo"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
xMin = tmax(a.x - segm.x, a.x - dx, 0); // clipping x + riflessione + ritorno
|
|
Toshihiro Shimizu |
890ddd |
xMax = tmin(a.x - segm.x + count, a.x, lx - 1); // alle coordinate "di schermo"
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *p = ras->pixels(segm.y + a.y) + xMin;
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *q = p + (xMax - xMin);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
while (p <= q)
|
|
Toshihiro Shimizu |
890ddd |
*p++ = col;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
dSegm = dSegm + incNE;
|
|
Toshihiro Shimizu |
890ddd |
segm.x++;
|
|
Toshihiro Shimizu |
890ddd |
segm.y++;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} else // m>1 oppure segmento verticale
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
// midpoint algorithm
|
|
Toshihiro Shimizu |
890ddd |
TPoint segm;
|
|
Toshihiro Shimizu |
890ddd |
if (dx == 0) // segmento verticale: inizializza segm
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
segm.x = 0;
|
|
Toshihiro Shimizu |
890ddd |
segm.y = yMin;
|
|
Toshihiro Shimizu |
890ddd |
} else // m>1 : inizializza segm
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
segm.x = tround(yMin / m);
|
|
Toshihiro Shimizu |
890ddd |
segm.y = yMin;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int dSegm = tfloor(alpha * (segm.x + 0.5) + beta * (segm.y + 1));
|
|
Toshihiro Shimizu |
890ddd |
while (segm.y <= yMax) {
|
|
Toshihiro Shimizu |
890ddd |
int xMin, xMax;
|
|
Toshihiro Shimizu |
890ddd |
if (k > 0) {
|
|
Toshihiro Shimizu |
890ddd |
xMin = tmax(a.x + segm.x, 0); // clipping x + ritorno alle
|
|
Toshihiro Shimizu |
890ddd |
xMax = tmin(a.x + segm.x, lx - 1); // coordinate "di schermo"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
xMin = tmax(a.x - segm.x, 0); // clipping x + riflessione + ritorno
|
|
Toshihiro Shimizu |
890ddd |
xMax = tmin(a.x - segm.x, lx - 1); // alle coordinate "di schermo"
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *p = ras->pixels(segm.y + a.y) + xMin;
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *q = p + (xMax - xMin);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
while (p <= q)
|
|
Toshihiro Shimizu |
890ddd |
*p++ = col;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (dSegm <= 0) // NordEst
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
dSegm = dSegm + incNE;
|
|
Toshihiro Shimizu |
890ddd |
segm.x++;
|
|
Toshihiro Shimizu |
890ddd |
} else // Nord
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
dSegm = dSegm + incN;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
segm.y++;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
ras->unlock();
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
HalfCord halfCord(radius);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int x, y;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// ----- punti iniziali coincidenti: disegna un cerchio
|
|
Toshihiro Shimizu |
890ddd |
if (a == b) {
|
|
Toshihiro Shimizu |
890ddd |
int yMin = tmax(a.y - radius, 0); // clipping y
|
|
Toshihiro Shimizu |
890ddd |
int yMax = tmin(a.y + radius, ly - 1); // clipping y
|
|
Toshihiro Shimizu |
890ddd |
for (y = yMin; y <= yMax; y++) {
|
|
Toshihiro Shimizu |
890ddd |
int deltay = abs(y - a.y);
|
|
Toshihiro Shimizu |
890ddd |
int xMin = tmax(a.x - halfCord.getCord(deltay), 0); // clipping x
|
|
Toshihiro Shimizu |
890ddd |
int xMax = tmin(a.x + halfCord.getCord(deltay), lx - 1); // clipping x
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *p = ras->pixels(y) + xMin;
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *q = p + (xMax - xMin);
|
|
Toshihiro Shimizu |
890ddd |
while (p <= q)
|
|
Toshihiro Shimizu |
890ddd |
*p++ = col;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
ras->unlock();
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// ----- rettangolo orizzontale (a.y = b.y, a.x != b.x)
|
|
Toshihiro Shimizu |
890ddd |
if (a.y == b.y) {
|
|
Toshihiro Shimizu |
890ddd |
int yMin = tmax((a.y - radius), 0); // clipping y
|
|
Toshihiro Shimizu |
890ddd |
int yMax = tmin((a.y + radius), ly - 1); // clipping y
|
|
Toshihiro Shimizu |
890ddd |
int xLeft = tmin(a.x, b.x);
|
|
Toshihiro Shimizu |
890ddd |
int xRight = tmax(a.x, b.x);
|
|
Toshihiro Shimizu |
890ddd |
for (y = yMin; y <= yMax; y++) {
|
|
Toshihiro Shimizu |
890ddd |
int deltay = abs(y - a.y);
|
|
Toshihiro Shimizu |
890ddd |
int xMin = tmax(xLeft - halfCord.getCord(deltay), 0); // clipping x
|
|
Toshihiro Shimizu |
890ddd |
int xMax = tmin(xRight + halfCord.getCord(deltay), lx - 1); // clipping x
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *p = ras->pixels(y) + xMin;
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *q = p + (xMax - xMin);
|
|
Toshihiro Shimizu |
890ddd |
while (p <= q)
|
|
Toshihiro Shimizu |
890ddd |
*p++ = col;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
ras->unlock();
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// ----- rettangolo verticale (a.x = b.x, a.y != b.y)
|
|
Toshihiro Shimizu |
890ddd |
if (a.x == b.x) {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int xMin = tmax(a.x - radius, 0); // clipping x
|
|
Toshihiro Shimizu |
890ddd |
int xMax = tmin(a.x + radius, lx - 1); // clipping x
|
|
Toshihiro Shimizu |
890ddd |
for (x = xMin; x <= xMax; x++) {
|
|
Toshihiro Shimizu |
890ddd |
int deltax = abs(x - a.x);
|
|
Toshihiro Shimizu |
890ddd |
int yMin = tmax(a.y - halfCord.getCord(deltax), 0); // clipping y
|
|
Toshihiro Shimizu |
890ddd |
int yMax = tmin(b.y + halfCord.getCord(deltax), ly - 1); // clipping y
|
|
Toshihiro Shimizu |
890ddd |
if (yMin <= yMax) {
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *p = ras->pixels(yMin) + x;
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *q = ras->pixels(yMax) + x;
|
|
Toshihiro Shimizu |
890ddd |
int wrap = ras->getWrap();
|
|
Toshihiro Shimizu |
890ddd |
while (p <= q) {
|
|
Toshihiro Shimizu |
890ddd |
*p = col;
|
|
Toshihiro Shimizu |
890ddd |
p += wrap;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
ras->unlock();
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// ----- rettangolo inclinato
|
|
Toshihiro Shimizu |
890ddd |
// k = +1/-1 se il rettangolo e' inclinato positivamente/negativamente
|
|
Toshihiro Shimizu |
890ddd |
int k = 1;
|
|
Toshihiro Shimizu |
890ddd |
int dx = b.x - a.x;
|
|
Toshihiro Shimizu |
890ddd |
if (dx < 0) {
|
|
Toshihiro Shimizu |
890ddd |
dx = -dx;
|
|
Toshihiro Shimizu |
890ddd |
k = -1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
int dy = b.y - a.y;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(dx > 0);
|
|
Toshihiro Shimizu |
890ddd |
assert(dy > 0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double length = sqrt((double)(dx * dx + dy * dy));
|
|
Toshihiro Shimizu |
890ddd |
const double m = dy / (double)dx;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//punto di tangenza superiore nel sistema di riferimento del cerchio
|
|
Toshihiro Shimizu |
890ddd |
TPointD up(-radius * dy / length, radius * dx / length);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//semi-ampiezza orizzontale delle "calotte" circolari
|
|
Toshihiro Shimizu |
890ddd |
int halfAmplCap = tfloor(-up.x);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// A meno di intersezioni relative tra le diverse zone:
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// le scanline della "calotta" circolare superiore sono (b.y+cutExt,b.y+radius]
|
|
Toshihiro Shimizu |
890ddd |
// le scanline del trapezoide circolare superiore sono [b.y-cutIn,b.y+cutExt]
|
|
Toshihiro Shimizu |
890ddd |
// le scanline del parallelogramma sono (a.y+cutIn,b.y-cutIn)
|
|
Toshihiro Shimizu |
890ddd |
// le scanline del trapezoide circolare inferiore sono [a.y-cutExt,a.y+cutIn]
|
|
Toshihiro Shimizu |
890ddd |
// le scanline della "calotta" circolare inferiore sono [a.y-radius,a.y-cutExt)
|
|
Toshihiro Shimizu |
890ddd |
int cutExt, cutIn;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// vertici del parallelogramma
|
|
Toshihiro Shimizu |
890ddd |
TPointD rightUp;
|
|
Toshihiro Shimizu |
890ddd |
TPointD rightDown;
|
|
Toshihiro Shimizu |
890ddd |
TPointD leftUp;
|
|
Toshihiro Shimizu |
890ddd |
TPointD leftDown;
|
|
Toshihiro Shimizu |
890ddd |
double mParall; //coeff. angolare parallelogramma
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// NOTA BENE: halfAmplCap=0 <=> (radius=0 (caso a parte) , 1)
|
|
Toshihiro Shimizu |
890ddd |
if (radius > 1) {
|
|
Toshihiro Shimizu |
890ddd |
for (cutExt = radius; cutExt >= 0 && halfCord.getCord(cutExt) <= halfAmplCap; cutExt--)
|
|
Toshihiro Shimizu |
890ddd |
;
|
|
Toshihiro Shimizu |
890ddd |
cutIn = cutExt; // vedi else successivo
|
|
Toshihiro Shimizu |
890ddd |
rightUp.x = dx + halfCord.getCord(cutIn);
|
|
Toshihiro Shimizu |
890ddd |
rightUp.y = dy - cutIn;
|
|
Toshihiro Shimizu |
890ddd |
rightDown.x = halfCord.getCord(cutIn);
|
|
Toshihiro Shimizu |
890ddd |
rightDown.y = -cutIn;
|
|
Toshihiro Shimizu |
890ddd |
leftUp.x = dx - halfCord.getCord(cutIn);
|
|
Toshihiro Shimizu |
890ddd |
leftUp.y = dy + cutIn;
|
|
Toshihiro Shimizu |
890ddd |
leftDown.x = -halfCord.getCord(cutIn);
|
|
Toshihiro Shimizu |
890ddd |
leftDown.y = cutIn;
|
|
Toshihiro Shimizu |
890ddd |
mParall = dy / (double)dx;
|
|
Toshihiro Shimizu |
890ddd |
} else // N.B. cutExt != cutIn solo quando radius=1
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
cutExt = radius; // radius=1 => halfAmplCap=0 (non ci sono mai le "calotte" circolari)
|
|
Toshihiro Shimizu |
890ddd |
cutIn = 0; // anche per radius=1 il limite "interno" dei trapezoidi circolari e' < radius
|
|
Toshihiro Shimizu |
890ddd |
rightUp.x = dx - up.x;
|
|
Toshihiro Shimizu |
890ddd |
rightUp.y = dy - up.y;
|
|
Toshihiro Shimizu |
890ddd |
rightDown.x = -up.x;
|
|
Toshihiro Shimizu |
890ddd |
rightDown.y = -up.y;
|
|
Toshihiro Shimizu |
890ddd |
leftUp.x = dx + up.x;
|
|
Toshihiro Shimizu |
890ddd |
leftUp.y = dy + up.y;
|
|
Toshihiro Shimizu |
890ddd |
leftDown.x = up.x;
|
|
Toshihiro Shimizu |
890ddd |
leftDown.y = up.y;
|
|
Toshihiro Shimizu |
890ddd |
mParall = m;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
// ----- riempie "calotte" circolari
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// ----- riempie "calotta" circolare inferiore
|
|
Toshihiro Shimizu |
890ddd |
int yMin = tmax(a.y - radius, 0); // clipping y
|
|
Toshihiro Shimizu |
890ddd |
int yMax = tmin(a.y - cutExt - 1, ly - 1); // clipping y
|
|
Toshihiro Shimizu |
890ddd |
for (y = yMin; y <= yMax; y++) {
|
|
Toshihiro Shimizu |
890ddd |
int r = halfCord.getCord(a.y - y);
|
|
Toshihiro Shimizu |
890ddd |
int xMin = tmax(a.x - r, 0); // clipping x
|
|
Toshihiro Shimizu |
890ddd |
int xMax = tmin(a.x + r, lx - 1); // clipping x
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *p = ras->pixels(y) + xMin;
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *q = p + (xMax - xMin);
|
|
Toshihiro Shimizu |
890ddd |
while (p <= q)
|
|
Toshihiro Shimizu |
890ddd |
*p++ = col;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
// ----- riempie "calotta" circolare superiore
|
|
Toshihiro Shimizu |
890ddd |
yMin = tmax(b.y + cutExt + 1, 0); // clipping y
|
|
Toshihiro Shimizu |
890ddd |
yMax = tmin(b.y + radius, ly - 1); // clipping y
|
|
Toshihiro Shimizu |
890ddd |
for (y = yMin; y <= yMax; y++) {
|
|
Toshihiro Shimizu |
890ddd |
int r = halfCord.getCord(y - b.y);
|
|
Toshihiro Shimizu |
890ddd |
int xMin = tmax(b.x - r, 0); // clipping x
|
|
Toshihiro Shimizu |
890ddd |
int xMax = tmin(b.x + r, lx - 1); // clipping x
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *p = ras->pixels(y) + xMin;
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *q = p + (xMax - xMin);
|
|
Toshihiro Shimizu |
890ddd |
while (p <= q)
|
|
Toshihiro Shimizu |
890ddd |
*p++ = col;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
// ----- riempie trapezoidi
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// (se k<0 viene fatta una riflessione sulle ascisse prima di tornare alle
|
|
Toshihiro Shimizu |
890ddd |
// coordinate "di schermo")
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// limite destro assoluto delle scanline trapezoide:
|
|
Toshihiro Shimizu |
890ddd |
int xSegmMax = tround(dx - up.x); // coordinata x del punto di tangenza inferiore sul cerchio superiore
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// limite sinistro assoluto delle scanline:
|
|
Toshihiro Shimizu |
890ddd |
int xSegmMin = tround(up.x); // coordinata x del punto di tangenza superiore sul cerchio inferiore
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// ----- riempie trapezoide inferiore
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// N.B. le coordinate sono relative ad un sist. di rif. con l'origine sul centro
|
|
Toshihiro Shimizu |
890ddd |
// del cerchio inferiore
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
yMin = tmax(a.y - cutExt, 0) - a.y; // clipping y
|
|
Toshihiro Shimizu |
890ddd |
yMax = tmin(a.y + cutIn, b.y - cutIn - 1, ly - 1) - a.y; // clipping y
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// l'eq. della retta e' alpha * x + beta * y + gammaRight = 0
|
|
Toshihiro Shimizu |
890ddd |
const int alpha = dy, beta = -dx;
|
|
Toshihiro Shimizu |
890ddd |
const double gammaRight = rightDown.y * dx - rightDown.x * dy;
|
|
Toshihiro Shimizu |
890ddd |
const int incE = alpha;
|
|
Toshihiro Shimizu |
890ddd |
const int incNE = alpha + beta;
|
|
Toshihiro Shimizu |
890ddd |
const int incN = beta;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (m <= 1) {
|
|
Toshihiro Shimizu |
890ddd |
// midpoint algorithm; le scanline vengono disegnate solo
|
|
Toshihiro Shimizu |
890ddd |
// sul NordEst. L'ultima scanline non viene disegnata
|
|
Toshihiro Shimizu |
890ddd |
TPoint segmRight(tceil((yMin + 0.5 - rightDown.y) / mParall + rightDown.x) - 1, yMin);
|
|
Toshihiro Shimizu |
890ddd |
int dSegmRight = tfloor(alpha * (segmRight.x + 1) + beta * (segmRight.y + 0.5) + gammaRight);
|
|
Toshihiro Shimizu |
890ddd |
while (segmRight.y <= yMax) {
|
|
Toshihiro Shimizu |
890ddd |
if (dSegmRight < 0) // Est
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
dSegmRight = dSegmRight + incE;
|
|
Toshihiro Shimizu |
890ddd |
segmRight.x++;
|
|
Toshihiro Shimizu |
890ddd |
} else // NordEst
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int xMin, xMax;
|
|
Toshihiro Shimizu |
890ddd |
if (k > 0) {
|
|
Toshihiro Shimizu |
890ddd |
xMin = tmax(a.x - halfCord.getCord(abs(segmRight.y)), 0); // clipping x
|
|
Toshihiro Shimizu |
890ddd |
xMax = tmin(a.x + tmin(segmRight.x, xSegmMax), lx - 1); // clipping x
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
xMin = tmax(a.x - tmin(segmRight.x, xSegmMax), 0); // clipping x + ritorno alle
|
|
Toshihiro Shimizu |
890ddd |
xMax = tmin(a.x + halfCord.getCord(abs(segmRight.y)), lx - 1); // coordinate "di schermo"
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *p = ras->pixels(segmRight.y + a.y) + xMin;
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *q = p + (xMax - xMin);
|
|
Toshihiro Shimizu |
890ddd |
while (p <= q)
|
|
Toshihiro Shimizu |
890ddd |
*p++ = col;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
dSegmRight = dSegmRight + incNE;
|
|
Toshihiro Shimizu |
890ddd |
segmRight.x++;
|
|
Toshihiro Shimizu |
890ddd |
segmRight.y++;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} else // m>1
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
// midpoint algorithm; le scanline vengono disegnate sempre
|
|
Toshihiro Shimizu |
890ddd |
TPoint segmRight(tround((yMin - rightDown.y) / mParall + rightDown.x), yMin);
|
|
Toshihiro Shimizu |
890ddd |
int dSegmRight = tfloor(alpha * (segmRight.x + 0.5) + beta * (segmRight.y + 1) + gammaRight);
|
|
Toshihiro Shimizu |
890ddd |
while (segmRight.y <= yMax) {
|
|
Toshihiro Shimizu |
890ddd |
int xMin, xMax;
|
|
Toshihiro Shimizu |
890ddd |
if (k > 0) {
|
|
Toshihiro Shimizu |
890ddd |
xMin = tmax(a.x - halfCord.getCord(abs(segmRight.y)), 0); // clipping x
|
|
Toshihiro Shimizu |
890ddd |
xMax = tmin(a.x + segmRight.x, lx - 1); // clipping x
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
xMin = tmax(a.x - segmRight.x, 0); // clipping x + ritorno alle coordinate
|
|
Toshihiro Shimizu |
890ddd |
xMax = tmin(a.x + halfCord.getCord(abs(segmRight.y)), lx - 1); // "di schermo"
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *p = ras->pixels(segmRight.y + a.y) + xMin;
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *q = p + (xMax - xMin);
|
|
Toshihiro Shimizu |
890ddd |
while (p <= q)
|
|
Toshihiro Shimizu |
890ddd |
*p++ = col;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (dSegmRight <= 0) // NordEst
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
dSegmRight = dSegmRight + incNE;
|
|
Toshihiro Shimizu |
890ddd |
segmRight.x++;
|
|
Toshihiro Shimizu |
890ddd |
} else // Nord
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
dSegmRight = dSegmRight + incN;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
segmRight.y++;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// ----- riempie trapezoide superiore
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// N.B. le coordinate sono relative ad un sist. di rif. con l'origine sul centro
|
|
Toshihiro Shimizu |
890ddd |
// del cerchio superiore
|
|
Toshihiro Shimizu |
890ddd |
yMin = tmax(b.y - cutIn, a.y + cutIn + 1, 0) - b.y; // clipping y
|
|
Toshihiro Shimizu |
890ddd |
yMax = tmin(b.y + cutExt, ly - 1) - b.y; // clipping y
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// l'eq. della retta e' alpha * x + beta * y + gammaLeft = 0
|
|
Toshihiro Shimizu |
890ddd |
const double gammaLeft = leftDown.y * dx - leftDown.x * dy;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (m <= 1) {
|
|
Toshihiro Shimizu |
890ddd |
// midpoint algorithm; le scanline vengono disegnate solo
|
|
Toshihiro Shimizu |
890ddd |
// sul NordEst. L'ultima scanline non viene disegnata
|
|
Toshihiro Shimizu |
890ddd |
TPoint segmLeft(tceil((yMin - 0.5 - leftDown.y) / mParall + leftDown.x), yMin);
|
|
Toshihiro Shimizu |
890ddd |
int dSegmLeft = tfloor(alpha * (segmLeft.x + 1) + beta * (segmLeft.y + 0.5) + gammaLeft);
|
|
Toshihiro Shimizu |
890ddd |
while (segmLeft.y <= yMax) {
|
|
Toshihiro Shimizu |
890ddd |
int xMin, xMax;
|
|
Toshihiro Shimizu |
890ddd |
if (k > 0) {
|
|
Toshihiro Shimizu |
890ddd |
xMin = tmax(b.x + tmax(segmLeft.x, xSegmMin - dx), 0); // clipping x
|
|
Toshihiro Shimizu |
890ddd |
xMax = tmin(b.x + halfCord.getCord(abs(segmLeft.y)), lx - 1); // clipping x
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
xMin = tmax(b.x - halfCord.getCord(abs(segmLeft.y)), 0); // clipping x + ritorno alle
|
|
Toshihiro Shimizu |
890ddd |
xMax = tmin(b.x - tmax(segmLeft.x, xSegmMin - dx), lx - 1); // coordinate "di schermo"
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *p = ras->pixels(segmLeft.y + b.y) + xMin;
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *q = p + (xMax - xMin);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
while (p <= q)
|
|
Toshihiro Shimizu |
890ddd |
*p++ = col;
|
|
Toshihiro Shimizu |
890ddd |
while (dSegmLeft < 0) {
|
|
Toshihiro Shimizu |
890ddd |
dSegmLeft = dSegmLeft + incE;
|
|
Toshihiro Shimizu |
890ddd |
segmLeft.x++;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
dSegmLeft = dSegmLeft + incNE;
|
|
Toshihiro Shimizu |
890ddd |
segmLeft.x++;
|
|
Toshihiro Shimizu |
890ddd |
segmLeft.y++;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} else // m>1
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
// midpoint algorithm; le scanline vengono disegnate sempre
|
|
Toshihiro Shimizu |
890ddd |
TPoint segmLeft(tround((yMin - leftDown.y) / mParall + leftDown.x), yMin);
|
|
Toshihiro Shimizu |
890ddd |
int dSegmLeft = tfloor(alpha * (segmLeft.x + 0.5) + beta * (segmLeft.y + 1) + gammaLeft);
|
|
Toshihiro Shimizu |
890ddd |
while (segmLeft.y <= yMax) {
|
|
Toshihiro Shimizu |
890ddd |
int xMin, xMax;
|
|
Toshihiro Shimizu |
890ddd |
if (k > 0) {
|
|
Toshihiro Shimizu |
890ddd |
xMin = tmax(b.x + segmLeft.x, 0); // clipping x
|
|
Toshihiro Shimizu |
890ddd |
xMax = tmin(b.x + halfCord.getCord(abs(segmLeft.y)), lx - 1); // clipping x
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
xMin = tmax(b.x - halfCord.getCord(abs(segmLeft.y)), 0); // clipping x + ritorno alle
|
|
Toshihiro Shimizu |
890ddd |
xMax = tmin(b.x - segmLeft.x, lx - 1); // coordinate "di schermo"
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *p = ras->pixels(segmLeft.y + b.y) + xMin;
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *q = p + (xMax - xMin);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
while (p <= q)
|
|
Toshihiro Shimizu |
890ddd |
*p++ = col;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (dSegmLeft <= 0) // NordEst
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
dSegmLeft = dSegmLeft + incNE;
|
|
Toshihiro Shimizu |
890ddd |
segmLeft.x++;
|
|
Toshihiro Shimizu |
890ddd |
} else // Nord
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
dSegmLeft = dSegmLeft + incN;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
segmLeft.y++;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// ----- parallelogramma (in alternativa a "parallelogrammoide circolare")
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// N.B. le coordinate sono relative ad un sist. di rif. con l'origine sul centro
|
|
Toshihiro Shimizu |
890ddd |
// del cerchio inferiore
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// retta destra di equaz. alpha * x + beta * y + gammaRight = 0
|
|
Toshihiro Shimizu |
890ddd |
// retta sinistra di equaz. alpha * x + beta * y + gammaLeft = 0
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
yMin = tmax(a.y + cutIn + 1, 0) - a.y; //clipping y
|
|
Toshihiro Shimizu |
890ddd |
yMax = tmin(b.y - cutIn - 1, ly - 1) - a.y; //clipping y
|
|
Toshihiro Shimizu |
890ddd |
if (m <= 1) {
|
|
Toshihiro Shimizu |
890ddd |
// midpoint algorithm; le scanline vengono disegnate solo
|
|
Toshihiro Shimizu |
890ddd |
// sul NordEst. L'ultima scanline non viene disegnata
|
|
Toshihiro Shimizu |
890ddd |
TPoint segmRight(tceil((yMin + 0.5 - rightDown.y) / mParall + rightDown.x) - 1, yMin);
|
|
Toshihiro Shimizu |
890ddd |
TPoint segmLeft = TPoint(tceil((yMin - 0.5 - leftDown.y) / mParall + leftDown.x), yMin);
|
|
Toshihiro Shimizu |
890ddd |
int dSegmRight = tfloor(alpha * (segmRight.x + 1) + beta * (segmRight.y + 0.5) + gammaRight);
|
|
Toshihiro Shimizu |
890ddd |
int dSegmLeft = tfloor(alpha * (segmLeft.x + 1) + beta * (segmLeft.y + 0.5) + gammaLeft);
|
|
Toshihiro Shimizu |
890ddd |
while (segmRight.y <= yMax) {
|
|
Toshihiro Shimizu |
890ddd |
if (dSegmRight < 0) // segmRight a Est
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
dSegmRight = dSegmRight + incE;
|
|
Toshihiro Shimizu |
890ddd |
segmRight.x++;
|
|
Toshihiro Shimizu |
890ddd |
} else // segmRight a NordEst
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int xMin, xMax;
|
|
Toshihiro Shimizu |
890ddd |
if (k > 0) {
|
|
Toshihiro Shimizu |
890ddd |
xMin = tmax(a.x + tmax(segmLeft.x, xSegmMin), 0); // clipping x
|
|
Toshihiro Shimizu |
890ddd |
xMax = tmin(a.x + tmin(segmRight.x, xSegmMax), lx - 1); // clipping x
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
xMin = tmax(a.x - tmin(segmRight.x, xSegmMax), 0); // clipping x + ritorno alle
|
|
Toshihiro Shimizu |
890ddd |
xMax = tmin(a.x - tmax(segmLeft.x, xSegmMin), lx - 1); // coordinate "di schermo"
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *p = ras->pixels(segmRight.y + a.y) + xMin;
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *q = p + (xMax - xMin);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
while (p <= q)
|
|
Toshihiro Shimizu |
890ddd |
*p++ = col;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
dSegmRight = dSegmRight + incNE;
|
|
Toshihiro Shimizu |
890ddd |
segmRight.x++;
|
|
Toshihiro Shimizu |
890ddd |
segmRight.y++;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
while (dSegmLeft < 0) // segmLeft a Est
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
dSegmLeft = dSegmLeft + incE;
|
|
Toshihiro Shimizu |
890ddd |
segmLeft.x++;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
// segmLeft a NordEst
|
|
Toshihiro Shimizu |
890ddd |
dSegmLeft = dSegmLeft + incNE;
|
|
Toshihiro Shimizu |
890ddd |
segmLeft.x++;
|
|
Toshihiro Shimizu |
890ddd |
segmLeft.y++;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} else // m>1
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
// midpoint algorithm; le scanline vengono disegnate sempre
|
|
Toshihiro Shimizu |
890ddd |
TPoint segmRight(tround((yMin - rightDown.y) / mParall + rightDown.x), yMin);
|
|
Toshihiro Shimizu |
890ddd |
TPoint segmLeft(tround((yMin - leftDown.y) / mParall + leftDown.x), yMin);
|
|
Toshihiro Shimizu |
890ddd |
int dSegmRight = tfloor(alpha * (segmRight.x + 0.5) + beta * (segmRight.y + 1) + gammaRight);
|
|
Toshihiro Shimizu |
890ddd |
int dSegmLeft = tfloor(alpha * (segmLeft.x + 0.5) + beta * (segmLeft.y + 1) + gammaLeft);
|
|
Toshihiro Shimizu |
890ddd |
while (segmRight.y <= yMax) {
|
|
Toshihiro Shimizu |
890ddd |
int xMin, xMax;
|
|
Toshihiro Shimizu |
890ddd |
if (k > 0) {
|
|
Toshihiro Shimizu |
890ddd |
xMin = tmax(a.x + segmLeft.x, 0); // clipping x
|
|
Toshihiro Shimizu |
890ddd |
xMax = tmin(a.x + segmRight.x, lx - 1); // clipping x
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
xMin = tmax(a.x - segmRight.x, 0); // clipping x + ritorno alle
|
|
Toshihiro Shimizu |
890ddd |
xMax = tmin(a.x - segmLeft.x, lx - 1); // coordinate "di schermo"
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *p = ras->pixels(segmRight.y + a.y) + xMin;
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *q = p + (xMax - xMin);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
while (p <= q)
|
|
Toshihiro Shimizu |
890ddd |
*p++ = col;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (dSegmRight <= 0) // segmRight a NordEst
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
dSegmRight = dSegmRight + incNE;
|
|
Toshihiro Shimizu |
890ddd |
segmRight.x++;
|
|
Toshihiro Shimizu |
890ddd |
} else // segmRight a Nord
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
dSegmRight = dSegmRight + incN;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
segmRight.y++;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (dSegmLeft <= 0) // segmLeft a NordEst
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
dSegmLeft = dSegmLeft + incNE;
|
|
Toshihiro Shimizu |
890ddd |
segmLeft.x++;
|
|
Toshihiro Shimizu |
890ddd |
} else // segmLeft a Nord
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
dSegmLeft = dSegmLeft + incN;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// ---- parallelogrammoide circolare (in alternativa a parallelogramma)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// N.B. coordinate di schermo (riflessione per k<0 )
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
yMin = tmax(b.y - cutIn, 0);
|
|
Toshihiro Shimizu |
890ddd |
yMax = tmin(a.y + cutIn, ly - 1);
|
|
Toshihiro Shimizu |
890ddd |
for (y = yMin; y <= yMax; y++) {
|
|
Toshihiro Shimizu |
890ddd |
int xMin, xMax;
|
|
Toshihiro Shimizu |
890ddd |
if (k > 0) {
|
|
Toshihiro Shimizu |
890ddd |
xMin = tmax(a.x - halfCord.getCord(abs(y - a.y)), 0); // clipping x
|
|
Toshihiro Shimizu |
890ddd |
xMax = tmin(b.x + halfCord.getCord(abs(b.y - y)), lx - 1); // clipping x
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
xMin = tmax(b.x - halfCord.getCord(abs(b.y - y)), 0); // clipping x + ritorno alle
|
|
Toshihiro Shimizu |
890ddd |
xMax = tmin(a.x + halfCord.getCord(abs(y - a.y)), lx - 1); // coordinate "di schermo"
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *p = ras->pixels(y) + xMin;
|
|
Toshihiro Shimizu |
890ddd |
TPixel32 *q = p + (xMax - xMin);
|
|
Toshihiro Shimizu |
890ddd |
while (p <= q)
|
|
Toshihiro Shimizu |
890ddd |
*p++ = col;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
ras->unlock();
|
|
Toshihiro Shimizu |
890ddd |
}
|