2009-12-10 11 views
0

두 점마다 각 점의 X 값과 Y 값이 같으며 Z 값이 같습니다.OpenGL에서 두 점을 연결하는 원통형을 그리는 방법

이 두 점 사이에 실린더를 그리는 기능이 필요합니다.

+0

난 당신이 훨씬 더 구체적으로해야 할 것 같아요. – bmargulies

+0

두 점을 포함하는 무한 수의 실린더가 있습니다. 점에 대해 원통을 어떻게 원하도록 설명 할 수 있습니까? 나는 한쪽 끝에서 중심선에있는 두 점을 이용하여 원통형 (또는 사용자 지정) 반경의 원통을 원한다고 생각합니다. 그러나 당신은 구체적이어야합니다 ... –

답변

0

(당신의 OpenGL-ES에 AE 경우 예) 당신은 GLU 라이브러리에서 gluCylinder()를 사용하지 못할

아니면 작은 평면 세그먼트에서 실린더의 측면을 만들기 위해
이있는 경우 How do you draw a cylinder with OpenGLES?

+0

하지만 포인트 사이의 X와 Y 각도를 계산하고 처음부터 다른 하나까지 실린더를 그려야하는 기능이 필요합니다. – trrrrrrm

2

주어진 두 점이있는 원통형 건물의 경우 벡터 분석이 필요합니다. 당신은 각 점에 더해지고 반지름으로 곱해진 sin/cos로 스케일 된 두개의 수직 벡터를 만들고 있습니다. 모든 점을 받아들입니다 (길이에 대해 sqrt()가 없어서 이전 코드에 버그가 있음). 이제 올바르게 작동하고 gl 루틴으로 실린더를 그립니다. 나는 JOGL에서 그것을 테스트했다. 빠른 그리기를 위해 firstPerpVector/secondPerpVector/points 변수를 개인 최종 배열 필드로 이동하고 처음부터 초기화하십시오.

자바 코드 : 현재 허용 대답을 사용하여

public float[] getFirstPerpVector(float x, float y, float z) { 
    float[] result = {0.0f,0.0f,0.0f}; 
    // That's easy. 
    if (x == 0.0f || y == 0.0f || z == 0.0f) { 
    if (x == 0.0f) 
     result[0] = 1.0f; 
    else if (y == 0.0f) 
     result[1] = 1.0f; 
    else 
     result[2] = 1.0f; 
    } 
    else { 
    // If xyz is all set, we set the z coordinate as first and second argument . 
    // As the scalar product must be zero, we add the negated sum of x and y as third argument 
    result[0] = z;  //scalp = z*x 
    result[1] = z;  //scalp = z*(x+y) 
    result[2] = -(x+y); //scalp = z*(x+y)-z*(x+y) = 0 
    // Normalize vector 
    float length = 0.0f; 
    for (float f : result) 
     length += f*f; 
    length = (float) Math.sqrt(length); 
    for (int i=0; i<3; i++) 
     result[i] /= length; 
    } 
    return result; 
} 

public void drawCylinder(GL gl, float x1, float y1, float z1, float x2, float y2, float z2) { 
    final int X = 0, 
      Y = 1, 
      Z = 2; 
    // Get components of difference vector 
    float x = x1-x2, 
     y = y1-y2, 
     z = z1-z2; 
    float[] firstPerp = getFirstPerpVector(x,y,z); 
    // Get the second perp vector by cross product 
    float[] secondPerp = new float[3]; 
    secondPerp[X] = y*firstPerp[Z]-z*firstPerp[Y]; 
    secondPerp[Y] = z*firstPerp[X]-x*firstPerp[Z]; 
    secondPerp[Z] = x*firstPerp[Y]-y*firstPerp[X]; 
    // Normalize vector 
    float length = 0.0f; 
    for (float f : secondPerp) 
    length += f*f; 
    length = (float) Math.sqrt(length); 
    for (int i=0; i<3; i++) 
    secondPerp[i] /= length; 

    // Having now our vectors, here we go: 
    // First points; you can have a cone if you change the radius R1 

    final int ANZ = 32; // number of vertices 
    final float FULL = (float) (2.0f*Math.PI), 
       R1 = 4.0f; // radius 
    float[][] points = new float[ANZ+1][3]; 
    for (int i=0; i<ANZ; i++) { 
    float angle = FULL*(i/(float) ANZ); 

    points[i][X] = (float) (R1*(Math.cos(angle)*firstPerp[X]+Math.sin(angle)*secondPerp[X])); 
    points[i][Y] = (float) (R1*(Math.cos(angle)*firstPerp[Y]+Math.sin(angle)*secondPerp[Y])); 
    points[i][Z] = (float) (R1*(Math.cos(angle)*firstPerp[Z]+Math.sin(angle)*secondPerp[Z])); 
    } 
    // Set last to first 
    System.arraycopy(points[0],0,points[ANZ],0,3); 

    gl.glColor3f(1.0f,0.0f,0.0f); 
    gl.glBegin(GL.GL_TRIANGLE_FAN); 
    gl.glVertex3f(x1,y1,z1); 
    for (int i=0; i<=ANZ; i++) { 
    gl.glVertex3f(x1+points[i][X], 
        y1+points[i][Y], 
        z1+points[i][Z]); 
    } 
    gl.glEnd(); 

    gl.glBegin(GL.GL_TRIANGLE_FAN); 
    gl.glVertex3f(x2,y2,z2); 
    for (int i=0; i<=ANZ; i++) { 
    gl.glVertex3f(x2+points[i][X], 
        y2+points[i][Y], 
        z2+points[i][Z]); 
    } 
    gl.glEnd(); 

    gl.glBegin(GL.GL_QUAD_STRIP); 
    for (int i=0; i<=ANZ; i++) { 
    gl.glVertex3f(x1+points[i][X], 
        y1+points[i][Y], 
        z1+points[i][Z]); 
    gl.glVertex3f(x2+points[i][X], 
        y2+points[i][Y], 
        z2+points[i][Z]); 
    } 
    gl.glEnd();  
} 
0

이 솔루션은 사용자가 3D 벡터와 하나의 유틸리티 클래스로 4D 사원 수를 결합하여 몇 가지 일반적인 카메라 코드를 가정합니다. 그래서이 3D 점 A와 세계 공간에서 B를 들어, A에서 B로 실린더를 그리기에 대한 일반적인 솔루션입니다 :

void draw_cylinder 
(
    const vector3d& A 
    ,const vector3d& B 
    ,const double radius 
) 
{ 

    // STEP 1: calculate the distance between the points A and B 

    double height = (B-A).length(); 

    // STEP 2: put a camera object at point A 

    camera C(A); // quat rotation assumed to be facing -Z axis 

    // STEP 3: tell the camera to look directly at point B 

    C.look_at(B); 

    // STEP 4: save the current OpenGl matrix state 

    glPushMatrix(); 

    // STEP 5: give the camera transform to OpenGL 

    C.apply_transform_model_to_world(); 

    // STEP 6: draw your cylinder from (0,0,0) to (0,0,-height) 

    gluCylinder 
    (
     pqobj  //GLUquadric* 
     ,radius  //GLdouble base 
     ,radius  //GLdouble top 
     ,height  //GLdouble 
     ,8   //GLint slices 
     ,8   //GLint stacks 
    ); 

    // STEP 7: restore the OpenGl matrix stack 

    glPopMatrix(); 

} 
관련 문제