点击之间的绘制线从左上角绘制

时间:2015-10-28 10:15:12

标签: java drawing processing

我目前正在尝试使用处理功能创建程序,从所有鼠标点击到新鼠标点击。 作为一方,它还应该将点击保存在二维数组中。

    public void setup() {
        size(500,500);
    }

    int clickcount = 0;
    int storedclicks = 10000;
    int[] mouseclickX = new int [storedclicks];
    int[] mouseclickY = new int [storedclicks];

    public void draw() {
        background(80);
        drawing();
    }

    public void mousePressed() {

        if(clickcount >= storedclicks) {
            clickcount = 0;
        }

        mouseclickX[clickcount] = mouseX;
        mouseclickY[clickcount] = mouseY;
        clickcount++;

    }

    public void drawing() {
        beginShape(LINES);
            for (int i = 0; i < storedclicks; i++) {
                vertex(mouseclickX[i], mouseclickY[i]);
            }
            endShape();
    }
}

有些东西适用于我现在的代码,但有些东西并没有为我加起来。就像现在一样,在第一次点击时我从左上角得到一条线,然后点击该线消失,我从该线的终点得到一条新线,第一条线消失。

接下来,点击从角落到点击点的新线(第2行仍然存在)。然后它就会继续。

我想如果我将storeclicks更改为5之类的数字,它就不会从角落里做的事情,只是来自之前每个点击位置的新行。

这听起来有点令人困惑,所以这里有一张图片可供帮助(点击3次后): enter image description here

3 个答案:

答案 0 :(得分:1)

一些注意事项:

我使用了一个生命环缓冲区(您可以使用链接列表进行模拟)或类似内容来存储点击次数,这样您就不必单独检查storedclicks它应该因为从前面移除元素时缓冲区的头部会移动,所以绘制更容易。

此外,如果列表/缓冲区中至少有两个点,我只会绘制线条。

第三,为了防止同步问题(仅更新x或y)我使用Point个对象的列表/缓冲区/数组(自己创建或使用java.awt.Point)而不是两个单独的x和y数组。

至于你的绘图代码,你应该遍历存储的点而不是所有元素(大多数可能是空的),即像这样:

使用您的代码时:

if( clickcount > 1 ) {
  for (int i = 0; i < clickcount ; i++) {
     vertex(mouseclickX[i], mouseclickY[i]);
  }
}

使用列表/环形缓冲区以及Point个对象时:

if( list.size() > 1 ) {
  for (Point clickpos : list ) {
     vertex(clickpos.x, clickpos.y);
  }
}

最后,如果处理类似于OpenGL(我不知道处理),形状类型LINES会在两个顶点之间画一条线,即每个不平顶点都是一个线起点,每个偶数顶点都是一行结束。您可能需要的是类似LINE_STRIP(不知道名称或是否存在于处理中),这使得渲染器在所有顶点之间绘制线条(即从0到1,从1到2等)。 )

修改

作为对您发布的图片中情况的解释,我假设点击是从右到左排序的(索引0,1,2)。如果是这种情况,那么我就这样解释一下(详见上文):

  • 在第0点和第1点之间绘制第一条线,这没关系。
  • 第二行是在第2点和第3点之间绘制的(参见关于循环的段落以及LINES resp。线条),这不是你想要的。
  • 第三行(如果storedclicks > 5)将在第4点和第5点之间绘制,这是一个点,因为两个顶点的坐标都是0/0。
  • 对以下所有行重复上述要点(再次参见有关循环的段落)。

正如您所看到的,有两个问题:

  • 您想要绘制0到1之间以及1到2之间的线条,这就是为什么我建议使用线条(如果在处理中存在,否则您必须重复使用最后一点)。
  • 您想要在索引2处停止,即忽略从3开始的所有索引,这就是我提到在循环条件中不使用storedclicks的原因。)

答案 1 :(得分:0)

要了解草图中发生的情况,请查看the reference

此代码:

beginShape(LINES);
vertex(30, 20);
vertex(85, 20);
vertex(85, 75);
vertex(30, 75);
endShape();

生成此图片:

所以,这就是为什么你没有画出你的线段的间隙。您可能希望使用no-args LINES函数以及beginShape()函数,而不是使用endShape(CLOSE)

noFill();
beginShape();
vertex(30, 20);
vertex(85, 20);
vertex(85, 75);
vertex(30, 75);
endShape(CLOSE);

至于为什么你在0,0得到一个点:请记住,默认情况下int数组被初始化为包含所有零。因此,当您遍历整个数组时,最终会在0,0处绘制一堆点。相反,您可能需要一个单独的变量来跟踪总点击次数(当您达到要保留的最大点击次数时,您会停止更新)。

  

作为一方,它还应该将点击保存在二维数组中。

请注意,您不是将点击存储在二维数组中。您将它们存储在两个一维数组中,也称为并行数组。这通常是一个糟糕的设计。相反,请考虑使用Processing的PVector类以及ArrayList而不是数组。这样,您可以跟踪您拥有的有效点击次数,而无需我上面提到的单独变量。

总而言之,它可能看起来像这样:

ArrayList<PVector> clicks = new ArrayList<PVector>();

public void setup() {
  size(500, 500);
}

public void draw() {
  background(80);
  drawing();
}

public void mousePressed() {
  clicks.add(new PVector(mouseX, mouseY));
  if(clicks.size() > 5){
    clicks.remove(0);
  }
}

public void drawing() {
  noFill();
  beginShape();
  for(PVector v : clicks){
    vertex(v.x, v.y);
  }
  endShape(CLOSE);
}
  

从所有鼠标点击中绘制线条到新的鼠标点击。

如果不是一个封闭的多边形,你想要一个类似蜘蛛网的东西,将每个点连接到每个其他点,那么你只需要遍历每次点击并绘制连接线:

public void drawing() {
  for (PVector v1 : clicks) {
    for (PVector v2 : clicks) {
      line(v1.x, v1.y, v2.x, v2.y);
    }
  }
}

答案 2 :(得分:0)

Just to add to the existing great answers, here's a hacky approach that simply takes advantage of not clearing the background: int lastClickX = -1; int lastClickY = -1; void setup(){ size(500,500); background(80); } void draw(){} void mouseReleased(){ if(lastClickX >= 0 && lastClickY >= 0) line(mouseX,mouseY,lastClickX,lastClickY); lastClickX = mouseX; lastClickY = mouseY; } You can run this as demo bellow: var lastClickX = -1; var lastClickY = -1; function setup(){ createCanvas(500,500); background(80); } function draw(){} function mouseReleased(){ if(lastClickX >= 0 && lastClickY >= 0) line(mouseX,mouseY,lastClickX,lastClickY); lastClickX = mouseX; lastClickY = mouseY; } <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.4.17/p5.min.js"></script> Bare in mind, although this method doesn't store position, it simply takes advantage of not clearing the screen, which isn't the most flexible of options.