你可以简单地使用PGraphics。这个想法是,一旦你有了一个 PGraphics 实例,你就可以使用点符号来访问以前使用的绘图函数(只要它们在.beginDraw()
and之间调用.endDraw()
)。
使用noSmooth()
你可以让它看起来像素完美。
这是一个基本草图来说明这个想法:
// disable anti-aliasing
noSmooth();
// create a PGraphics layer
PGraphics layer = createGraphics(25, 25);
// render a line
layer.beginDraw();
layer.line(0, 24, 24, 0);
layer.endDraw();
// render the line at 100%
image(layer, 0, 0);
// render the line scaled up
image(layer, 0, 0, width, height);
![100% 和 400% 比例的光栅化线条图,没有平滑(锯齿)](https://i.stack.imgur.com/L6r7P.jpg)
这应该适用于大多数情况。(只有具有非常小的值和透明度的更棘手的情况可能会让您头疼)
如果由于某种原因您需要更多的控制,您总是可以实现自己的光栅化方法。您可能可以从Bresenham 的线算法开始的地方
关于您的代码,有一些可能出错的地方:
float deltaPixl = deltaX/deltaY;
:如果 deltaY 为零,您将遇到异常
- 您正在为
deltaX
and进行整数除法deltaY
(可能使其对于任何一个值都可能为 0)
- 您应该
println()
在 for 循环之前尝试一个带有开始/结束值的语句,以了解该循环是否会实际执行。此外,在for
循环中,您可以println(i)
查看是否获得了您期望的值。
总的来说,我建议查看Kevin Workman 的如何调试指南。
此外,您可以使用lerp()来计算线的起点和终点之间的线性插值位置。传递每个坐标和一个标准化(0.0、1.0 之间)值,其中 0.0 = 在起点,1.0 = 在终点,中间的任何值都在线上(例如 0.5 = 沿线的 50%)。
这是一个基本示例:
void drawLinePoints(int x1, int y1, int x2, int y2, int numberOfPoints){
// for each point
for(int i = 0; i < numberOfPoints; i++){
// map the counter to a normalized (0.0 to 1.0) value for lerp
// 0.0 = 0 % along the line, 0.5 = 50% along the line, 1.0 = 100% along the line
float t = map(i, 0, numberOfPoints, 0.0, 1.0);
// linearly interpolate between the start / end points (and snap to whole pixels (casting to integer type))
int x = (int)lerp(x1, x2, t);
int y = (int)lerp(y1, y2, t);
// render the point
point(x, y);
}
}
void setup(){
// render points are large squares
strokeWeight(6);
strokeCap(PROJECT);
}
void draw(){
// clear frame
background(255);
// calculate distance
float distance = dist(10, 10, mouseX, mouseY);
// map distance the number of points to illustrate interpolation (more points = continuous line)
int numPoints = (int)distance / 8;
// render points along the line
drawLinePoints(10, 10, mouseX, mouseY, numPoints);
}
![沿垂直线的插值点呈现为白色背景上的黑色方块](https://i.stack.imgur.com/2Lorf.jpg)
![沿对角线的插值点呈现为白色背景上的黑色方块](https://i.stack.imgur.com/EtMVg.jpg)
为了完整起见,这里使用了上面的代码片段pixels[]
:
void drawLinePoints(int x1, int y1, int x2, int y2, int numberOfPoints){
// for each point
for(int i = 0; i < numberOfPoints; i++){
// map the counter to a normalized (0.0 to 1.0) value for lerp
// 0.0 = 0 % along the line, 0.5 = 50% along the line, 1.0 = 100% along the line
float t = map(i, 0, numberOfPoints, 0.0, 1.0);
// linearly interpolate between the start / end points (and snap to whole pixels (casting to integer type))
int x = (int)lerp(x1, x2, t);
int y = (int)lerp(y1, y2, t);
// convert the x, y coordinate to pixels array index and render the point in black
pixels[x + (y * width)] = color(0);
}
}
void setup(){
noSmooth();
}
void draw(){
// clear frame
loadPixels();
java.util.Arrays.fill(pixels, color(255));
// calculate distance
float distance = dist(10, 10, mouseX, mouseY);
// map distance the number of points to illustrate interpolation (more points = continuous line)
int numPoints = (int)distance;
// render points along the line
drawLinePoints(10, 10, mouseX, mouseY, numPoints);
// update pixels
updatePixels();
}
![在 100x100 栅格中的捕捉像素处渲染的插值线](https://i.stack.imgur.com/PvceN.jpg)