Java 在Conway'中绘制网格[2D阵列]的平滑线;人生的游戏

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 *=

tl;dr使用坐标点在阵列中绘制平滑线的快速方法是什么?注意:阅读以下信息可能会提供一些急需的上下文

我目前正在实施康威的《生命游戏》。我使用鼠标侦听器[mouseDragged,特别是]一次对两个点执行操作,并将它们传递到该方法中:

     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;
        }
    }
}