我需要控制应用程序中触摸点的数量,为此我使用的是矢量容器,我的基本设置是这样的:
//--------------------------------------------------------------
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()中出现了大多数错误,有什么想法吗?
答案 0 :(得分: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
。由于vector具有随机访问迭代器,我们可以在常量时间内说begin() + touch.id
。
更新:实际上我认为您的代码已损坏:从向量中删除元素后,其他元素向上移动,因此您将失去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);
}
};
答案 1 :(得分:0)
如果您已完成iter=touchPoints.erase(iter)
,则不应该++iter
;你已经转到了下一个项目。