所以我在一个文件中的坐标和我想要一行的秒数逐渐变大。在文件中,我有x1,x2(关于第一个点坐标),x2,y2(第二个点坐标),以及我想要在第二个点方向开始生长线的时间(以秒为单位)。
这是我的代码:
//阅读线
import processing.video.*;
Movie myMovie;
Table table;
float duration, time;
int row_no=1;
int clickcount = 0;
void setup() {
size(640,480);
myMovie = new Movie(this, "draft.mov");
myMovie.loop();
table = loadTable("data/new.csv");
}
void draw() {
duration = myMovie.duration();
time = myMovie.time();
image(myMovie, 0, 0);
if(time>= table.getFloat(row_no, 4)){
strokeWeight(15);
stroke(255,14,255);
float a = table.getFloat(row_no, 0);
float b = table.getFloat(row_no,1);
line(table.getFloat(row_no,0),table.getFloat(row_no, 1), a, b);
a = a + 2;
b = b + 2;
}
}
// Called every time a new frame is available to read
void movieEvent(Movie m) {
m.read();
} `
答案 0 :(得分:0)
正如Niccolo建议的那样,先解决问题,拿出任何你不需要的东西,一步一步。
根据您对目标的描述而言,根据您的目标描述而言,这听起来并不像代码与播放电影有任何关系,因此请简单地使用该代码。 (我想到使用电影的唯一原因是使用它的当前时间来控制线条,但除非你想要电影背景,否则不需要它)
在draw()循环中有一些看起来奇怪的东西:
if(time>= table.getFloat(row_no, 4)){
假设.csv文件中的第5列以秒为单位保存当前行的提示时间,此条件只会触发一次,因为没有任何增量row_no
line(table.getFloat(row_no,0),table.getFloat(row_no, 1), a, b);
可能不是你想要的,可能是一个错字,因为a
和b
已经从相同的.csv列(0和1)中检索到了,这意味着你的行的开始和结束位置都在准确的位置(因此不会呈现一条线)。也许你的意思是line(table.getFloat(row_no,2),table.getFloat(row_no, 3), a, b);
?a = a + 2;
和b = b + 2;
:其中一个点的x,y位置可能会偏移2,但新位置永远不会超过此点。在下一个draw()
次迭代a
和b
被重新定义,因此偏移量将丢失。让我们解决问题:
我有一个文件 坐标和秒我想让一条线逐渐变大。在文件中,我有x1,x2(关于第一个点坐标),x2,y2(第二个点坐标),以及我想要在第二个点方向开始生长线的时间(以秒为单位)。
甚至更进一步,如果从头开始,更多的是作为“如何”:
幸运的是,Processing提供了一个内置函数,用于在值lerp()之间进行线性插值(lerp =简称线性插值)。 它需要三个参数:
并返回一个值:start和stop值之间的值。 将插值量视为百分比(0 = 0%,0.5 = 50%,1.0 = 100%)。
这是一个基本草图来说明这个概念:
void draw(){
background(255);
//map time to an interpolation normalized value
float t = map(mouseX,0,width,0.0,1.0);
//interpolate the values
float size = lerp(10,90,constrain(t,0.0,1.0));
ellipse(50,50,size,size);
}
你可以运行p5.js演示的片段:
function setup() {
createCanvas(100,100);
}
function draw(){
background(255);
//map time to an interpolation normalized value
var t = map(mouseX,0,width,0.0,1.0);
//interpolate the values
var size = lerp(10,90,constrain(t,0.0,1.0));
ellipse(50,50,size,size);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.11/p5.min.js"></script>
如果您在x轴上移动鼠标,您会发现根据鼠标位置,直径大小在10到90像素之间。
完成第1步!
接下来,您可以使用millis()
来跟踪时间,并在毫秒时间内简单地map()
(将开始和结束时间之间的当前时间映射到0.0 - 1.0范围):< / p>
float seconds = 3.5;
//the time in millis since the last update
int previousMillis;
//the current time in millis
int currentMillis;
//the time in millis until the next event
int nextMillis;
void setup(){
previousMillis = millis();
currentMillis = millis();
nextMillis = currentMillis + (int)(seconds * 1000);
}
void draw(){
background(255);
//update the current timer continously
currentMillis = millis();
//map the current time from the previous to the next time as a normalized value (0,0 to 1.0) range
float t = map(currentMillis,previousMillis,nextMillis,0.0,1.0);
//interpolate the values
float size = lerp(10,90,constrain(t,0.0,1.0));
ellipse(50,50,size,size);
}
以及作为p5.js可运行的演示:
var seconds = 3.5;
//the time in millis since the last update
var previousMillis;
//the current time in millis
var currentMillis;
//the time in millis until the next event
var nextMillis;
function setup(){
previousMillis = millis();
currentMillis = millis();
nextMillis = currentMillis + (int)(seconds * 1000);
}
function draw(){
background(255);
//update the current timer continously
currentMillis = millis();
//map the current time from the previous to the next time as a normalized value (0,0 to 1.0) range
var t = map(currentMillis,previousMillis,nextMillis,0.0,1.0);
//interpolate the values
var size = lerp(10,90,constrain(t,0.0,1.0));
ellipse(50,50,size,size);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.11/p5.min.js"></script>
这已经完成了第2步,看起来你已经掌握了第3步(解析.csv值):)
一旦你理解了如何插入一个值,步骤4应该是微不足道的:只需对不同的变量做4次!
第5步很简单,因为您只需要检查row_no
是否超出了表的行数。
row_no = row_no + 1;
if(row_no > table.getRowCount()) row_no = 0;
你可以做的一件好事是使用modulo operator(%)做一个数学表达式:
row_no = (row_no + 1) % table.getRowCount();
总之,我们假设您的.csv文件看起来有点像这样:
x1,y1,x2,y2,seconds
5,5,95,5,4
95,5,95,95,3
95,95,5,95,2
5,95,5,5,1
将这一切放在一起的一种方法是这样的:
Table table;
int row_no = 0;
//the time in millis since the last update
int previousMillis;
//the current time in millis
int currentMillis;
//the time in millis until the next event
int nextMillis;
//where to animate the line from
float x1Start,y1Start,x2Start,y2Start;
//where to animate the line to
float x1Stop,y1Stop,x2Stop,y2Stop;
//currently interpolated line positions
float x1Lerp,y1Lerp,x2Lerp,y2Lerp;
void setup(){
size(100,100);
strokeWeight(3);
fill(0);
table = loadTable("data/new.csv","header, csv");
//printing the table in console, handy just for debugging/double checking values
println("data");
for(int i = 0 ; i <= table.getRowCount(); i++){
print(table.getColumnTitle(i)+"\t");
}
println();
for(int i = 0 ; i < table.getRowCount(); i++){
TableRow row = table.getRow(i);
for(int j = 0; j < row.getColumnCount(); j++){
print(row.getFloat(j) + "\t");
}
println();
}
//fetch lines and seconds from the current and next rows
updateFromRow();
}
void updateFromRow(){
//update times
previousMillis = millis();
currentMillis = millis();
//get the current row and it's line coordinates
TableRow currentRow = table.getRow(row_no);
x1Start = currentRow.getFloat("x1");
y1Start = currentRow.getFloat("y1");
x2Start = currentRow.getFloat("x2");
y2Start = currentRow.getFloat("y2");
//get the next row and it's line coordinates - notice % module is used to easily loop back to 0 once row_no goes beyond the number of table rows
TableRow nextRow = table.getRow((row_no + 1) % table.getRowCount());
x1Stop = nextRow.getFloat("x1");
y1Stop = nextRow.getFloat("y1");
x2Stop = nextRow.getFloat("x2");
y2Stop = nextRow.getFloat("y2");
//get the duration in seconds, convert it to millis( * 1000) and add it to the current millis
nextMillis = currentMillis + (int)(currentRow.getFloat("seconds") * 1000);
println("updated from row: " + row_no);
}
void draw(){
background(255);
//update the current timer continously
currentMillis = millis();
//map the current time from the previous to the next time as a normalized value (0,0 to 1.0) range
float t = map(currentMillis,previousMillis,nextMillis,0.0,1.0);
//if the current interpolation value is above 1.0
if(t > 1.0){
t = 0;
//increment the row
row_no++;
//if the current row counter is above the total number of rows, reset back 0
if(row_no >= table.getRowCount()){
row_no = 0;
}
//update values from incremented row (lines and their coordinates + time)
updateFromRow();
}
text("t:"+t,15,20);
//constrain interpolated value between 0.0 and 1.0
float interpolationAmount = constrain(t,0.0,1.0);
//linearly interpolate (lerp) between the current and next line coordinates
x1Lerp = lerp(x1Start,x1Stop,interpolationAmount);
y1Lerp = lerp(y1Start,y1Stop,interpolationAmount);
x2Lerp = lerp(x2Start,x2Stop,interpolationAmount);
y2Lerp = lerp(y2Start,y2Stop,interpolationAmount);
//finally, render the interpolated line
line(x1Lerp,y1Lerp,x2Lerp,y2Lerp);
}
在跟踪数据方面,可以使用PVector实例(... .csv数据中的x,y分量set()来存储线坐标,并且可以插入线点成对通过PVector's lerp())。 到目前为止,我们只使用线性插值,但您可能还想查看easing和tweening。