2

我正在尝试做一个 twitter 可视化。我使用曲线连接地图上的两个点。 在此处输入图像描述

这是我正在使用的代码。它取自处理论坛中的 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 曲线制作动画,以便我可以看到它们在地图上绘制。谁能帮我解决这个问题。我已经尝试了从帧数到处理中库的高级动画的所有方法,但还没有运气:(

谢谢。

4

3 回答 3

1

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

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();
}
于 2013-04-24T04:55:55.090 回答
0

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

于 2013-04-21T13:10:11.720 回答
0

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

于 2014-10-18T22:54:19.817 回答