我需要通过引入反锯齿线来升级一个旧的VCL图形应用程序。为此,我用C编写了https://en.wikipedia.org/wiki/Xiaolin_Wu%27s_line_algorithm页中指出的算法。代码如下。不幸的是,我没有找到任何方法或手段来推导C Builder的“亮度”,不同颜色的亮度如何?
//Antialiased line:
void Observer::aaLine(int x0, int y0, int x1, int y1)
{
//Draws the pixel point (x,y) with specified brightness, 0 <= br <= 1 :
auto plot = [&](double X, double Y, double brighness){
pC->Pixels[X][Y] = brightness; };
//Fractional part of x:
auto fpart = [](double x) { return x - floor(x); };
auto rfpart = [&](double x) { return 1 - fpart(x); };
bool steep = abs(y1 - y0) > abs(x1 - x0);
if(steep) {
std::swap(x0, y0);
std::swap(x1, y1);
}
if( x0 > x1 ) {
std::swap(x0, x1);
std::swap(y0, y1);
}
auto dx = x1 - x0;
auto dy = y1 - y0;
double gradient;
if( dx == 0.0 )
gradient = 1.0;
else
gradient = dy / dx;
//Handle first endpoint
auto xend = round(x0),
yend = y0 + gradient * (xend - x0),
xgap = rfpart(x0 + 0.5),
xpxl1 = xend, // this will be used in the main loop
ypxl1 = floor(yend);
if( steep ) {
plot(ypxl1, xpxl1, rfpart(yend) * xgap);
plot(ypxl1+1, xpxl1, fpart(yend) * xgap);
}
else {
plot(xpxl1, ypxl1 , rfpart(yend) * xgap);
plot(xpxl1, ypxl1+1, fpart(yend) * xgap);
}
auto intery = yend + gradient; // first y-intersection for the main loop
//Handle second endpoint
xend = round(x1);
yend = y1 + gradient * (xend - x1);
xgap = fpart(x1 + 0.5);
auto xpxl2 = xend, //this will be used in the main loop
ypxl2 = floor(yend);
if( steep ){
plot(ypxl2 , xpxl2, rfpart(yend) * xgap);
plot(ypxl2+1, xpxl2, fpart(yend) * xgap);
}
else {
plot(xpxl2, ypxl2, rfpart(yend) * xgap);
plot(xpxl2, ypxl2+1, fpart(yend) * xgap);
}
//Main loop:
if( steep )
for(double x = xpxl1 + 1 ; x <= xpxl2 - 1 ; x += 1)
{
plot(floor(intery) , x, rfpart(intery));
plot(floor(intery)+1, x, fpart(intery));
intery += gradient;
}
else
for(double x = xpxl1 + 1 ; x <= xpxl2 - 1 ; x += 1)
{
plot(x, floor(intery), rfpart(intery));
plot(x, floor(intery)+1, fpart(intery));
intery += gradient;
}
}//Observer::aaLine.
问题位于(我相信)函数的lambda顶部。非常感谢。
1条答案
按热度按时间kmbjn2e31#
我认为你的问题就在于此:
如果我没理解错的话,pC是某个目标
TCanvas
......这有两个主要问题:pC->Pixels[X][Y] = brightness;
将根据所选模式(如复制、异或等)将brightness
处理为颜色,而不是亮度。我会使用alpha混合的形式,你采取原始渲染颜色(或背景)和渲染线的想要的颜色,并将其与
brightness
混合作为参数:注意VCL透明度不使用alpha参数,它只是不透明或不...有关混合的更多信息,请参见类似的:
尤其要注意:
因为TColor是32位整数...
pC->Pixels[X][Y]
的速度充其量也是可怜的如果你要处理很多像素,你应该考虑使用
Graphics::TBitmap
中的ScanLine[Y]
...并渲染到位图作为后备缓冲区。这通常会将速度提高约1000到约10000倍。有关更多信息,请参阅: