我正在尝试使用Jonathan Feinberg的Peasycam库进行处理,以围绕物体的Z轴旋转相机。 documentation指定旋转是围绕主体,而不是对象。这似乎难以实现。虽然在控制意义上,农民的重点是面向对象,但是农民旋转在主体(即相机)周围起作用。设置camera()
似乎也有问题,因为我无法让农民记住指定摄像机的位置。还有一个差异,即农民的y轴映射到数据空间的z轴。
我已经制作了一个基本模型来帮助解释这个问题。如果一些新鲜的眼睛可以帮助解决这个问题,感激不尽。 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));
}
答案 0 :(得分: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不适合程序控制。如果您想自己操纵视图,最好使用优秀的Proscene或OCD库。
编辑:如果您想将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();
答案 1 :(得分: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)