如何在 Processing 中点对点画线
How to draw a line from point to point in Processing
我正在尝试生成一个图形,用一条线从起点到目的地绘制货运路径。我已将纬度和经度数据转换为适合美国地图的像素 (1620, 1080)。
当前的书写方式是按照它们在我的 csv 文件中的排序方式顺序绘制的。但是,我希望这些线从起点辐射到终点。现在我只能想办法把已经画好的线放下来。
我认为代码的相关部分在 // Draw Lines
。
long current;
int x;
int y;
ArrayList loads;
void setup() {
size(1620, 1080);
background(55);
smooth();
frameRate(15);
// 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();
}
// Draw Lines
loads = new ArrayList();
String[] loadset = loadStrings("data1.csv");
for ( int i3 = 0; i3 < loadset.length; i3++) {
String[] loads2 = split(loadset[i3], ',');
loads.add( new Lane(int(loads2[0]), int(loads2[1]), int(loads2[2]), int(loads2[3])) );
}
}
int i=1;
int imax = 1;
int incmult = 1;
void draw() {
if (i < loads.size()-imax){
for(int iadd = 0; iadd < imax; iadd++)
{
Lane Lane = (Lane) loads.get(iadd);
Lane.display();
Lane = (Lane) loads.get(i+iadd);
Lane.display();
}
i +=imax;
}
imax = imax + incmult;
}
class Lane {
int x;
int y;
int x2;
int y2;
Lane( int tempX, int tempY, int tempX2, int tempY2) {
x = tempX;
y = tempY;
x2 = tempX2;
y2 = tempY2;
}
void display() {
int r = 65;
int g = 255;
int b = 35;
strokeWeight(1);
stroke(r, g, b, 55);
line(x, y, x2, y2);
stroke(255, 255, 255); // Origin
fill(255, 255, 255, 55);
ellipse(x, y, 3, 3);
stroke(171, 62, 193); // Destination
fill(171, 62, 193);
ellipse(x2, y2, 3, 3);
}
}
我的 data1.csv
文件包含四列 x, y, x2, y2
,其中 (x, y)
表示原点,(x2, y2)
表示目标坐标。
// data.csv
data[0] data[1] data[2] data[3]
929 327 602 507
1335 458 1327 782
1422 325 848 744
1302 280 1118 458
1041 583 1193 666
1267 616 1058 394
1215 671 1351 857
1334 851 1410 946
1334 851 1409 916
828 761 861 653
1386 323 1203 594
1037 293 1013 522
908 869 958 532
1029 331 1053 409
906 357 828 761
. . . .
. . . .
更新
我已经添加了指向我的数据的链接,因为我仍然无法按照我的设想绘制图像。
目前问题还不是很清楚,所以当前形式的回答不完整。
以下是一些可以简化代码并希望有助于实现最终目标的建议:
- 使用 loadTable(). It supports the tab support and headers as your sample data. The nice thing about parsing the headers is that you can use the column label to parse each value using functions readily available functions like getInt()
尝试 Processing 的内置 CSV 解析器
- 尝试使用 PShape:您可以在设置中设置一次绘制命令,然后在一个命令中渲染最终形状。优点是您可以在需要时访问以后使用的形状和顶点。
这是一个使用此 TSV 的基本示例,该示例基于以上保存为 data.tsv
的数据
Table data;
PShape dataPlot;
size(1620, 1080,P2D);
//create a group to store the lines from each row
dataPlot = createShape();
//load the data, specifying it has a header and it's tab separated
data = loadTable("data.tsv", "header, tsv");
//traverse each row
dataPlot.beginShape(LINES);
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
dataPlot.stroke(160);
dataPlot.vertex(x1,y1);
dataPlot.stroke(0);
dataPlot.vertex(x2,y2);
}
dataPlot.endShape();
//render the plot
shape(dataPlot);
使用深灰色到浅灰色显示路径的起点和终点,这是使用部分示例数据的结果:
如果您需要在创建 PShape 实例后访问每个顶点,您可以使用 getVertex()。它需要您可能想要检索的顶点的索引。
例如,dataPlot.getVertex(0);
和 dataPlot.getVertex(1);
将 return 第一行的坐标,dataPlot.getVertex(2);
和 dataPlot.getVertex(2);
将 return 第二行的坐标等等。
如果管理树状层次结构而不是顶点索引更容易,您可以创建 PShape 组。唯一需要注意的是,创建的以下子 PShape 实例将使用以 set 为前缀的函数绘制,而不是典型的 stroke()
/fill()
/等。你已经习惯了:setStroke()
/setFill()
/etc.
下面是一个使用 PShape 组并将距离映射到线条颜色和粗细的代码示例:
Table data;
PShape dataPlot;
size(1620, 1080, P2D);
//create a group to store the lines from each row
dataPlot = createShape(GROUP);
//load the data, specifying it has a header and it's tab separated
data = loadTable("data.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);
float dist = dist(x1, y1, x2, y2);
line.setStroke(color(map(dist, 0, height, 160, 0)));
line.setStrokeWeight(map(dist, 0, height, 10.0, 1.0));
dataPlot.addChild(line);
}
//render the plot
shape(dataPlot);
在这种情况下,检索第一行将如下所示:
PShape line0 = dataPlot.getChild(0);
您允许访问它的两个顶点:
println(line0.getVertex(0));
println(line0.getVertex(1));
如果要为这些位置设置动画,可以轻松使用 lerp() on single values or PVector's lerp() 方法(对于 PVectors :))。此函数需要一对 start/end 值和一个标准化值(介于 0.0 和 1.0 之间)和 return 之间的值。将其视为沿途的百分比:
- 传递 0.0 将成为该行的开始
- 通过0.5将是沿线的50%
- 传递 1.0 将是行尾
这是一个在遍历每条线时绘制椭圆的基本示例,它的颜色指示开始(黑色)或结束(白色)位置(拖动应该允许手动控制将 X 轴映射到线遍历):
Table data;
PShape plot;
void setup(){
size(1620, 1080, P2D);
//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("data.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);
float dist = dist(x1, y1, x2, y2);
line.setStroke(color(map(dist, 0, height, 160, 0)));
line.setStrokeWeight(map(dist, 0, height, 10.0, 1.0));
plot.addChild(line);
}
}
void draw(){
background(255);
//render the plot
shape(plot);
//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.1),-1.0,1.0,0.0,1.0);
}
//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
fill(traversal * 255);
ellipse(inbetween.x,inbetween.y,15,15);
}
}
这是一个非常相似的例子,只淡化点:
Table data;
PShape plot;
void setup(){
size(1620, 1080, P2D);
//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("data.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);
float dist = dist(x1, y1, x2, y2);
line.setStroke(color(map(dist, 0, height, 160, 0)));
line.setStrokeWeight(map(dist, 0, height, 10.0, 1.0));
plot.addChild(line);
}
//clear the background
noStroke();
shape(plot);//this needs to be drawn at least once it seems
background(255);
}
void draw(){
//hacky fade effect, change the alpha (16) transparency value to experiment with fade amount
fill(255,16);
rect(0,0,width,height);
//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);
}
//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
fill(lerpColor(color(255,0,0),color(0,255,0),traversal));
ellipse(inbetween.x,inbetween.y,15,15);
}
}
这是另一个有趣的小变化:
Table data;
PShape plot;
void setup(){
size(1620, 1080, P2D);
smooth(8);
//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("data.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(5.0);
}
void draw(){
//hacky fade effect, change the alpha/transparency value to experiment with fade amount
background(255);
//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();
}
视频演示 here
如果线性插值不够,并且您需要更多地控制时间或插值类型,请查看 Benedikt Groß's Ani library
我正在尝试生成一个图形,用一条线从起点到目的地绘制货运路径。我已将纬度和经度数据转换为适合美国地图的像素 (1620, 1080)。
当前的书写方式是按照它们在我的 csv 文件中的排序方式顺序绘制的。但是,我希望这些线从起点辐射到终点。现在我只能想办法把已经画好的线放下来。
我认为代码的相关部分在 // Draw Lines
。
long current;
int x;
int y;
ArrayList loads;
void setup() {
size(1620, 1080);
background(55);
smooth();
frameRate(15);
// 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();
}
// Draw Lines
loads = new ArrayList();
String[] loadset = loadStrings("data1.csv");
for ( int i3 = 0; i3 < loadset.length; i3++) {
String[] loads2 = split(loadset[i3], ',');
loads.add( new Lane(int(loads2[0]), int(loads2[1]), int(loads2[2]), int(loads2[3])) );
}
}
int i=1;
int imax = 1;
int incmult = 1;
void draw() {
if (i < loads.size()-imax){
for(int iadd = 0; iadd < imax; iadd++)
{
Lane Lane = (Lane) loads.get(iadd);
Lane.display();
Lane = (Lane) loads.get(i+iadd);
Lane.display();
}
i +=imax;
}
imax = imax + incmult;
}
class Lane {
int x;
int y;
int x2;
int y2;
Lane( int tempX, int tempY, int tempX2, int tempY2) {
x = tempX;
y = tempY;
x2 = tempX2;
y2 = tempY2;
}
void display() {
int r = 65;
int g = 255;
int b = 35;
strokeWeight(1);
stroke(r, g, b, 55);
line(x, y, x2, y2);
stroke(255, 255, 255); // Origin
fill(255, 255, 255, 55);
ellipse(x, y, 3, 3);
stroke(171, 62, 193); // Destination
fill(171, 62, 193);
ellipse(x2, y2, 3, 3);
}
}
我的 data1.csv
文件包含四列 x, y, x2, y2
,其中 (x, y)
表示原点,(x2, y2)
表示目标坐标。
// data.csv
data[0] data[1] data[2] data[3]
929 327 602 507
1335 458 1327 782
1422 325 848 744
1302 280 1118 458
1041 583 1193 666
1267 616 1058 394
1215 671 1351 857
1334 851 1410 946
1334 851 1409 916
828 761 861 653
1386 323 1203 594
1037 293 1013 522
908 869 958 532
1029 331 1053 409
906 357 828 761
. . . .
. . . .
更新 我已经添加了指向我的数据的链接,因为我仍然无法按照我的设想绘制图像。
目前问题还不是很清楚,所以当前形式的回答不完整。
以下是一些可以简化代码并希望有助于实现最终目标的建议:
- 使用 loadTable(). It supports the tab support and headers as your sample data. The nice thing about parsing the headers is that you can use the column label to parse each value using functions readily available functions like getInt() 尝试 Processing 的内置 CSV 解析器
- 尝试使用 PShape:您可以在设置中设置一次绘制命令,然后在一个命令中渲染最终形状。优点是您可以在需要时访问以后使用的形状和顶点。
这是一个使用此 TSV 的基本示例,该示例基于以上保存为 data.tsv
的数据Table data;
PShape dataPlot;
size(1620, 1080,P2D);
//create a group to store the lines from each row
dataPlot = createShape();
//load the data, specifying it has a header and it's tab separated
data = loadTable("data.tsv", "header, tsv");
//traverse each row
dataPlot.beginShape(LINES);
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
dataPlot.stroke(160);
dataPlot.vertex(x1,y1);
dataPlot.stroke(0);
dataPlot.vertex(x2,y2);
}
dataPlot.endShape();
//render the plot
shape(dataPlot);
使用深灰色到浅灰色显示路径的起点和终点,这是使用部分示例数据的结果:
如果您需要在创建 PShape 实例后访问每个顶点,您可以使用 getVertex()。它需要您可能想要检索的顶点的索引。
例如,dataPlot.getVertex(0);
和 dataPlot.getVertex(1);
将 return 第一行的坐标,dataPlot.getVertex(2);
和 dataPlot.getVertex(2);
将 return 第二行的坐标等等。
如果管理树状层次结构而不是顶点索引更容易,您可以创建 PShape 组。唯一需要注意的是,创建的以下子 PShape 实例将使用以 set 为前缀的函数绘制,而不是典型的 stroke()
/fill()
/等。你已经习惯了:setStroke()
/setFill()
/etc.
下面是一个使用 PShape 组并将距离映射到线条颜色和粗细的代码示例:
Table data;
PShape dataPlot;
size(1620, 1080, P2D);
//create a group to store the lines from each row
dataPlot = createShape(GROUP);
//load the data, specifying it has a header and it's tab separated
data = loadTable("data.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);
float dist = dist(x1, y1, x2, y2);
line.setStroke(color(map(dist, 0, height, 160, 0)));
line.setStrokeWeight(map(dist, 0, height, 10.0, 1.0));
dataPlot.addChild(line);
}
//render the plot
shape(dataPlot);
在这种情况下,检索第一行将如下所示:
PShape line0 = dataPlot.getChild(0);
您允许访问它的两个顶点:
println(line0.getVertex(0));
println(line0.getVertex(1));
如果要为这些位置设置动画,可以轻松使用 lerp() on single values or PVector's lerp() 方法(对于 PVectors :))。此函数需要一对 start/end 值和一个标准化值(介于 0.0 和 1.0 之间)和 return 之间的值。将其视为沿途的百分比:
- 传递 0.0 将成为该行的开始
- 通过0.5将是沿线的50%
- 传递 1.0 将是行尾
这是一个在遍历每条线时绘制椭圆的基本示例,它的颜色指示开始(黑色)或结束(白色)位置(拖动应该允许手动控制将 X 轴映射到线遍历):
Table data;
PShape plot;
void setup(){
size(1620, 1080, P2D);
//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("data.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);
float dist = dist(x1, y1, x2, y2);
line.setStroke(color(map(dist, 0, height, 160, 0)));
line.setStrokeWeight(map(dist, 0, height, 10.0, 1.0));
plot.addChild(line);
}
}
void draw(){
background(255);
//render the plot
shape(plot);
//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.1),-1.0,1.0,0.0,1.0);
}
//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
fill(traversal * 255);
ellipse(inbetween.x,inbetween.y,15,15);
}
}
这是一个非常相似的例子,只淡化点:
Table data;
PShape plot;
void setup(){
size(1620, 1080, P2D);
//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("data.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);
float dist = dist(x1, y1, x2, y2);
line.setStroke(color(map(dist, 0, height, 160, 0)));
line.setStrokeWeight(map(dist, 0, height, 10.0, 1.0));
plot.addChild(line);
}
//clear the background
noStroke();
shape(plot);//this needs to be drawn at least once it seems
background(255);
}
void draw(){
//hacky fade effect, change the alpha (16) transparency value to experiment with fade amount
fill(255,16);
rect(0,0,width,height);
//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);
}
//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
fill(lerpColor(color(255,0,0),color(0,255,0),traversal));
ellipse(inbetween.x,inbetween.y,15,15);
}
}
这是另一个有趣的小变化:
Table data;
PShape plot;
void setup(){
size(1620, 1080, P2D);
smooth(8);
//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("data.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(5.0);
}
void draw(){
//hacky fade effect, change the alpha/transparency value to experiment with fade amount
background(255);
//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();
}
视频演示 here
如果线性插值不够,并且您需要更多地控制时间或插值类型,请查看 Benedikt Groß's Ani library