Java 在Conway'中绘制网格[2D阵列]的平滑线;人生的游戏
tl;dr使用坐标点在阵列中绘制平滑线的快速方法是什么?注意:阅读以下信息可能会提供一些急需的上下文 我目前正在实施康威的《生命游戏》。我使用鼠标侦听器[mouseDragged,特别是]一次对两个点执行操作,并将它们传递到该方法中:Java 在Conway'中绘制网格[2D阵列]的平滑线;人生的游戏,java,arrays,graphics,conways-game-of-life,Java,Arrays,Graphics,Conways Game Of Life,tl;dr使用坐标点在阵列中绘制平滑线的快速方法是什么?注意:阅读以下信息可能会提供一些急需的上下文 我目前正在实施康威的《生命游戏》。我使用鼠标侦听器[mouseDragged,特别是]一次对两个点执行操作,并将它们传递到该方法中: public void findIndexSmoothed(int x, int y, int nx, int ny) { int size1 = size / 2 + 1; // radius size1 *=
public void findIndexSmoothed(int x, int y, int nx, int ny)
{
int size1 = size / 2 + 1; // radius
size1 *= brush;
int searchMargin = 10; // how many squares are checked within a certain
double slope;
// ((x/size) -50 >0) ? ((x/size) -50) : 0
// Optimizes performance at the expense of function
// UPDATE: a simple if/else reduced function loss to nominal levels
if (x + 2.5 < nx)
{
slope = (((double) ny - y) / (nx - x));
for (int i = 0; i < sY; i++)
{
for (int j = ((x / size) - searchMargin > 0) ? ((x / size) - searchMargin) : 0; j <
sX; j++) {
for (double c = x; c <= nx; c += 1)
{
if ((valCoord[i][j][0] >= c - size1 && valCoord[i][j][0] <= c + size1)
&& (valCoord[i][j][1] >= ((slope * (c - x)) + y) - size1 && valCoord[i][j][1] <= ((slope * (c - x)) + y)
+ size1))
{
flagVals[i][j] = true;
actualVals[i][j] = true;
cachedVals[i][j] = true;
cachedVals[i + 1][j + 1] = true;
cachedVals[i + 1][j] = true;
cachedVals[i + 1][j - 1] = true;
cachedVals[i][j + 1] = true;
cachedVals[i][j - 1] = true;
cachedVals[i - 1][j + 1] = true;
cachedVals[i - 1][j - 1] = true;
cachedVals[i - 1][j + 1] = true;
}
}
}
}
}
else if (x - 2.5 > nx)
{
slope = (((double) ny - y) / (nx - x));
int d = ((x / size) + searchMargin < sX) ? ((x / size) + searchMargin) : sX;
for (int i = 0; i < sY; i++)
{
for (int j = 0; j < d; j++)
{
for (double c = nx; c <= x; c += 1)
{
if ((valCoord[i][j][0] >= c - size1 && valCoord[i][j][0] <= c + size1)
&& (valCoord[i][j][1] >= ((slope * (c - x)) + y) - size1 && valCoord[i][j][1] <= ((slope * (c - x)) + y)
+ size1))
{
flagVals[i][j] = true;
actualVals[i][j] = true;
cachedVals[i][j] = true;
cachedVals[i + 1][j + 1] = true;
cachedVals[i + 1][j] = true;
cachedVals[i + 1][j - 1] = true;
cachedVals[i][j + 1] = true;
cachedVals[i][j - 1] = true;
cachedVals[i - 1][j + 1] = true;
cachedVals[i - 1][j - 1] = true;
cachedVals[i - 1][j + 1] = true;
}
}
}
}
}
else
{
if (ny > y)
{
for (int i = 0; i < sY; i++)
{
for (int j = ((x / size) - searchMargin > 0) ? ((x / size) - searchMargin) : 0; j < sX; j++)
{
for (double c = y; c <= ny; c++)
{
if ((valCoord[i][j][0] >= x - size1 && valCoord[i][j][0] <= x + size1)
&& (valCoord[i][j][1] >= c - size1 && valCoord[i][j][1] <= c + size1))
{
flagVals[i][j] = true;
actualVals[i][j] = true;
cachedVals[i][j] = true;
cachedVals[i + 1][j + 1] = true;
cachedVals[i + 1][j] = true;
cachedVals[i + 1][j - 1] = true;
cachedVals[i][j + 1] = true;
cachedVals[i][j - 1] = true;
cachedVals[i - 1][j + 1] = true;
cachedVals[i - 1][j - 1] = true;
cachedVals[i - 1][j + 1] = true;
}
}
}
}
}
else
{
for (int i = 0; i < sY; i++)
{
for (int j = ((x / size) - searchMargin > 0) ? ((x / size) - searchMargin) : 0; j < sX; j++)
{
for (double c = ny; c <= y; c++)
{
if ((valCoord[i][j][0] >= x - size1 && valCoord[i][j][0] <= x + size1)
&& (valCoord[i][j][1] >= c - size1 && valCoord[i][j][1] <= c + size1))
{
flagVals[i][j] = true;
actualVals[i][j] = true;
cachedVals[i][j] = true;
cachedVals[i + 1][j + 1] = true;
cachedVals[i + 1][j] = true;
cachedVals[i + 1][j - 1] = true;
cachedVals[i][j + 1] = true;
cachedVals[i][j - 1] = true;
cachedVals[i - 1][j + 1] = true;
cachedVals[i - 1][j - 1] = true;
cachedVals[i - 1][j + 1] = true;
}
}
}
}
}
}
}
public void findIndex平滑(int x,int y,int nx,int ny)
{
int size1=size/2+1;//半径
尺寸1*=刷子;
int searchMargin=10;//在一个特定范围内检查了多少个正方形
双坡;
//((x/尺寸)-50>0)?((x/尺寸)-50):0
//以牺牲功能为代价优化性能
//更新:简单的if/else将功能损失降低到标称水平
如果(x+2.50)?((x/size)-searchMargin):0;j<
sX;j++){
对于(双c=x;c=c-size1和&valCoord[i][j][0]=(斜率*(c-x))+y)-size1和&valCoord[i][j][1]nx)
{
斜率=((双)ny-y)/(nx-x));
intd=((x/size)+搜索边距0)?((x/size)-searchMargin):0;j 对于(双c=ny;c=x-size1和&valCoord[i][j][0]=c-size1和&valCoord[i][j][1]实现Bresenham的直线算法()。这非常简单,您可以直接使用数组索引作为坐标。如果您知道直线的端点,为什么会有三个嵌套循环?我希望您能够用一个来绘制直线。此外,一旦您知道斜率,您就不必在内部循环中计算它。计算外部的斜率,然后将其添加到y
每次移动x
一个单元格。只需x++;
,和y+=slope;
添加垂直线的大小写(slope=无穷大)你也必须在垂直的斜坡上增加一些聪明,以确保你得到一条连续的线。最后,仅仅为了好玩,为生命创造一个巨大的栅格是容易的,但是浪费系统资源。生命往往有一簇细胞,并且在两者之间有很多空间。Y不再相互影响。如果你有一支枪,它创造了一个滑翔机。经过10代之后,它将不再受到枪的影响。为什么不代表滑翔机在它自己的6x6子网格上?考虑一个生命游戏,它支持一个网格类,它管理动态大小的、自给的生命。@托尼,原因是两个循环A。我们需要的是,我正在传递坐标点,我需要将它们转换为格式Actuals in[#单元格的数量与它们在屏幕上的位置相比]。我这样做的方法是查看数组中某个区域内的每个位置,并确定它是否位于由两个点组成的线上。请注意点的3D数组。我认为,在这种设置下,我不能使用<3个循环。既然您提到了它,您可能会注意到其中的cachedVals数组。这是为了通过只处理活细胞和它们的邻居,可以大幅度减少处理网格空白区域的时间。我认为这个解决方案与您提到的类似。实际的索引?我不确定我会怎么做,因为我正在传递坐标点。如果您能给我一个更好的想法,您的实现记住,那太好了。@Azar拜托,wiki甚至有一些示例实现(可以很好地复制和粘贴)。它们使用的正是坐标。问题出在哪里?是的,我已经看过了(顺便说一下,没有一个是Java的),是的,使用坐标,但这就是问题所在!我需要一种干净的方法将传入的坐标转换为实际使用的格式,即数组中的位置。无论如何,我有一个想法,我会看看是否可以实现。如果是这样,我会将此标记为答案。我不认为在pascal或basic中添加花括号实现不应该要求太高。我也不认为你的格式或数组有什么问题,把索引想象成(x,y)而不是(I,j)-只是不同的名称,相同的概念。你的建议只适用于每个网格成员只有一个像素宽的情况,而不是[总是]我打算重做valCoord数组,这样索引将是X,Y坐标,它们将包含指向实际值中相应位置的数据。
for (int i = 0; i < sY; i++)
{
for (int j = ((x / size) - searchMargin > 0) ? ((x / size) - searchMargin) : 0; j <
sX; j++) {
for (double c = x; c <= nx; c += 1)
{
if ((valCoord[i][j][0] >= c - size1 && valCoord[i][j][0] <= c + size1)
&& (valCoord[i][j][1] >= ((slope * (c - x)) + y) - size1 && valCoord[i][j][1] <= ((slope * (c - x)) + y)
+ size1))
{
flagVals[i][j] = true;
actualVals[i][j] = true;
cachedVals[i][j] = true;
cachedVals[i + 1][j + 1] = true;
cachedVals[i + 1][j] = true;
cachedVals[i + 1][j - 1] = true;
cachedVals[i][j + 1] = true;
cachedVals[i][j - 1] = true;
cachedVals[i - 1][j + 1] = true;
cachedVals[i - 1][j - 1] = true;
cachedVals[i - 1][j + 1] = true;
}
}
}
public void findIndexSmoothedII(int x, int y, int nx, int ny) // A custom implementation of Bresenham's Line
// Algorithm
{
// preliminary brush size and super-sampling calculations
int use = (size / 2 + 1) * brush / size;
int shift = superSampled ? 1 : 0;
// Determine distance between points in the X and Y axes, regardless of direction
int dx = Math.abs(nx - x), dy = Math.abs(ny - y);
// Determine what type of movement to take along line, based on direction
int sx = x < nx ? 1 : -1, sy = y < ny ? 1 : -1;
// threshold of offset before incrementing
int err = (dx > dy ? dx : -dy) / 2;
// The (sX,sY) values converted from the raw coordinates
int xS, yS;
while (true)
{
// if Both x and y have been incremented to the location of the second point, line is drawn and the algorithim
// can end
if (x == nx && y == ny)
break;
// Determine where cursor is in terms of (sY,sX) and handle border cases for X-Axis
if ((x / size) - use > 0 && (x / size) + use < sX)
xS = x / size;
else if ((x / size) - use > 0 && (x / size) + use >= sX)
xS = 5000;
else
xS = -5000;
// Determine where cursor is in terms of (sY,sX) and handle border cases for Y-Axis
if ((y / size) - use > 0 && (y / size) + use < sY)
yS = y / size;
else if ((y / size) - use > 0 && (y / size) + use >= sY)
yS = 5000;
else
yS = -5000;
// Below loops are responsible for array access and accounting for brush size
for (int j = yS - (use << shift); j < yS + (use << shift); j++)
{
for (int i = xS - (use << shift); i < xS + (use << shift); i++)
{
if (i < sX - 3 && i > 2 && j > 2 && j < sY - 3)
{
flagVals[j][i] = true;
actualVals[j][i] = true;
cachedVals[j][i] = true;
cachedVals[j + 1][i + 1] = true;
cachedVals[j + 1][i] = true;
cachedVals[j + 1][i - 1] = true;
cachedVals[j][i + 1] = true;
cachedVals[j][i - 1] = true;
cachedVals[j - 1][i + 1] = true;
cachedVals[j - 1][i - 1] = true;
cachedVals[j - 1][i + 1] = true;
}
}
}
// determine where to point to next
int e2 = err;
if (e2 > -dx)
{
err -= dy;
x += sx;
}
if (e2 < dy)
{
err += dx;
y += sy;
}
}
}