2012-04-22 1 views
0

현재 OpenFrameworks를 사용하여 cloth physics 앱을 제작 중입니다. C++을 처음 접했을 때 머리가 위로 올라갔습니다.예측할 수없는 포인터 동작

내 응용 프로그램에서는 두 개의 '인접한'입자 개체가 스프링 개체에 포인터로 전달됩니다. 테스트로서, 저는 두 개의 파티클 사이에 (3d 벡터 위치 사이에) 스프링 오브젝트 그리기 선이 있습니다. 어떤 이유로 든 프로그램을 실행할 때마다 임의의 값이 포함되어 있지 않더라도이 행은 다릅니다. 스프링 구조체의 입자 위치 값을 계산할 때 -4.15301e-12와 같은 우스운 값이 종종 있습니다. 나는 거의 그대로 그대로 예제 코드를 따르기 때문에 어디서 잘못 될지 잘 모르겠습니다. 여기

https://sites.google.com/site/ofauckland/examples/17-cloth-physics

내 봄 구조체입니다 : 여기

내가 다음있어 예제 코드입니다

#pragma once 
#include "ofMain.h" 
#include "Particle.h" 

struct Spring { 

    float k, restLength; 
    Particle *a, *b; 
    ofVec3f posA, posB; 

    Spring(Particle *a, Particle *b, float k = .2) : a(a), b(b), k(k) { 
     restLength = (b->pos - a->pos).length(); 
    } 

    void update() { 
     posA = a->pos; 
     posB = b->pos; 
    } 
    void draw() { 
     ofSetLineWidth(5); 
     ofSetColor(0, 255, 0); 
     ofLine(posA.x, posA.y, posB.x, posB.y); 
    } 
};        

입자 구조체 :

#pragma once 
#include "ofMain.h" 

struct Particle { 

    ofVec3f pos; 

    Particle(ofVec3f pos) : pos(pos) { 
    } 

    void update() { 
    } 
    void draw() { 
     ofSetColor(ofRandom(255), 0, 0); 
     ofFill(); 
     ofCircle(pos.x, pos.y, 3); 
    } 
};  

그리고 이것이 두 개의 입자를 포인터로 봄에 전달합니다 :

#pragma once 
#include "ofMain.h" 
#include "Particle.h" 
#include "Spring.h" 

struct Petal { 

    float maxWidth, spacing; 
    vector<Particle> particles; 
    vector<Spring> springs; 

    Petal(float maxWidth, float spacing) : maxWidth(maxWidth), spacing(spacing) {   
     setupPoints(); 
    } 

    void setupPoints() { 
     float x = 0; 
     float y = 0; 

     for(int r = 1; r <= maxWidth; r++) { 
      x = (int)(r/2) * -spacing; 
      y += spacing; 
      for(int c = 1; c <= r; c++) { 
       ofVec3f pos = ofVec3f(x, y, 0); 
       Particle p(pos); 
       particles.push_back(p); 
       x+=spacing; 
      } 
     } 

     for(int r = maxWidth; r > 0; r--) { 
      x = (int)(r/2) * -spacing; 
      y += spacing; 
      for(int c = 1; c <= r; c++) { 
       ofVec3f pos = ofVec3f(x, y, 0); 
       Particle p(pos); 
       particles.push_back(p); 
       x+=spacing; 
      } 
     } 

     //find neighbors 
     for(int i = 0; i < particles.size(); i++) { 
      Spring s(&particles[i], &particles[findNeighbor(i)]); 
      springs.push_back(s); 
     } 
    } 

    int findNeighbor(int pIndex) { 
     float leastDist = 0; 
     float leastDistIndex = 0; 
     for(int i = 0; i < particles.size(); i++) { 
      if(i != pIndex) { 
       float distance = particles[pIndex].pos.distance(particles[i].pos); 
       if(abs(distance) < abs(leastDist) || leastDist == 0) { 
         leastDist = distance; 
         leastDistIndex = i; 
       } 
      } 
     } 
     return leastDistIndex; 

    } 

    void update() { 
     for(int i = 0; i < particles.size(); i++) { 
      particles[i].update(); 
     } 
     for(int s = 0; s < springs.size(); s++) { 
      springs[s].update(); 
     } 
    } 
    void draw() { 
     for(int i = 0; i < particles.size(); i++) { 
      particles[i].draw(); 
     } 
     for(int s = 0; s < springs.size(); s++) { 
      springs[s].draw(); 
     } 
    } 
}; 

This입니다. 이상한 점은 스프링의 일부가 정확한 위치에있는 것 같습니다.

내가 명확하게 설명해 주시면 알려주세요.

감사합니다.

+1

'draw' 전에'update'를 호출하고 있는지 확인하고 있습니까? 일반적으로 생성자가 완료되면 객체가 완전히 생성되었는지 (모든 연산이 호출 될 수 있는지) 확인해야하지만 2 단계 초기화를 수행하는 것이 좋습니다. 즉, 입자는 생성자에서 초기화되지만 위치, 'k'와'restLength'는 그렇지 않습니다. –

+0

나는 constructor에서 k와 restlength를 초기화하는 것에 대해 조언했다. 그리고 예, 갱신은 그려지기 전에 호출됩니다. 감사합니다. – Miles

답변

2

particles 벡터는 값이 Particles이고 값은 vector이므로이 값을 복사하고 이동할 수 있습니다. ParticlesSpring에 대한 포인터로 전달하면 나중에 어느 시점에 없을 수도있는 주소가 전달됩니다. 이것이 문제인지 확실하지 않지만 확실하게 고쳐야 할 부분입니다.

+0

포인터를 만들면 필자는 입자 벡터에 요소를 추가했습니다. 이 후에도 주소가 변경됩니까? 대신 주소 안정성을 보장하기 위해 배열을 사용해야합니까? – Miles

+0

@Miles 언제든지 이동할 수 있다고 가정해야합니다. 배열을 사용할 수도 있지만 실제로 포인터를 전달해야하는 경우에는 스스로에게 질문 할 수 있습니다. 값 대신 스마트 포인터의 벡터를 보유 할 수도 있습니다. 많은 솔루션이 있지만 실제로 사용 사례를 정확하게 알지 못합니다. – juanchopanza

+0

솔루션을 생각했지만 작동하지 않는 것 같습니다. 입자 벡터의 포인터와 첫 번째와 두 번째 입자의 인덱스를 스프링 구조체로 전달했습니다. 입자 벡터의 주소 자체가 변경 될 수 있습니까? – Miles