运动:在处理中绘制一条从起点到终点的线 [英] Motion: Drawing a Line from an Origin to a Destination in Processing

查看:73
本文介绍了运动:在处理中绘制一条从起点到终点的线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我希望处理过程能够以足够慢的速度从起点到终点划一条线,以便您可以用眼睛跟踪货件的路径.我希望有一个顺序元素,以便可以通过相应地对 data1.csv 文件进行排序来按特定顺序绘制线条,但这不是必需的.

按原样写,线条画得很好,但是我的美国地图无法绘制,并且出现错误说明草图已自动调整大小以适应屏幕分辨率 如果我从 size(1620,1080, P2D) 中删除 P2D 地图将绘制,但线条将不再移动.

下面是我的代码以及相关数据的链接.

表格数据;PShape 图;长电流;整数 x;输入 y;无效设置(){尺寸(1620、1080、P2D);背景(55);光滑的();//绘制美国地图String[] lines = loadStrings("Map2.csv");//包含绘制美国地图坐标的文件行程(55);行程重量(1);光滑的();String[]pieces = split(lines[0], ',');for ( int i = 0; i 

数据:

解决方案

您在这里有几个问题,但我会尝试一次解决一个.

<块引用>

按原样书写,线条画得很好,但是我的美国地图无法绘制,并且出现错误提示草图已自动调整大小以适应屏幕分辨率.

我最好的猜测是,Processing 无法创建大于屏幕分辨率的窗口.您可以创建一个全屏应用程序,但实际上这无关紧要:您不应该将自己束缚在一个屏幕尺寸上;您应该编写代码,以便任何窗口大小都可以使用.稍后会详细介绍.

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

size(810, 540, P2D);

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

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

stroke(64);顶点(start.x,start.y);行程(160);顶点(inbetween.x,inbetween.y);

请注意,您正在直接使用 vertexxy 值.只有当您的窗口和顶点值使用相同的比例时,这才有效.相反,您应该缩放您的顶点值,以便它们考虑到窗口的widthheight.一种方法是这样的:

stroke(64);顶点(宽度/1620.0 * start.x,高度/1080.0 * start.y);行程(160);顶点(宽度/1620.0 * inbetween.x,高度/1080.0 * inbetween.y);

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

<块引用>

但是我的美国地图不会绘制

注意您绘制地图的位置.您只需在 setup() 函数中一次绘制它.但是,您只需在 draw() 函数中使用 background() 调用将其绘制出来,这样您就永远看不到它了!

由于您在加载文件时绘制地图和湖泊,因此从 draw() 函数执行此操作会减慢您的草图速度.无需移动任何逻辑,您只需将地图和湖泊绘制到 setup() 中的 PGraphics,然后绘制该 PGraphics 在您的 draw() 函数中.

为此,您首先必须在草图顶部声明一个 PGraphics 变量:

PGraphics mapGraphics;

然后您将更改绘图代码以使用该 PGraphics 代替:

//绘制美国地图String[] lines = loadStrings("Map2.csv");//包含绘制美国地图坐标的文件mapGraphics = createGraphics(width, height);mapGraphics.beginDraw();mapGraphics.stroke(55);mapGraphics.strokeWeight(1);mapGraphics.smooth();String[] 件 = split(lines[0], ',');for ( int i = 0; i 

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

然后你只需要从你的 draw() 函数中绘制 PImage :

void draw() {//hacky 淡入淡出效果,更改 alpha/透明度值以尝试淡入淡出量背景(55);图像(地图图形,0, 0);//...

I'm trying to create a graphic that plots a map of the United States using coordinates stored in Map2.csv. Then I add the great lakes using information from Water.csv. I then have origin and destination coordinates for various shipments that were made stored in data1.csv.

I want processing to draw a line from origin to destination slowly enough that you can track the path of the shipment with your eye. I'd like there to be a sequential element so the lines could be drawn in certain orders by sorting the data1.csvfile accordingly, but that's not a necessity.

Written as is, the lines draw very nicely, however my map of the US will not draw and I get an error stating The sketch has been automatically resized to fit the screen resolution If I delete P2D from size(1620,1080, P2D)the map will draw, but the lines will no longer move.

My code is below along with links to the relevant data.

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

Data: Map2 Water.

data1 <"https://docs.google.com/spreadsheets/d/1QzbCGW8H6PZgLkmWN8OyplVNTJhp3tlPGxR_Zv6lttM/edit?usp=sharing">

解决方案

You've got a couple questions here, but I'll try to go through them one at a time.

Written as is, the lines draw very nicely, however my map of the US will not draw and I get an error stating The sketch has been automatically resized to fit the screen resolution.

My best guess is that Processing can't create windows that are bigger than the resolution of the screen. You can create a full-screen application, but really it shouldn't matter: you shouldn't tie yourself to one screen size; you should write your code so any window size will work. More on that later.

Anyway, to get rid of your first error, let's just use a smaller size:

size(810, 540, P2D);

But now you only see some of your lines, since you're always drawing to the same coordinates regardless of the window's size. Let's change that.

Notice these lines at the end of your draw() function:

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

Notice that you're using the x and y values of the vertex directly. This will only work as long as your window and vertex values are using the same scale. Instead, you should scale your vertex values so that they take into account the width and height of the window. One way to do that is this:

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

Cool, now we've got your lines drawing in a more reasonable scale. Next problem:

however my map of the US will not draw

Notice where you're drawing your map. You're only drawing it once, in your setup() function. But then you just draw over it in the draw() function with the background() call, so you never see it!

Since you're drawing the map and lakes as you load the file, doing that from the draw() function will slow your sketch down. Instead of moving any of your logic around, you could just draw your map and lakes to a PGraphics in setup(), then just draw that PGraphics in your draw() function.

To do that, you first have to declare a PGraphics variable at the top of your sketch:

PGraphics mapGraphics;

Then you'd change your drawing code to use that PGraphics instead:

  // 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();

Notice that I've also added the logic for scaling the map- otherwise, your map would be too big for the window!

Then you just need to draw that PImage from your draw() function:

void draw() {
  //hacky fade effect, change the alpha/transparency value to experiment with fade amount 
  background(55);
  image(mapGraphics, 0, 0);
  //...

这篇关于运动:在处理中绘制一条从起点到终点的线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆