2013-07-16 127 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)