Animation 如何为地图上两点之间的3D曲线设置动画?

Animation 如何为地图上两点之间的3D曲线设置动画?,animation,3d,processing,curve,Animation,3d,Processing,Curve,我正在尝试做一个推特可视化。 我使用曲线连接地图上的两点。 这是我正在使用的代码。它来自Chrisir在处理论坛上的一个示例 void setup() { size( 800, 800, P3D ); } // setup void draw() { // myCurveTest() ; PVector firstpoint = new PVector (120, 320, -30); PVector secondpoint = new PVector (320, 220

我正在尝试做一个推特可视化。 我使用曲线连接地图上的两点。

这是我正在使用的代码。它来自Chrisir在处理论坛上的一个示例

void setup()
{
  size( 800, 800, P3D );
} // setup

void draw() 
{
  // myCurveTest() ;
  PVector firstpoint = new PVector (120, 320, -30); 
  PVector secondpoint = new PVector (320, 220, -30);
  myCurve (firstpoint, secondpoint ) ;
  firstpoint = new PVector (420, 220, 30); 
  secondpoint = new PVector (620, 120, -30);
  myCurve (firstpoint, secondpoint ) ;
}


void myCurve (
PVector firstpoint, 
PVector secondpoint) {
  PVector beginningcontrolpoint = new PVector (120, firstpoint.y+1200, -30); 
  PVector endingcontrolpoint = new PVector (720, secondpoint.y+1200, -30); 
  myPointPVector(beginningcontrolpoint, color(255, 0, 0));
  myPointPVector(firstpoint, color(0, 0, 255));  
  myPointPVector(secondpoint, color(0, 0, 255));  
  myPointPVector(endingcontrolpoint, color(255, 0, 0));
  stroke (255);
  noFill();
  curve(
  beginningcontrolpoint.x, beginningcontrolpoint.y, beginningcontrolpoint.z, 
  firstpoint.x, firstpoint.y, firstpoint.z, 
  secondpoint.x, secondpoint.y, secondpoint.z, 
  endingcontrolpoint.x, endingcontrolpoint.y, endingcontrolpoint.z);
}


void myPointPVector (PVector test, color col1) {
  MyBox(test.x, test.y, test.z, 
  test.x+3, test.y, test.z, 
  9, 
  col1);
}

void MyBox(float x1, float y1, float z1, float x2, float y2, float z2, float weight, color strokeColour)
// was called drawLine; programmed by James Carruthers
// see http://processing.org/discourse/yabb2/YaBB.pl?num=1262458611/0#9
{
  PVector p1 = new PVector(x1, y1, z1);
  PVector p2 = new PVector(x2, y2, z2);
  PVector v1 = new PVector(x2-x1, y2-y1, z2-z1);
  float rho = sqrt(pow(v1.x, 2)+pow(v1.y, 2)+pow(v1.z, 2));
  float phi = acos(v1.z/rho);
  float the = atan2(v1.y, v1.x);
  v1.mult(0.5);
  pushMatrix();
  translate(x1, y1, z1);
  translate(v1.x, v1.y, v1.z);
  rotateZ(the);
  rotateY(phi);
  noStroke();
  fill(strokeColour);
  box(weight, weight, p1.dist(p2)*1.2);
  popMatrix();
}
我想设置这条3D曲线的动画,这样我就可以看到它们在地图上绘制。有人能帮我解决这个问题吗。我尝试了从帧数到处理中的高级动画库的所有方法,但还没有成功:(


谢谢。

您正在使用curve()命令()绘制曲线,该命令可绘制Catmull Rom样条曲线。在您的代码中,您只绘制一个样条曲线部分(两个控制点之间的部分),因此您真正感兴趣的是“如何仅绘制Catmull Rom样条曲线部分?”.我没有这个问题的答案,但是如果你将曲线(control1,first,second,control2)调用更改为bezier(first,c1,c2,second)调用(你现在必须为控制点c1和c2编写代码)相反,您可以使用de Casteljau的算法将曲线沿任意方向切割成两段。如果每帧向上滑动切割点的位置,然后仅绘制从拆分操作获得的第一段,则它看起来就像一条从起点到终点绘制自身的曲线。有关如何绘制曲线的说明,请参阅o这(好处:源代码正在处理)

您可以逐点计算抛物线,使用
curveVertex
绘制抛物线,并使用translate和rotate在3D中对其进行动态观察,这里是一个示例(使用1.5.1/P3D/
fontMode(屏幕)
):

float initial_x=-200;
浮点数x=初始值x;
浮动y;
浮动y_偏移;
float r=200;//更改此值可更改抛物线的高度
ArrayList pts=新的ArrayList();
浮动mx=70,my=-15,tmx,tmy;
布尔动画=假;
pfontf;
无效设置(){
尺寸(800、400、P3D);
背景(255);
光滑的();
f=createFont(“Arial”,15);
文本模式(屏幕);
}
作废提款(){
//灯光();
背景(255);
填充(100);
textFont(f,15);
文本(“拖动到轨道”,宽度-10-文本宽度(“拖动到轨道”),高度-30);
文本(“重画抛物线的任意键”,宽度-10-文本宽度(“重画抛物线的任意键”),高度-10);
//旋转三维
平移(宽度/4,高度/2);
rotateY(弧度(mx));
rotateZ(弧度(my));
//标记原点并帮助查看三维视图的步骤
noFill();
中风(100);
盒子(20);
pushMatrix();
翻译(100,5,-100);
中风(200);
填充(0,20);
盒子(600,2600);
popMatrix();
//存储y偏移量
如果(x==初始值x){
y_偏移=(平方(x)+2*x)/r;
}
//停止抛物线
如果(x==初始值x | | x<-初始值x+2){
x+=2;
动画=真;
//添加到曲线存储
增加(新的PVector(x,y));
}
否则{
动画=假;
}
//计算y
y=(平方(x)+2*x)/r-y_偏移量;
中风(50,30,7);
noFill();
冲程重量(1);
//在原点绘制
翻译(-initial_x,0);
//绘制曲线
beginShape();
用于(PVector p:pts){
curveVertex(p.x,p.y);
}
endShape();
//抽签
如果(!设置动画){
转换(pts.get(帧数%pts.size()).x,pts.get(帧数%pts.size()).y);
仰泳();
填充(220、190、35);
球体(4);
}
}
void mousePressed(){
tmx=鼠标;
tmy=老鼠;
}
void mouseDragged(){
mx=tmx-mouseX;
my=tmy-mouseY;
}
按下void键(){
x=-200;
pts.clear();
}
使用curvePoint()方法。下面是一个类似问题的解决方案:

float initial_x = -200;
float x =  initial_x;
float y;
float y_offset;
float r = 200;// change this to change the height of the parabola
ArrayList<PVector> pts = new ArrayList<PVector>();
float mx = 70, my = -15, tmx, tmy;
boolean animating = false;
PFont f;



void setup() {
  size( 800, 400, P3D);
  background(255);
  smooth();
  f = createFont("Arial", 15);
  textMode(SCREEN);
}

void draw() {
  //lights();
  background(255);
  fill(100);
  textFont(f, 15);
  text("drag to orbit", width - 10 - textWidth("drag to orbit"), height -30);
  text("any key to redraw parabola", width - 10 - textWidth("any key to redraw parabola"), height -10);

  //rotate 3d
  translate(width/4, height/2);
  rotateY(radians(mx));
  rotateZ(radians(my));

  // to mark origin and help view 3d
  noFill();
  stroke(100);
  box(20);
  pushMatrix();
  translate(100, 5, -100);
  stroke(200);
  fill(0, 20);
  box(600, 2, 600);
  popMatrix();



  //store y offset
  if (x == initial_x) {
    y_offset = (sq(x)+2*x)/r;
  }

  // stop parabola
  if ( x == initial_x ||  x < -initial_x + 2) {
    x+=2;
    animating = true;
     // add to curve storage
    pts.add(new PVector(x, y));
  }
  else {
    animating = false;
  }

  //calc y
  y = (sq(x)+2*x)/r - y_offset;

  stroke(50, 30, 7);
  noFill();
  strokeWeight(1);

  //draw at origin
  translate(-initial_x, 0);


  //draw curve
  beginShape();
  for (PVector p:pts) {
    curveVertex(p.x, p.y);
  }
  endShape();

  //draw a ball
  if (!animating) {
    translate(pts.get(frameCount%pts.size()).x, pts.get(frameCount%pts.size()).y);
    noStroke();
    fill(220, 190, 35);
    sphere(4);
  }
}
void mousePressed() {
  tmx = mouseX;
  tmy = mouseY;
}
void mouseDragged() {
  mx = tmx - mouseX;
  my = tmy - mouseY;
}

void keyPressed() {
  x = -200;
  pts.clear();
}