动作:在处理中从原点到目的地绘制线条

时间:2015-12-24 17:33:32

标签: java processing

我正在尝试使用Map2.csv中存储的坐标创建一个绘制美国地图的图形。然后我使用来自Water.csv的信息添加了大湖。然后,我有data1.csv存储的各种货件的原点和目的地坐标。

我希望处理能够慢慢地从原点到目的地绘制一条线,以便您可以用眼睛跟踪货物的路径。我希望有一个顺序元素,因此可以通过相应地排序data1.csv文件以某些顺序绘制线条,但这不是必需的。

按原样编写,线条绘制得非常好,但是我的美国地图不会绘制,我收到错误说明 The sketch has been automatically resized to fit the screen resolution如果我从P2D删除size(1620,1080, P2D),地图将会绘制,但这些行将不再移动。

我的代码如下,以及相关数据的链接。

Table data;
PShape plot;

long current;

int x;
int y;

void setup(){
  size(1620, 1080, P2D);
  background(55);
  smooth();


    // Draw US Map

  String[] lines = loadStrings("Map2.csv");    // File containing coordinates to plot US Map
  stroke(55);
  strokeWeight(1);
  smooth();

  String[] pieces = split(lines[0], ',');

  for ( int i = 0; i < lines.length; i++) {

    fill(0);

    beginShape();
    current = int(pieces[0]);

    while ( current == int(pieces[0]) & i < lines.length) {

      x = int(pieces[2]);
      y = int(pieces[1]);
      vertex(x, y);
      i++;

      if ( i < lines.length) {
        pieces = split(lines[i], ',');
      }
    }
    endShape();
  }



  // Add Lakes to Map


  String[] lines2 = loadStrings("Water.csv");    // File containing coordinates to plot great lakes
  smooth();

  fill(22, 25, 180);

  String[] pieces2 = split(lines2[0], ',');
  for (int i = 0; i < lines2.length; i++)
  {

    fill(110);
    beginShape();
    current =  int(pieces2[0]);

    while (current == int(pieces2[0]) & i < lines2.length) {

      x = int(pieces2[2]);
      y = int(pieces2[1]);
      vertex(x, y);
      i++;
      if (i < lines2.length) {
        pieces2 = split(lines2[i], ',');
      }
    }
    endShape();
  }





  //create a group to store the lines from each row
  plot = createShape(GROUP);
  //load the data, specifying it has a header and it's tab separated
  data = loadTable("data2.tsv", "header, tsv");
  //traverse each row
  for (TableRow row : data.rows ()) {
    //extract each value
    int x1 = row.getInt("x1");
    int y1 = row.getInt("y1");
    int x2 = row.getInt("x2");
    int y2 = row.getInt("y2");
    //add the coordinates as lines to the group
    PShape line = createShape(LINE, x1, y1, x2, y2);
    plot.addChild(line);
  }
  shape(plot);
  strokeWeight(1.0);
}
void draw(){
  //hacky fade effect, change the alpha/transparency value to experiment with fade amount 
  background(55);
  int r = 65;
  int g = 255;
  int b = 35;
  stroke(r, g, b);
  //animate the trajectories
  //use normalized (between 0.0 and 1.0) value to traverse the paths (think of it as 0 and 100%, 0 is at the start 100% is at the end)
  //if can be interactive
  float traversal;
  if(mousePressed) {
    traversal = map(mouseX,0,width,0.0,1.0);
  }else{//or time based, up to you :)
    traversal = map(sin(frameCount * 0.01),-1.0,1.0,0.0,1.0);
  } 
  beginShape(LINES);
  //for each trajectory
  for(int i = 0 ; i < plot.getChildCount(); i++){
    PShape line = plot.getChild(i);
    //access each line's start and end points
    PVector start = line.getVertex(0);
    PVector end   = line.getVertex(1);
    //calculate the linearly interpolated point in between start end using the traversal value and lerp()
    PVector inbetween = PVector.lerp(start,end,traversal);
    //use the interpolated value to draw
    stroke(64);
    vertex(start.x,start.y);
    stroke(160);
    vertex(inbetween.x,inbetween.y);
  }
  endShape();
}

数据:  Map2 Water

DATA1 &LT; “https://docs.google.com/spreadsheets/d/1QzbCGW8H6PZgLkmWN8OyplVNTJhp3tlPGxR_Zv6lttM/edit?usp=sharing” &GT;

enter image description here

1 个答案:

答案 0 :(得分:2)

您在这里遇到了几个问题,但我会尝试逐个完成这些问题。

  

按原样编写,线条绘制得非常好,但是我的美国地图不会绘制,我收到错误说明The sketch has been automatically resized to fit the screen resolution.

我最好的猜测是,Processing无法创建大于屏幕分辨率的窗口。您可以创建一个全屏应用程序,但实际上它并不重要:您不应该将自己绑定到一个屏幕大小;您应该编写代码,以便任何窗口大小都可以工作。稍后会详细介绍。

无论如何,为了摆脱你的第一个错误,让我们使用更小的尺寸:

size(810, 540, P2D);

但现在你只能看到一些线条,因为无论窗口的大小如何,你总是画到相同的坐标。让我们改变它。

请注意draw()函数末尾的这些行:

stroke(64);
vertex(start.x,start.y);
stroke(160);
vertex(inbetween.x,inbetween.y);

请注意,您直接使用x的{​​{1}}和y值。只有当窗口和顶点值使用相同的比例时,这才有效。相反,您应缩放您的顶点值,以便它们考虑窗口的vertexwidth。一种方法是:

height

很酷,现在我们已经让您的线条以更合理的比例绘制。下一个问题:

  

但是我的美国地图不会画出

注意您在哪里绘制地图。您只需在stroke(64); vertex(width/1620.0 * start.x, height/1080.0 * start.y); stroke(160); vertex(width/1620.0 * inbetween.x, height/1080.0 * inbetween.y); 功能中绘制一次。但是你只需要在setup()函数中通过draw()调用来覆盖它,所以你永远不会看到它!

由于您在加载文件时正在绘制地图和湖泊,因此从background()函数执行此操作会减慢草图速度。您可以将地图和湖泊绘制到draw()中的PGraphics,然后在setup()中绘制PGraphics,而不是移动任何逻辑。功能

要做到这一点,首先必须在草图顶部声明一个draw()变量:

PGraphics

然后,您需要更改您的绘图代码,而不是使用PGraphics mapGraphics;

PGraphics

请注意,我还添加了缩放地图的逻辑 - 否则,您的地图对于窗口来说太大了!

然后您只需要从 // Draw US Map String[] lines = loadStrings("Map2.csv"); // File containing coordinates to plot US Map mapGraphics = createGraphics(width, height); mapGraphics.beginDraw(); mapGraphics.stroke(55); mapGraphics.strokeWeight(1); mapGraphics.smooth(); String[] pieces = split(lines[0], ','); for ( int i = 0; i < lines.length; i++) { mapGraphics.fill(0); mapGraphics.beginShape(); current = int(pieces[0]); while ( current == int(pieces[0]) & i < lines.length) { x = int(pieces[2]); y = int(pieces[1]); mapGraphics.vertex(width/1620.0 * x, height/1080.0 * y); i++; if ( i < lines.length) { pieces = split(lines[i], ','); } } mapGraphics.endShape(); } // Add Lakes to Map String[] lines2 = loadStrings("water.csv"); // File containing coordinates to plot great lakes mapGraphics.smooth(); mapGraphics.fill(22, 25, 180); String[] pieces2 = split(lines2[0], ','); for (int i = 0; i < lines2.length; i++) { mapGraphics.fill(110); mapGraphics.beginShape(); current = int(pieces2[0]); while (current == int(pieces2[0]) & i < lines2.length) { x = int(pieces2[2]); y = int(pieces2[1]); mapGraphics.vertex(width/1620.0 * x, height/1080.0 * y); i++; if (i < lines2.length) { pieces2 = split(lines2[i], ','); } } mapGraphics.endShape(); } mapGraphics.endDraw(); 函数中绘制PImage

draw()