2013-04-21 1 views
2

Я пытаюсь сделать визуализацию twitter. Я использую кривые для соединения двух точек на карте. 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(); 
} 

Я хочу анимировать эту трехмерную кривую, чтобы я мог видеть их нарисованными на карте. Может ли кто-нибудь помочь мне с этим. Я пробовал все, от FrameCount к расширенному анимации libraried в обработке но не повезло еще :(

Спасибо.

ответ

0

Вы рисования кривых с помощью команды кривой() (http://processing.org/reference/curve_.html), который рисует Catmull-Rom сплайны В вашем коде вы рисуете только один раздел сплайна (один из двух контрольных точек), так что вы действительно заинтересованы в том, «как я могу сделать только часть раздела сплайна Catmull-Rom». у вас нет ответа на этот вопрос, но если вы измените свою кривую (control1, first, second, control2), вызовите вызов bezier (first, c1, c2, second) (где вам теперь придется придумывать код для контрольных точек c1 и c2), тогда вы можете использовать алгоритм де Кастеляу, чтобы вырезать кривую на два сегмента в любом месте это. Если вы выдвигаете «где-к-вырезать», то указываете на каждый кадр, а затем извлекаете только первый сегмент, который вы получаете из операции разделения, он будет выглядеть как кривая, которая тянется от начала до конечной точки. См. http://pomax.github.io/bezierinfo/#splitting для описания того, как это сделать (бонус: исходный код даже в обработке)

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(); 
} 
Смежные вопросы