2

オブジェクトの Z 軸を中心にカメラを回転させる処理に、Jonathan Feinberg の Peasycam ライブラリを使用しようとしています。ドキュメンテーションは、回転が被写体の周りであることを指定していますが、オブジェクトの周りではありません。これを達成するのは非常に難しいようです。peasycam の回転は、オブジェクトではなく被写体 (つまり、カメラ) の周りに作用しますが、コントロールの意味で peasycam の重点はオブジェクト指向です。camera()また、割り当てられたカメラの位置を peasycam に記憶させることができないため、 の設定も問題があるようです。peasycam の y 軸がデータ空間の z 軸にマッピングされるという不一致もあります。

これをインタラクティブに説明するのに役立つ基本モデルを作成しました。新鮮な目がこれを解くのに役立つ場合は感謝します. Peasycam をアプリケーションのライブラリ フォルダにインストールする必要がある場合があります。全体的な目的は、アニメーション目的で 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));
}
4

2 に答える 2

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 の動きを 1 つの軸または別の軸に制限したい場合は、次の方法を使用できます。

// 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();
于 2013-07-17T13:37:12.977 に答える
1

この質問に対する正確な答えではありませんが、似たようなものです。単純にカメラの位置を設定 (移動) したかったのですが、peasycam. そこで、2 番目に簡単なライブラリである OCD を試してみたいと思いました。

そのため、OCD にはインストール時に例が含まれていないようです ( Obsessive Camera Direction API リファレンスのみ)。以下は、 OCD ライブラリで動作するように変更され.pdeた の基本的な例のコードですpeasycam(スケッチは実際には両方のライブラリを参照しています)。変数を設定することで、どちらの動作も簡単に比較できます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)
于 2014-11-05T10:58:55.250 に答える