Project1
标题:
求联结两点的方法
[打印本页]
作者:
IamI
时间:
2010-9-12 17:39
标题:
求联结两点的方法
本帖最后由 IamI 于 2010-9-23 14:07 编辑
如题。最近比较懒,什么都不想弄……
求定义Sprite#lineto(x0,y0,x,y,color),以color色在该sprite的Bitmap上联结此两点。
要求:这条线是“致密的”。
x0,y0,x,y是Float。
每帧调用1次,不掉帧。
作者:
禾西
时间:
2010-9-12 17:39
本帖最后由 禾西 于 2010-9-13 02:29 编辑
class Bitmap
#// Wu algorithm
#--------------------------------------------------------------------------
# ● 描绘直线
# x1,y1,x2,y2: 直线两端的坐标
# color: 颜色
#--------------------------------------------------------------------------
def drawline(x1, y1, x2, y2, color)
x1 = x1.to_f
y1 = y1.to_f
x2 = x2.to_f
y2 = y2.to_f
draw_a_wuline(x1,y1,x2,y2,color)
end
def plot(x,y,c, ori_color)
color = ori_color.clone
color.alpha = 255 * c
set_pixel(x, y, color)
end
def ipart(x)
return x.floor
end
def fpart(x)
return (x - x.floor)
end
def rfpart(x)
return 1 - fpart(x)
end
def draw_a_wuline(x1,y1,x2,y2,color)
dx = x2 - x1 #horizontal distance
dy = y2 - y1 #perpendicular distance
if dx.abs < dy.abs
x1, x2 = x2, x1
y1, y2 = y2, y1
dx, dy = dy, dx
end
if x2 < x1
x1, x2 = x2, x1
y1, y2 = y2, y1
end
# find slope
gradient = dy/dx
# find initial endpoint
xend = x1.round
yend = y1 + gradient * (xend - x1) # y + k(xend - x)
xgap = rfpart(x1 + 0.5)
xpxl1 = xend # this will be used in the main loop
ypxl1 = ipart(yend)
plot(xpxl1, ypxl1, rfpart(yend) * xgap, color)
plot(xpxl1, ypxl1 + 1, fpart(yend) * xgap, color)
intery = yend + gradient # first y-intersection for the main loop
# find terminal endpoint
xend = x2.round
yend = y2 + gradient * (xend - x2)
xgap = fpart(x2 + 0.5)
xpxl2 = xend # this will be used in the main loop
ypxl2 = ipart(yend)
plot(xpxl2, ypxl2, rfpart(yend) * xgap, color)
plot(xpxl2, ypxl2 + 1, fpart(yend) * xgap, color)
# main loop
for x in (xpxl1 + 1) ... (xpxl2 - 1)
plot(x, ipart(intery), rfpart(intery), color)
plot(x, ipart(intery) + 1, fpart(intery), color)
intery = intery + gradient
end
end
end
复制代码
作者:
紫苏
时间:
2010-9-12 22:00
本帖最后由 紫苏 于 2010-9-13 00:08 编辑
这种东西在 DLL 中处理比较好,之前弄过一个:
void __stdcall DrawLine(register short x1, register short y1, register short x2, short y2, unsigned &clr, Bitmap &bitmap) {
register bool steep;
register char step;
register short dx, dy;
register int err;
seek(bitmap);
dx = abs(x2 - x1);
dy = abs(y2 - y1);
steep = dy > dx;
if(steep) {
swap(x1, y1);
swap(x2, y2);
}
if(x1 > x2) {
swap(x1, x2);
swap(y1, y2);
}
step = y1 < y2 ? 1 : -1;
if(steep) {
err = dy/2;
for(; x1 <= x2; ++x1) {
plot(y1, x1, clr, bitmap);
err -= dx;
if(err < 0) {
y1 += step;
err += dy;
}
}
} else {
err = dx/2;
for(; x1 <= x2; ++x1) {
plot(x1, y1, clr, bitmap);
err -= dy;
if(err < 0) {
y1 += step;
err += dx;
}
}
}
}
复制代码
用的是目前公认最快的 Bresenham 直线算法
辅助函数,算 Bitmap 地址的那个(seek)是比较重要的:
struct Bitmap {
short width;
short height;
unsigned id;
unsigned *bits;
};
void __stdcall seek(Bitmap &bitmap) {
unsigned *&bits = bitmap.bits;
if(0 == bits) {
bits = (unsigned *)((bitmap.id << 1) + 16);
bits = (unsigned *)(*bits + 8);
bits = (unsigned *)(*bits + 16);
bits = (unsigned *)*bits;
}
}
short __stdcall abs(short &x) {
return x < 0 ? -x : x;
}
void __stdcall swap(short &x, short &y) {
x ^= y;
y ^= x;
x ^= y;
}
复制代码
欢迎光临 Project1 (https://rpg.blue/)
Powered by Discuz! X3.1