Napisałem sobie alg. wg. przepisu (graficznego) mojego prowadzącego AntyAliasingu. Coś robi poprawnie, ale nie do końca. W zależności od gałęzi |x| >= |y| lub na odwrót albo góra albo dół linii jest nieatyaliasowany, natomiast drugi brzeg jest antyaliasowany. Ktoś mógłby podać linka do poprawnego multisamplingu lub pomóc w rozgryzieniu tej zagadki?
Kod (w paczce z resztą też jest)
private void AntyAliasedLineDraw(Point from, Point to, int grubosc)
{
double offsetX = to.X - from.X;
double offsetY = to.Y - from.Y;
var fromX = from.X;
var fromY = from.Y;
var toX = to.X;
var toY = to.Y;
if (Math.Abs(offsetX) >= Math.Abs(offsetY))
{
// robimy po x
if (from.X > to.X)
{
fromX = to.X;
fromY = to.Y;
toX = from.X;
toY = from.Y;
offsetX = -offsetX;
offsetY = -offsetY;
}
var yPerPixel = offsetY/offsetX;
double actualHeight = _Sampling*fromY;
for (var j = _Sampling * fromX; j <= _Sampling * toX; j++) // robimy po X-ach
{
var bottom = (int)Math.Floor((double)actualHeight + grubosc*_Sampling);
var top = (int)Math.Ceiling((double) actualHeight);
for (var i = top; i <= bottom; i++)
_Pkts[j,i] = true;
actualHeight += yPerPixel;
}
actualHeight = fromY;
for (var j = fromX; j <= toX; j++)
{
var bottom = (int)Math.Floor((double)actualHeight + grubosc);
var top = (int)Math.Ceiling((double)actualHeight);
for (var i = top; i <= bottom; i++ )
{
var ile = 0;
for (var k = 0; k < _Sampling; k++) // x
for (var l = 0 ; l < _Sampling; l++) // y
{
if (_Pkts[_Sampling * j + k, _Sampling * i + l] == true)
{
_Pkts[_Sampling*j + k, _Sampling*i + l] = false;
++ile;
}
}
var stos = (double) ile/(double) (_Sampling*_Sampling);
stos = 1 - stos;
//var stos = 0;
var war = (int)Math.Floor(255.00*stos);
_Bmp.SetPixel(j, i, Color.FromArgb(war, war, war));
}
actualHeight += yPerPixel;
}
}
else
{
// robimy po y
if (from.Y > to.Y)
{
fromX = to.X;
fromY = to.Y;
toX = from.X;
toY = from.Y;
offsetX = -offsetX;
offsetY = -offsetY;
}
var xPerPixel = offsetX / offsetY;
double actualWidth = _Sampling * fromX;
for (var i = _Sampling * fromY; i <= _Sampling * toY; i++) // robimy po X-ach
{
var right = (int)Math.Floor((double)actualWidth + grubosc * _Sampling);
var left = (int)Math.Ceiling((double)actualWidth);
for (var j = left; j <= right; j++)
_Pkts[j, i] = true;
actualWidth += xPerPixel;
}
actualWidth = fromX;
for (var i = fromY; i <= toY; i++)
{
var right = (int)Math.Floor((double)actualWidth + grubosc);
var left = (int)Math.Ceiling((double)actualWidth);
for (var j = left; j <= right; j++)
{
var ile = 0;
for (var l = 0; l < _Sampling; l++) // y
for (var k = 0; k < _Sampling; k++) // x
{
if (_Pkts[_Sampling * j + k, _Sampling * i + l] == true)
{
_Pkts[_Sampling*j + k, _Sampling*i + l] = false;
++ile;
}
}
var stos = (double)ile / (double)(_Sampling * _Sampling);
stos = 1 - stos;
//var stos = 0;
var war = (int)Math.Floor(255.00 * stos);
_Bmp.SetPixel(j, i, Color.FromArgb(war, war, war));
}
actualWidth += xPerPixel;
}
}
}