0

アプリケーションでタッチ ポイントの量を制御する必要があります。このために、ベクター コンテナーを使用しています。基本的な設定は次のとおりです。

//--------------------------------------------------------------
void testApp::touchDown(ofTouchEventArgs &touch){
    isTouching = true;

    touchPoints.push_back( ofVec2f( touch.x, touch.y ) );
}

//--------------------------------------------------------------
void testApp::touchMoved(ofTouchEventArgs &touch){
    for ( int i = 0; i < touchPoints.size(); i++ ) {
        if ( touch.id == i ) {
            touchPoints[i] = ofVec2f( touch.x, touch.y );
        }
    }
}

//--------------------------------------------------------------
void testApp::touchUp(ofTouchEventArgs &touch){
    isTouching = false;

    int i = 0;
    for ( vector<ofVec2f>::iterator iter = touchPoints.begin(); iter != touchPoints.end(); ) {
        //int i = std::distance( touchPoints.begin(), iter );
        cout << "i: " << i << endl;
        if ( touch.id == i ) {
            iter = touchPoints.erase( iter );
        }
        i++;
        ++iter;
    }
}

しかし、指を上に動かすとアプリがフリーズするので、ほとんどの場合 touchUp() に何か問題がありますか?

4

2 に答える 2

4

多くのこと: まず第一に、コンテナーを変更 (消去/挿入) することはできず、イテレーターが有効なままであると期待することはできません!

どれどれ。私も変更したいtouchMove

void testApp::touchMoved(const ofTouchEventArgs & touch)
{
  if (touch.id < touchPoints.size())
    touchPoints[touch.id] = ofVec2f(touch.x, touch.y);
}

次に、大きなもの:

void testApp::touchUp(const ofTouchEventArgs & touch)
{
  if (touch.id < touchPoints.size())
    touchPoints.erase(touchPoints.begin() + touch.id);
}

基本的にtouch.id ベクター内の単なるインデックスなので、それを直接使用できます。要素を途中から消去するeraseには、対応するイテレータを呼び出すだけです。begin() + touch.idvector にはランダム アクセス イテレータがあるため、定数時間で言えます。

更新:実際には、コードが壊れていると思います:ベクトルから要素を消去すると、他の要素が上に移動するためtouch.id、コンテナ要素との関連付けが失われます! 必要なのは、ご想像のとおり、連想コンテナーです。

struct testApp
{
  std::map<int, ofVec2f> touchPoints;
  bool isTouching;

  void touchDown(const ofTouchEventArgs & touch)
  {
    isTouching = true;
    touchPoints[touch.id] = ofVec2f(touch.x, touch.y);
  }

  void touchMoved(const ofTouchEventArgs & touch)
  {
    touchPoints[touch.id] = ofVec2f(touch.x, touch.y);
  }

  void touchUp(const ofTouchEventArgs & touch)
  {
    isTouching = false;
    touchPoints.erase(touch.id);
  }
};
于 2011-07-27T20:09:09.970 に答える
0

行った場合iter=touchPoints.erase(iter)は、行うべきではありません++iter。あなたはすでに次の項目に進んでいます。

于 2011-07-27T20:07:43.697 に答える