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

时间:2013-04-21 09:02:45

标签: animation 3d processing curve

我正在尝试进行推特可视化。 我使用曲线连接地图上的两个点。 enter image description here

以下是我正在使用的代码。它来自处理论坛的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曲线,以便我可以看到它们在地图上绘制。任何人都可以帮我解决这个问题。我已经尝试了从framecount到高级动画的所有内容,但是还没有好运:(

感谢。

3 个答案:

答案 0 :(得分:1)

您可以逐点计算抛物线,使用curveVertex绘制它并使用平移和旋转在3D中环绕,这里是一个示例(使用1.5.1 / P3D / fontMode(SCREEN)):< / p>

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

答案 1 :(得分:0)

您使用绘制Catmull-Rom样条曲线的curve()命令(http://processing.org/reference/curve_.html)绘制曲线。在你的代码中,你只绘制一个样条曲线部分(两个控制点之间的部分),所以你真正感兴趣的是“我怎样才能绘制Catmull-Rom样条曲线部分的一部分”。我没有那个答案,但是如果你改变你的曲线(control1,first,second,control2)调用bezier(第一,c1,c2,第二)调用(你现在必须提出相反,控制点c1和c2的代码可以使用de Casteljau的算法将曲线切割成沿其任意位置的两个段。如果你向上滑动每一帧的切割位置,然后只绘制从分割操作中得到的第一个线段,它看起来就像是从开始到结束点绘制自己的曲线。有关如何执行此操作的说明,请参阅http://pomax.github.io/bezierinfo/#splitting(奖励:源代码甚至在处理中)

答案 2 :(得分:0)

使用curvePoint()方法。这是解决类似问题的方法: http://forum.processing.org/one/topic/animation-with-curve.html