2013-07-16 124 views
2

我正在嘗試使用Jonathan Feinberg的Peasycam庫進行處理以圍繞物體的Z軸旋轉相機。 documentation指定旋轉是圍繞主體,而不是對象。這似乎難以實現。 peasycam旋轉圍繞主體(即相機)而非物體,儘管在控制意義上peasycam的重點是面向對象的。並且設置camera()似乎也有問題,因爲我無法讓peasycam記住分配的相機的位置。 Peasycam的y軸映射到數據空間的z軸也有差異。使用Peasycam旋轉相機周圍的物體軸

我做了一個基本的模型來幫助解釋這個交互。感謝一些新鮮的眼睛可以幫助解決這個問題。 Peasycam可能會將need installing添加到應用程序的庫文件夾中。總體目標是爲了動畫目的能夠在Z軸上旋轉3D數據圖。提前致謝。

import peasy.*; 
PVector camPos; 
PVector[] points = new PVector[50]; 
float angleXY, d; 
PeasyCam cam; 

void setup() { 
    size(300,300,P3D); 
    cam = new PeasyCam(this, 100); 
    cam.setMinimumDistance(50); 
    cam.setMaximumDistance(150); 

    for(int i=0; i<50; i++) points[i] = new PVector(random(-15,15),random(-15,15),random(-15,15)); 
} 

void draw() { 
    background(250); 
    noFill(); 
    box(30); 

    // axes for frame of reference 
    stroke(255,0,0);   // red = Z 
    line(0,0,-100,0,0,100); 
    stroke(0,255,0);   // green = Y 
    line(0,-100,0,0,100,0); 
    stroke(0,0,255);   // blue = X 
    line(-100,0,0,100,0,0); 

    // points on axes to denote positive orientation 
    strokeWeight(3); 
    for(PVector p:points) point(p.x, p.y, p.z); 
    strokeWeight(5); 
    point(40,0,0); 
    point(0,40,0); 
    point(0,0,40); 
    strokeWeight(1); 

    stroke(0); 

    camPos = new PVector(cam.getPosition()[0], cam.getPosition()[1], cam.getPosition()[2]); 
    angleXY = degrees(atan2(camPos.z, camPos.x)); // camera XY angle from origin 
    d = sqrt(pow(camPos.z, 2) + pow(camPos.x, 2)); // camera-object XY distance (compare to cam.getDistance()) 

    // ZX campera slots map to XY data plane: 
    println("campos: " + camPos + " " + ", ang: " + angleXY + ", dist:" + d); 
} 

void keyPressed(){ 
    if(key=='r') setup(); // restart 
    if(key==' ') camera(camPos.x, camPos.y, camPos.z, 0, 0, 0, 0, 0, 1); // stabilise image on Z axis 

    if(key=='d') { 
    angleXY += radians(1); 
    camera(sin(angleXY)*d, camPos.y, cos(angleXY)*d, 0, 0, 0, 0, 1, 0); 
    } 

    // peasycam's rotations work around the subject: 
    if(key=='p') cam.rotateY(radians(2)); 
} 
+2

peasycam的事情是,它總是有「旋轉[圍繞軸通過查看點]」。爲了解決這個問題,你必須補償圍繞另外兩個軸的旋轉並將其發送到peasycam。你需要的是「桌面」旋轉。如果我可以提供一個簡單的方法來實現您的整體目標,請從草圖中刪除peasycam並添加:攝像頭(70 * sin(frameCount * .02),70 * cos(frameCount * .02), 70,0,0 ,0,0,0,-1); –

回答

3

您誤解了Peasycam文檔中的「主題」一詞。 「主題」僅僅是「觀察」點。在你想看的東西內選擇一個點,然後用該點構建Peasycam,或者稍後設置它。

PeasyCam(PApplet parent, double lookAtX, double lookAtY, double lookAtZ, double distance); 

camera.lookAt(double x, double y, double z); 
camera.lookAt(double x, double y, double z, double distance); 

Peasycam不太適合程序控制。如果您想自己操作視圖,那麼使用優秀的ProsceneOCD庫會更好。

編輯:如果您想將Peasycam的運動限制在一個軸或另一個,你可以使用這些方法:

// By default, the camera is in "free rotation" mode, but you can 
// constrain it to any axis, around the look-at point: 
camera.setYawRotationMode(); // like spinning a globe 
camera.setPitchRotationMode(); // like a somersault 
camera.setRollRotationMode(); // like a radio knob 
camera.setSuppressRollRotationMode(); // Permit pitch/yaw only. 

// Then you can set it back to its default mode: 
camera.setFreeRotationMode(); 
+0

感謝您澄清喬納森。文檔可能會使這個更清晰 - 如果_subject_默認爲(0,0,0)原點,那麼它的z軸(我想要旋轉)與數據空間無關,但實際上相對於相機的位置這就是我困惑的原因。我會檢查你的建議。雖然大圖書館:) – geotheory

1

不是一個確切的回答這個問題,但類似的東西 - 我想簡單地設置該位置(移動)相機,但似乎與peasycam複雜。所以我想試試下一個最簡單的圖書館OCD。

所以 - 因爲OCD顯然不包含目前例子中的安裝(僅在Obsessive Camera Direction API參考) - 以下是.pde代碼peasycam基本的例子,修改與OCD庫(草圖實際工作指的是兩個庫,並允許您通過設置USEPEASY變量輕鬆比較其行爲。大部分peasycam交互被複制用於OCD - 但是,您不會像PeasyCam那樣使用OCD獲得動畫「補間」。

// modification of example on http://mrfeinberg.com/peasycam/ 
// sdaau, 2014 

private static final boolean USEPEASY = false; 

// cannot do conditional import in Java! (expecting EOF, found 'if') 
// http://stackoverflow.com/questions/11288083/javaconditional-imports 
//if(USEPEASY) { 
    import peasy.*; 
//} else { 
    import damkjer.ocd.*; 
//} 

// ... nor conditional globals! (expecting EOF, found 'if') 
//if(USEPEASY) { 
    PeasyCam cam; 
//} else { 
    Camera cam1; 
//} 

void setup() { 
    size(200,200,P3D); 
    if(USEPEASY) { 
    cam = new PeasyCam(this, 100); // (PApplet parent, double distance); // look at 0,0,0 
    cam.setMinimumDistance(50); 
    cam.setMaximumDistance(500); 
    } else { 
    cam1 = new Camera(this, // (parent, 
     0, 0, 100,   // cameraX, cameraY, cameraZ, 
     0, 0, 0,    // targetX, targetY, targetZ 
     50, 500    // nearClip, farClip) //(doesn't clip as peasycam!) 
    ); 
    } 
} 
void draw() { 
    if(!USEPEASY) { 
    cam1.feed(); //"send what this camera sees to the view port" 
    } 
    // these rotates seem just to set initial view, in either case: 
    rotateX(-.5); 
    rotateY(-.5); 
    // actual drawing: 
    background(0); 
    fill(255,0,0); 
    box(30); 
    pushMatrix(); 
    translate(0,0,20); 
    fill(0,0,255); 
    box(5); 
    popMatrix(); 
} 

// ... nor conditional methods! (expecting EOF, found 'if') 
//if(!USEPEASY) { 
void mouseDragged() { 
    if(!USEPEASY) { 
    if (mouseButton == LEFT) { 
     // http://www.airtightinteractive.com/demos/processing/bezier_ribbon_p3d/BezierRibbons.pde 
     cam1.arc(radians(-(mouseY - pmouseY))/4); 
     cam1.circle(radians(-(mouseX - pmouseX))/4); 
    } else if (mouseButton == RIGHT) { 
     cam1.zoom(radians(mouseY - pmouseY)/2.0); 
    } else if (mouseButton == CENTER) { 
     // peasycam calls this .pan(); damkjer.ocd calls it .track() 
     cam1.track(-(mouseX - pmouseX), -(mouseY - pmouseY)); 
    } 
    } // end if(!USEPEASY) 
} 
void mouseWheel(MouseEvent event) { 
    if(!USEPEASY) { 
    float e = event.getCount(); 
    cam1.zoom(e/3.0); 
    } // end if(!USEPEASY) 
} 
//} // end if(!USEPEASY)