Esempio n. 1
0
// EdgeEvent 两个凸点合并成一个新的凸点
void PSLGSSkeleton::handleEdgeEvent(PSLGEdge* event) {
	//如果该边退化为一个点
	if (event->headvex == event->tailvex) {
		delete event->headvex;
		delete event;
		return;
	}
	//计算新顶点的坐标
	QPointF collisionPoint = event->tailvex->movedPosition( event->vanishTime );
	PSLGVertex* collisionvex = new PSLGVertex(collisionPoint, event->vanishTime); 
	//形成两条直骨架
	if ( !PSLGVertex::equalPosition( event->tailvex->oriPosition, collisionPoint ) ) {
		skeleton.push_back( QLineF( event->tailvex->oriPosition, collisionPoint ) );
	}
	if ( !PSLGVertex::equalPosition( event->headvex->oriPosition, collisionPoint ) ) {
		skeleton.push_back( QLineF( event->headvex->oriPosition, collisionPoint ) );
	}

	//增加三角剖分,方向为逆时针
	addTriangleMesh( event->tailvex, event->headvex, collisionPoint, event->vanishTime );
	addTriangleMesh( event->tailvex->firstin->tailvex, event->tailvex, collisionPoint, event->vanishTime );
	addTriangleMesh( event->headvex, event->headvex->firstout->headvex, collisionPoint, event->vanishTime );

	//建立新顶点与相邻边的链接关系
	PSLGVertex* p1 = event->tailvex;
	PSLGVertex* p2 = event->headvex;
	p1->firstin->headvex = collisionvex;
	p2->firstout->tailvex = collisionvex;
	collisionvex->firstin = p1->firstin;
	collisionvex->firstout = p2->firstout;
	collisionvex->type = PSLGVertexType::CONVEX_VERTEX;
	//如果新的两条邻边平行,直接更新两条邻边消失时间为当前的时间,不用更新点的速度
	if ( std::abs( PSLGGraph::determinant( collisionvex->firstin->tailvex, collisionvex, collisionvex->firstout->headvex ) ) < eps ) {
		//collisionvex->type = PSLGVertexType::CONVEX_VERTEX;
		if ( collisionvex->firstin->vanishTime != event->vanishTime ) {
			eventQueue->heapUpdateKey( collisionvex->firstin->heapIndex, event->vanishTime );
		} 
		if ( collisionvex->firstout->vanishTime != event->vanishTime ) {
			eventQueue->heapUpdateKey( collisionvex->firstout->heapIndex, event->vanishTime );
		}
	} else {
		//计算新顶点的速度
		PSLGGraph::calcConvexVertexSpeed( collisionvex );
		//更新新顶点的邻边的消失时间
		double t = PSLGGraph::calcEdgeVanishTime(collisionvex->firstin);
		eventQueue->heapUpdateKey(collisionvex->firstin->heapIndex, t);
		t = PSLGGraph::calcEdgeVanishTime(collisionvex->firstout);
		eventQueue->heapUpdateKey(collisionvex->firstout->heapIndex, t);
	}
	//释放这条边以及两顶点的空间(边已经在队列中删除)
	delete p1;
	delete p2;
	delete event;
	event = NULL;
}
bool SceneParser::addElement(struct basicxmlnode * elementNode, Scene * scene){
	if (!elementNode) {
		std::cout << "SceneParser::addElement: empty element node \n";
		return false;
	}

	// find out element type
	if (std::string(elementNode->tag) == "Plane") {
		return addPlane(elementNode, scene);
	}
  else if (std::string(elementNode->tag) == "CirclePlane") {
		return addCirclePlane(elementNode, scene);
	}
	else if (std::string(elementNode->tag) == "Sphere") {
		return addSphere(elementNode, scene);
	}
	else if (std::string(elementNode->tag) == "Triangle") {
		return addTriangle(elementNode, scene);
	}
	else if (std::string(elementNode->tag) == "Quadric") {
		return addQuadric(elementNode, scene);
	}
	else if (std::string(elementNode->tag) == "Torus") {
		return addTorus(elementNode, scene);
	}
	else if (std::string(elementNode->tag) == "TriangleMesh") {
		return addTriangleMesh(elementNode, scene);
	}
	else {
		std::cout << "SceneParser::addElement: do not know how to generate \"" << elementNode->tag << "\"\n";
		return false;
	}
}
Esempio n. 3
0
void PSLGSSkeleton::handleRemainingEvent( PSLGEdge* event ) {
	if ( event->tailvex->type == PSLGVertexType::MOVING_STEINER_VERTEX && 
		 event->headvex->type == PSLGVertexType::MOVING_STEINER_VERTEX ) {
			 //删除节点以及对应的边
			 PSLGEdge *tin, *tout, *hin, *hout; //尾结点和头结点的入边和出边
			 tin = event->tailvex->firstin;
			 tout = event->tailvex->firstout;
			 hin = event->headvex->firstin;
			 hout = event->headvex->firstout;
			 if ( tout == hin ) {
				 if ( tin->hedge == hout->tedge ) {
					 eventQueue->minHeapRemove( tin->hedge->heapIndex );
					 delete tin->hedge;
				 }
				 QPointF p = event->tailvex->movedPosition( event->vanishTime );
				 if ( PSLGVertex::equalPosition( p, event->tailvex->oriPosition ) ) {
					 p = event->headvex->movedPosition( event->vanishTime );
				 }
				 addTriangleMesh( tin->tailvex, event->tailvex, p, event->vanishTime );
				 addTriangleMesh( event->tailvex, event->headvex, p, event->vanishTime );
				 addTriangleMesh( event->headvex, hout->headvex, p, event->vanishTime );
				 hout->tailvex = tin->headvex;
				 //tin->headvex->firstin = hout;
				 tin->headvex->firstout = hout;
				 tin->hedge = hout->tedge = NULL;
				 PSLGGraph::calcVertexProperty( tin->headvex );
				 eventQueue->heapUpdateKey( tin->heapIndex, PSLGGraph::calcEdgeVanishTime( tin ) );
				 eventQueue->heapUpdateKey( hout->heapIndex, PSLGGraph::calcEdgeVanishTime( hout ) );
				 delete event->headvex;
				 delete event;
			 } else {
				 QPointF p = event->tailvex->movedPosition( event->vanishTime );
				 addTriangleMesh( tin->tailvex, event->tailvex, p, event->vanishTime );
				 addTriangleMesh( event->tailvex, tout->headvex, p, event->vanishTime );
				 addTriangleMesh( hin->tailvex, event->headvex, p, event->vanishTime );
				 addTriangleMesh( event->headvex, hout->headvex, p, event->vanishTime );
				 //保留tin边,并将tin边指向tout的头结点
				 tin->headvex = tout->headvex;
				 tout->headvex->firstin = tin;
				 tin->hedge = tout->hedge;
				 //保留hin边,并将hin指向hout的头结点
				 hin->headvex = hout->headvex;
				 hout->headvex->firstin = hin;
				 hin->hedge = hout->hedge;
				 eventQueue->minHeapRemove( tout->heapIndex ); //删除tout边
				 eventQueue->heapUpdateKey( tin->heapIndex, PSLGGraph::calcEdgeVanishTime( tin ) );
				 eventQueue->minHeapRemove( hout->heapIndex ); //删除hout边
				 eventQueue->heapUpdateKey( hin->heapIndex, PSLGGraph::calcEdgeVanishTime( hin ) );
				 delete tout;
				 delete hout;
				 delete event->tailvex;
				 delete event->headvex;
				 delete event;
			 }
	}
}
Esempio n. 4
0
void wiBULLET::registerObject(Object* object){
	if(object->rigidBody && rigidBodyPhysicsEnabled){
		//XMVECTOR s,r,t;
		//XMMatrixDecompose(&s,&r,&t,XMLoadFloat4x4(&object->world));
		XMFLOAT3 S,T;
		XMFLOAT4 R;
		//XMStoreFloat3(&S,s);
		//XMStoreFloat4(&R,r);
		//XMStoreFloat3(&T,t);
		object->applyTransform();
		object->attachTo(object->GetRoot());

		S = object->scale;
		T = object->translation;
		R = object->rotation;

		if(!object->collisionShape.compare("BOX")){
			addBox(
				S,R,T
				,object->mass,object->friction,object->restitution
				,object->damping,object->kinematic
			);
			object->physicsObjectI=++registeredObjects;
		}
		if(!object->collisionShape.compare("SPHERE")){
			addSphere(
				S.x,T
				,object->mass,object->friction,object->restitution
				,object->damping,object->kinematic
			);
			object->physicsObjectI=++registeredObjects;
		}
		if(!object->collisionShape.compare("CAPSULE")){
			addCapsule(
				S.x,S.y,R,T
				,object->mass,object->friction,object->restitution
				,object->damping,object->kinematic
			);
			object->physicsObjectI=++registeredObjects;
		}
		if(!object->collisionShape.compare("CONVEX_HULL")){
			addConvexHull(
				object->mesh->vertices,
				S,R,T
				,object->mass,object->friction,object->restitution
				,object->damping,object->kinematic
			);
			object->physicsObjectI=++registeredObjects;
		}
		if(!object->collisionShape.compare("MESH")){
			addTriangleMesh(
				object->mesh->vertices,object->mesh->indices,
				S,R,T
				,object->mass,object->friction,object->restitution
				,object->damping,object->kinematic
			);
			object->physicsObjectI=++registeredObjects;
		}
	}

	if(object->mesh->softBody && softBodyPhysicsEnabled){
		XMFLOAT3 s,t;
		XMFLOAT4 r;
		if(object->mesh->hasArmature()){
			s=object->mesh->armature->scale;
			r=object->mesh->armature->rotation;
			t=object->mesh->armature->translation;
		}
		else{
			s=object->scale;
			r=object->rotation;
			t=object->translation;
		}
		addSoftBodyTriangleMesh(
			object->mesh
			,s,r,t
			,object->mass,object->mesh->friction,object->restitution,object->damping
		);
		object->physicsObjectI=++registeredObjects;
	}
}
Esempio n. 5
0
void PSLGSSkeleton::handleSwitchEvent(PSLGEdge* event) {
	PSLGVertex *u, *v;  //event的两个顶点: u指向CONVEX_VERTEX; v指向REFLEX_VERTEX或MOVINGMOVING_STEINER_VERTEX
	
	if ( event->tailvex->type == CONVEX_VERTEX ) {
		u = event->tailvex;
		v = event->headvex;
	} else {
		u = event->headvex;
		v = event->tailvex;
	}
	PSLGEdge *uin, *uout; //u的入边与出边
	PSLGEdge *vin, *vout, *vedge;  //v的入边与出边,以及v的另一条不在多边形上的邻边
	uin = u->firstin;
	uout = u->firstout;
	vin = v->firstin;
	vout = v->firstout;
	if( vin->hedge != NULL ) {
		vedge = vin->hedge;
	} else {
		vedge = vout->tedge;
	}
	QPointF collisionPoint( u->movedPosition( event->vanishTime ) ); //两顶点相遇的点
	addTriangleMesh( v->firstin->tailvex, v, collisionPoint, event->vanishTime );
	addTriangleMesh( v, v->firstout->headvex, collisionPoint, event->vanishTime );
	//如果v为REFLEX_VERTEX,增加两条直骨架边;否则不增加直骨架边
	if ( v->type == PSLGVertexType::REFLEX_VERTEX ) { 
		skeleton.push_back( QLineF( u->oriPosition, collisionPoint ) );
		skeleton.push_back( QLineF( v->oriPosition, collisionPoint ) );
	} 
	//找到vedge的另一个端点
	PSLGVertex* vedge2v; //vedge不同于v的顶点
	if ( vedge->tailvex == v ) {
		vedge2v = vedge->headvex;
	} else {
		vedge2v = vedge->tailvex;
	}

	if ( event->tailvex == u && uin->tailvex == vedge2v ) {
		//三个点u,v,vedge2v一起湮灭
		if ( v->type == PSLGVertexType::MOVING_STEINER_VERTEX ) {
			skeleton.push_back( QLineF( u->oriPosition, collisionPoint ) );
			if ( vedge2v->type == PSLGVertexType::REFLEX_VERTEX ) {
				skeleton.push_back( QLineF( vedge2v->oriPosition, collisionPoint ) );
			}
			addTriangleMesh( vedge2v->firstin->tailvex, vedge2v, collisionPoint, event->vanishTime );
			addTriangleMesh( vedge2v, u, collisionPoint, event->vanishTime );
			addTriangleMesh( vin->tailvex, v, collisionPoint, event->vanishTime );
			addTriangleMesh( v, vout->headvex, collisionPoint, event->vanishTime );
		} else {
			addTriangleMesh( vedge2v, u, collisionPoint, event->vanishTime );
			addTriangleMesh( vedge2v->firstin->tailvex, vedge2v, collisionPoint, event->vanishTime );
		}
		//保留v点,v点的两条邻边为vout, vedge2v->firstin
		v->firstin = vedge2v->firstin;
		vedge2v->firstin->headvex = v;
		v->firstout->tedge = NULL;
		v->firstin->hedge = NULL;
		//计算v点速度
		v->oriPosition.setX( collisionPoint.x() );
		v->oriPosition.setY( collisionPoint.y() );
		v->startTime = event->vanishTime;
		PSLGGraph::calcVertexProperty( v );
		eventQueue->heapUpdateKey( v->firstin->heapIndex, PSLGGraph::calcEdgeVanishTime( v->firstin ) );
		eventQueue->heapUpdateKey( v->firstout->heapIndex, PSLGGraph::calcEdgeVanishTime( v->firstout ) );
		//删除uin,uout,vedge, 删除u,vedge2v
		eventQueue->minHeapRemove( uin->heapIndex );
		eventQueue->minHeapRemove( vedge->heapIndex );
		delete uin;
		delete vedge;
		delete event;
		delete u;
		delete vedge2v;
		return;
	} else if ( event->headvex == u && uout->headvex == vedge2v ){
		if ( v->type == PSLGVertexType::MOVING_STEINER_VERTEX ) {
			skeleton.push_back( QLineF( u->oriPosition, collisionPoint ) );
			if ( vedge2v->type == PSLGVertexType::REFLEX_VERTEX ) {
				skeleton.push_back( QLineF( vedge2v->oriPosition, collisionPoint ) );
			}
			addTriangleMesh( u, vedge2v, collisionPoint, event->vanishTime );
			addTriangleMesh( vedge2v, vedge2v->firstout->headvex, collisionPoint, event->vanishTime );
			addTriangleMesh( vin->tailvex, v, collisionPoint, event->vanishTime );
			addTriangleMesh( v, vout->headvex, collisionPoint, event->vanishTime );
		} else {
			addTriangleMesh( u, vedge2v, collisionPoint, event->vanishTime );
			addTriangleMesh( vedge2v, vedge2v->firstout->headvex, collisionPoint, event->vanishTime );
		}
		//保留v点,v点的两条邻边为vin vedge2v->firstout, 删除uin,uout,vedge
		v->firstout = vedge2v->firstout;
		vedge2v->firstout->tailvex = v;
		v->firstin->hedge = v->firstout->tedge = NULL;
		//计算v点速度
		v->oriPosition.setX( collisionPoint.x() );
		v->oriPosition.setY( collisionPoint.y() );
		v->startTime = event->vanishTime;
		PSLGGraph::calcVertexProperty( v );
		eventQueue->heapUpdateKey( v->firstin->heapIndex, PSLGGraph::calcEdgeVanishTime( v->firstin ) );
		eventQueue->heapUpdateKey( v->firstout->heapIndex, PSLGGraph::calcEdgeVanishTime( v->firstout ) );
		//删除uin,uout,vedge, 删除u,vedge2v
		eventQueue->minHeapRemove( uout->heapIndex );
		eventQueue->minHeapRemove( vedge->heapIndex );
		delete uout;
		delete vedge;
		delete event;
		delete u;
		delete vedge2v;
		return;
	}

	if ( event->tailvex == u ) {  //event的方向是从u到v
		addTriangleMesh( uin->tailvex, u, collisionPoint, event->vanishTime );
		//将event的方向改为从v到u,并更改event的链接关系
		event->tailvex = v;
		event->headvex = u;
		uin->headvex = v;
		v->firstin = uin;
		v->firstout = event;
		u->firstin = event;
		u->firstout = vout;
		vout->tailvex = u;
		event->tedge = event->hedge = NULL;
		vout->tedge = NULL;
	} else { //event的方向从v到u
		addTriangleMesh( u, uout->headvex, collisionPoint, event->vanishTime );
		//将event的方向设为从u到v
		event->tailvex = u;
		event->headvex = v;
		vin->headvex = u;
		u->firstin = vin;
		u->firstout = event;
		v->firstin = event;
		v->firstout = uout;
		uout->tailvex = v;
		event->tedge = event->hedge = NULL;
		vin->hedge = NULL;
	}
	
	//更新顶点的信息
	if ( v->type == PSLGVertexType::REFLEX_VERTEX ) {
		//u的速度发生变化
		u->oriPosition.setX( collisionPoint.x() );
		u->oriPosition.setY( collisionPoint.y() );
		u->startTime = event->vanishTime;
		if ( u->firstin->tailvex == v ) {
			//PSLGGraph::calcVertexProperty( v->firstin->tailvex, u, u->firstout->headvex );
			PSLGGraph::calcConvexVertexSpeed( v->firstin->tailvex, u, u->firstout->headvex );
			eventQueue->heapUpdateKey( u->firstout->heapIndex, PSLGGraph::calcEdgeVanishTime( u->firstout ) );
		} else {
			PSLGGraph::calcConvexVertexSpeed( u->firstin->tailvex, u, v->firstout->headvex );
			//PSLGGraph::calcVertexProperty( u->firstin->tailvex, u, v->firstout->headvex );
			eventQueue->heapUpdateKey( u->firstin->heapIndex, PSLGGraph::calcEdgeVanishTime( u->firstin ) );
		}
	} else {
		if ( u->firstin->tailvex == v ) {
			eventQueue->heapUpdateKey( u->firstout->heapIndex, PSLGGraph::calcEdgeVanishTime( u->firstout ) );
		} else {
			eventQueue->heapUpdateKey( u->firstin->heapIndex, PSLGGraph::calcEdgeVanishTime( u->firstin ) );
		}
	}

	//更新vedge的链接结构
	if ( vedge->tailvex == v ) {
		v->firstout->tedge = vedge;
	} else {
		v->firstin->hedge = vedge;
	}
	//v的速度变化
	v->oriPosition.setX( collisionPoint.x() );
	v->oriPosition.setY( collisionPoint.y() );
	v->startTime = event->vanishTime;
	v->type = PSLGVertexType::MOVING_STEINER_VERTEX;

	if ( u->firstin->tailvex == v ) {
		PSLGGraph::calcMovingSteinerSpeed( v, vedge2v, v->firstin->tailvex );
		eventQueue->heapUpdateKey( v->firstin->heapIndex, PSLGGraph::calcEdgeVanishTime( v->firstin ) );
	} else {
		PSLGGraph::calcMovingSteinerSpeed( v, vedge2v, v->firstout->headvex );
		eventQueue->heapUpdateKey( v->firstout->heapIndex, PSLGGraph::calcEdgeVanishTime( v->firstout ) );
	}
	//更新event, vedge的消失时间
	event->vanishTime = std::numeric_limits< double >::max();
	eventQueue->minHeapInsert( event );
	eventQueue->heapUpdateKey( vedge->heapIndex, PSLGGraph::calcEdgeVanishTime( vedge ) );
}
Esempio n. 6
0
void PSLGSSkeleton::handleStartEvent(PSLGEdge* event) {
	//这个事件不产生直接的skeleton
	PSLGVertex *u, *v; //event的两个顶点,u为REFLEX_VERTEX, v为RESTING_STEINER_VERTEX
	PSLGEdge *uin, *uout; //u的两条多边形上的邻边
	
	if ( event->tailvex->type != PSLGVertexType::RESTING_STEINER_VERTEX ) {
		u = event->tailvex;
		v = event->headvex;
	} else {
		u = event->headvex;
		v = event->tailvex;
	}
	uin = u->firstin;
	uout = u->firstout;
	
	PSLGEdge *vedge1, *vedge2; //v的除event外的两条邻边,其中vedge1与event共线
	vedge1 = vedge2 = NULL;
	std::vector< PSLGEdge* > restes;
	v->getVertexIncidentEdges( restes );
	
	for ( int i = 0; i < restes.size(); i++ ) {
		if ( restes[i] == event ) continue;
		if ( PSLGEdge::isParallel( restes[i], event ) ) {
			vedge1 = restes[i];
		} else {
			vedge2 = restes[i];
		}
	}
	if ( vedge1 == NULL ) {
		//极端情况,v的关联边中没有与event平行的边
		//此时小三角形将消失
		if ( restes[0] == event ) {
			vedge1 = restes[1];
			vedge2 = restes[2];
		} else if ( restes[1] == event ){
			vedge1 = restes[0];
			vedge2 = restes[2];
		} else {
			vedge1 = restes[0];
			vedge2 = restes[1];
		}
		//让vedge1为v的入边,vedge2为v的出边
		if ( vedge1->tailvex == v ) {
			PSLGEdge* temp = vedge1;
			vedge1 = vedge2;
			vedge2 = temp;
		}
		if ( uout->headvex == vedge1->tailvex ) {
			PSLGVertex* vedge1v = vedge1->tailvex;
			addTriangleMesh( uin->tailvex, u, v->oriPosition, event->vanishTime );
			addTriangleMesh( u, vedge1v, v->oriPosition, event->vanishTime );
			//保留vedge1v, vedge1v->firstout, uin, vedge2
			uin->headvex = vedge1v;
			vedge1v->firstin = uin;
			vedge1v->firstout->tedge = vedge2;
			vedge2->tailvex = vedge1v;
			eventQueue->heapUpdateKey( vedge1v->firstin->heapIndex, PSLGGraph::calcEdgeVanishTime( vedge1v->firstin ) );
			eventQueue->heapUpdateKey( vedge2->heapIndex, PSLGGraph::calcEdgeVanishTime( vedge2 ) );
			//删除vedge1, uout, u, v
			eventQueue->minHeapRemove( uout->heapIndex );
			eventQueue->minHeapRemove( vedge1->heapIndex );
			delete uout;
			delete vedge1;
			delete event;
			delete u;
			delete v;
			return;
		} else if ( uin->tailvex == vedge1->tailvex ){
			PSLGVertex* vedge1v = vedge1->tailvex;
			addTriangleMesh( vedge1v, u, v->oriPosition, event->vanishTime );
			addTriangleMesh( u, uout->headvex, v->oriPosition, event->vanishTime );
			//保留vedge1v, vedge1v->firstin, uout
			vedge1v->firstout = uout;
			uout->tailvex = vedge1v;
			vedge2->tailvex = vedge1v;
			vedge1v->firstout->tedge = vedge2;
			eventQueue->heapUpdateKey( vedge1v->firstout->heapIndex, PSLGGraph::calcEdgeVanishTime( vedge1v->firstout ) );
			eventQueue->heapUpdateKey( vedge2->heapIndex, PSLGGraph::calcEdgeVanishTime( vedge2 ) );
			//删除uin, vedge1, u, v
			eventQueue->minHeapRemove( uin->heapIndex );
			eventQueue->minHeapRemove( vedge1->heapIndex );
			delete uin;
			delete vedge1;
			delete event;
			delete u;
			delete v;
			return;
		}else if ( uout->headvex == vedge2->headvex ) {
			PSLGVertex* vedge2v = vedge2->headvex;
			addTriangleMesh( uin->tailvex, u, v->oriPosition, event->vanishTime );
			addTriangleMesh( u, vedge2v, v->oriPosition, event->vanishTime );
			//保留uin, vedge2v->firstout, vedge1
			vedge2v->firstin = uin;
			uin->headvex = vedge2v;
			vedge1->headvex = vedge2v;
			vedge2v->firstin->hedge = vedge1;
			eventQueue->heapUpdateKey( vedge2v->firstin->heapIndex, PSLGGraph::calcEdgeVanishTime( vedge2v->firstin ) );
			eventQueue->heapUpdateKey( vedge1->heapIndex, PSLGGraph::calcEdgeVanishTime( vedge1 ) );
			//删除 uout, vedge2, u, v
			eventQueue->minHeapRemove( uout->heapIndex );
			eventQueue->minHeapRemove( vedge2->heapIndex );
			delete uout;
			delete vedge2;
			delete event;
			delete u;
			delete v;
			return;
		} else if ( uin->tailvex == vedge2->headvex ) {
			PSLGVertex* vedge2v = vedge2->headvex;
			addTriangleMesh( vedge2v, u, v->oriPosition, event->vanishTime );
			addTriangleMesh( u, uout->headvex, v->oriPosition, event->vanishTime );
			//保留 vedge2v->firstin, uout, vedge1
			vedge2v->firstout = uout;
			uout->tailvex = vedge2v;
			vedge1->headvex = vedge2v;
			vedge2v->firstin->hedge = vedge1;
			eventQueue->heapUpdateKey( vedge2v->firstout->heapIndex, PSLGGraph::calcEdgeVanishTime( vedge2v->firstout ) );
			eventQueue->heapUpdateKey( vedge1->heapIndex, PSLGGraph::calcEdgeVanishTime( vedge1 ) );
			//删除uin, vedge2, u, v
			eventQueue->minHeapRemove( uin->heapIndex );
			eventQueue->minHeapRemove( vedge2->heapIndex );
			delete uin;
			delete vedge2;
			delete event;
			delete u;
			delete v;
			return;
		}
	}
	//判断vedge2与uout是否位于event的同一侧
	PSLGVertex *vedge2v; //vedge2的不同于v的端点
	if ( vedge2->tailvex == v ) {
		vedge2v = vedge2->headvex;
	} else {
		vedge2v = vedge2->tailvex;
	}
	PSLGVertex* vt;
	for ( vt = uout->headvex; vt->type == PSLGVertexType::MOVING_STEINER_VERTEX; vt = vt->firstout->headvex );
	double d1 = PSLGGraph::determinant( u, v, vt );
	double d2 = PSLGGraph::determinant( u, v, vedge2v);
	if ( d1* d2 > 0 ) {  
		//vedge2与uout位于event的同侧
		//vedge2v与uout->headvex相等,此时uout、vedge2将消失
		if ( vedge2v == uout->headvex ) {
			addTriangleMesh( u, vedge2v, v->oriPosition, event->vanishTime );
			addTriangleMesh( vedge2v, vedge2v->firstout->headvex, v->oriPosition, event->vanishTime );
			u->firstout = vedge2v->firstout;
			vedge2v->firstout->tailvex = u;
			//更新vedge1的链接结构
			if ( vedge1->tailvex == v ) {
				vedge1->tailvex = u;
				u->firstout->tedge = vedge1;
			} else {
				vedge1->headvex = u;
				u->firstin->hedge = vedge1;
			}
			//更新vedge1、u->firstout的时间
			eventQueue->heapUpdateKey( vedge1->heapIndex, PSLGGraph::calcEdgeVanishTime( vedge1 ) );
			eventQueue->heapUpdateKey( u->firstout->heapIndex, PSLGGraph::calcEdgeVanishTime( u->firstout ) );
			//删除uout、vedge2和v、vedge2v
			eventQueue->minHeapRemove( vedge2->heapIndex );
			eventQueue->minHeapRemove( uout->heapIndex );
			delete vedge2;
			delete uout;
			delete event;
			delete v;
			delete vedge2v;
			return;
		}
		//uout将被v点(vedge2)拆成两条边
		addTriangleMesh( u, uout->headvex, v->oriPosition, event->vanishTime );
		//将event的方向改为从u到v
		event->tailvex = u;
		event->headvex = v;
		event->hedge = event->tedge = NULL;
		//将event插入uout中,更新uin,uout的链接结构
		u->firstout = event;
		v->firstin = event;
		v->firstout = uout;
		uout->tailvex = v;
		uin->hedge = NULL;
		uout->tedge = NULL;
		//更新vedge1的链接结构
		if ( vedge1->tailvex == v ) {
			vedge1->tailvex = u;
			event->tedge = vedge1;
		} else {
			vedge1->headvex = u;
			uin->hedge = vedge1;
		}
		//更新vedge2的链接结构
		if ( vedge2->tailvex == v ) {
			uout->tedge = vedge2;
		} else {
			event->hedge = vedge2;
		}
		//更新v点的属性
		v->type = PSLGVertexType::MOVING_STEINER_VERTEX;
		v->startTime = event->vanishTime;
		PSLGGraph::calcMovingSteinerSpeed( v, vedge2v, uout->headvex );
		//更新uout的消失时间
		eventQueue->heapUpdateKey( uout->heapIndex, PSLGGraph::calcEdgeVanishTime( uout ) );
	} else { 
		//vedge2与uout位于event的异侧
		//vedge2v与uin->tailVex相等,此时uin、vedge2将消失
		if ( vedge2v == uin->tailvex ) {
			addTriangleMesh( vedge2v->firstin->tailvex, vedge2v, v->oriPosition, event->vanishTime );
			addTriangleMesh( vedge2v, u, v->oriPosition, event->vanishTime );
			u->firstin = vedge2v->firstin;
			vedge2v->firstin->headvex = u;
			//更新vedge1的链接结构
			if ( vedge1->tailvex == v ) {
				vedge1->tailvex = u;
				u->firstout->tedge = vedge1;
			} else {
				vedge1->headvex = u;
				u->firstin->hedge = vedge1;
			}
			//更新vedge1、u->firstout的时间
			eventQueue->heapUpdateKey( vedge1->heapIndex, PSLGGraph::calcEdgeVanishTime( vedge1 ) );
			eventQueue->heapUpdateKey( u->firstin->heapIndex, PSLGGraph::calcEdgeVanishTime( u->firstin ) );
			//删除uin、vedge2和v、vedge2v
			eventQueue->minHeapRemove( vedge2->heapIndex );
			eventQueue->minHeapRemove( uin->heapIndex );
			delete vedge2;
			delete uin;
			delete event;
			delete v;
			delete vedge2v;
			return;
		}
		//uin将被v点(vedge2)拆成两条边
		addTriangleMesh( uin->tailvex, u, v->oriPosition, event->vanishTime );
		//将event的方向改为从v到u
		event->tailvex = v;
		event->headvex = u;
		event->hedge = event->tedge = NULL;
		//将event插入uin中,更新uin,uout的链接结构
		u->firstin = event;
		v->firstout = event;
		v->firstin = uin;
		uin->headvex = v;
		uin->hedge = NULL;
		uout->tedge = NULL;
		//更新vedge1的链接结构
		if ( vedge1->tailvex == v ) {
			vedge1->tailvex = u;
			uout->tedge = vedge1;
		} else {
			vedge1->headvex = u;
			event->hedge = vedge1;
		}
		//更新vedge2的链接结构
		if ( vedge2->tailvex == v ) {
			event->tedge = vedge2;
		} else {
			uin->hedge = vedge2;
		}
		//更新v点的属性
		v->type = PSLGVertexType::MOVING_STEINER_VERTEX; //类型
		v->startTime = event->vanishTime; //开始时间
		PSLGGraph::calcMovingSteinerSpeed( v, vedge2v, uin->tailvex ); //消失时间
		//更新uin的消失时间
		eventQueue->heapUpdateKey( uin->heapIndex, PSLGGraph::calcEdgeVanishTime( uin ) );
	}
	//更新event, vedge1,vedge2的消失时间
	event->vanishTime = std::numeric_limits< double >::max();
	event->type = PSLGEdgeType::POLYGON_EDGE;
	eventQueue->minHeapInsert( event );
	eventQueue->heapUpdateKey( vedge1->heapIndex, PSLGGraph::calcEdgeVanishTime( vedge1 ) );
	eventQueue->heapUpdateKey( vedge2->heapIndex, PSLGGraph::calcEdgeVanishTime( vedge2 ) );
}
Esempio n. 7
0
void PSLGSSkeleton::handleSplitEvent(PSLGEdge* event) {
	if ( event->type == PSLGEdgeType::POLYGON_EDGE ) {
		PSLGVertex *u, *v; //u为凹点,v为Moving点
		if ( event->tailvex->type == PSLGVertexType::REFLEX_VERTEX ) {
			u = event->tailvex;
			v = event->headvex;
		} else {
			u = event->headvex;
			v = event->tailvex;
		}
		PSLGEdge* uedge = NULL; //u的另一条非多边形边
		PSLGVertex* uedgev = NULL;
		uedge = u->firstout->tedge;
		uedgev = uedge->headvex;
		if ( uedge == NULL ) { 
			uedge = u->firstin->hedge;
			uedgev = uedge->tailvex;
		}
		PSLGEdge* vedge = NULL; //v的另一条非多边形边
		vedge = v->firstin->hedge;
		if ( vedge == NULL ) {
			vedge = v->firstout->tedge;
		}
		PSLGEdge* uedge2; 
		std::vector< PSLGEdge* > restedges;
		uedgev->getVertexIncidentEdges( restedges );
		for ( std::vector< PSLGEdge* >::size_type i = 0; i < restedges.size(); i++ ) {
			if ( restedges[i] == vedge || restedges[i] == uedge ) continue;
			uedge2 = restedges[i];
		}
		if ( event->tailvex == v ) {
			addTriangleMesh( v->firstin->tailvex, v, uedgev->oriPosition, event->vanishTime );
			addTriangleMesh( v, u, uedgev->oriPosition, event->vanishTime );
			//保留 u->firstout, v->firstin
			v->firstin->headvex = u;
			u->firstin = v->firstin;
			if ( uedge2->tailvex == uedgev ) {
				uedge2->tailvex = u;
				u->firstout->tedge = uedge2;
				u->firstin->hedge = NULL;
			} else {
				uedge2->headvex = u;
				u->firstin->hedge = uedge2;
				u->firstout->tedge = NULL;
			}
			eventQueue->heapUpdateKey( uedge2->heapIndex, PSLGGraph::calcEdgeVanishTime( uedge2 ) );
			eventQueue->heapUpdateKey( u->firstin->heapIndex, PSLGGraph::calcEdgeVanishTime( u->firstin ) );
			//删除 vedge, uedge, uedgev, v
			eventQueue->minHeapRemove( vedge->heapIndex );
			eventQueue->minHeapRemove( uedge->heapIndex );
			delete vedge;
			delete uedge;
			delete event;
			delete uedgev;
			delete v;
			return;
		} else {
			addTriangleMesh( u, v, uedgev->oriPosition, event->vanishTime );
			addTriangleMesh( v, v->firstout->headvex, uedgev->oriPosition, event->vanishTime );
			//保留 uin, v->firstout, vedge2
			v->firstout->tailvex = u;
			u->firstout = v->firstout;
			if ( uedge2->tailvex == uedgev ) {
				uedge2->tailvex = u;
				u->firstout->tedge = uedge2;
				u->firstin->hedge = NULL;
			} else {
				uedge2->headvex = u;
				u->firstin->hedge = uedge2;
				u->firstout->tedge = NULL;
			}
			eventQueue->heapUpdateKey( u->firstout->heapIndex, PSLGGraph::calcEdgeVanishTime( u->firstout ) );
			eventQueue->heapUpdateKey( uedge2->heapIndex, PSLGGraph::calcEdgeVanishTime( uedge2 ) );
			//删除vedge, uedge, v, uedgev
			eventQueue->minHeapRemove( vedge->heapIndex );
			eventQueue->minHeapRemove( uedge->heapIndex );
			delete vedge;
			delete uedge;
			delete event;
			delete v;
			delete uedgev;
			return;
		}
	}
	//计算两顶点相遇的顶点坐标
	QPointF collisionPoint = event->tailvex->movedPosition( event->vanishTime );
	//将凹点对应的边加到直骨架中,并增加三角剖分
	if ( event->tailvex->type == PSLGVertexType::REFLEX_VERTEX ) {
		skeleton.push_back( QLineF( event->tailvex->oriPosition, collisionPoint ) );
		addTriangleMesh( event->tailvex->firstin->tailvex, event->tailvex, collisionPoint, event->vanishTime );
		addTriangleMesh( event->tailvex, event->tailvex->firstout->headvex, collisionPoint, event->vanishTime );
		addTriangleMesh( event->headvex->firstin->tailvex, event->headvex, collisionPoint, event->vanishTime );
		addTriangleMesh( event->headvex, event->headvex->firstout->headvex, collisionPoint, event->vanishTime );
	} else {
		skeleton.push_back( QLineF (event->headvex->oriPosition, collisionPoint ) );
		addTriangleMesh( event->headvex->firstin->tailvex, event->headvex, collisionPoint, event->vanishTime );
		addTriangleMesh( event->headvex, event->headvex->firstout->headvex, collisionPoint, event->vanishTime );
		addTriangleMesh( event->tailvex->firstin->tailvex, event->tailvex, collisionPoint, event->vanishTime );
		addTriangleMesh( event->tailvex, event->tailvex->firstout->headvex, collisionPoint, event->vanishTime );
	}
	//更新两个端点的坐标和起始时间
	event->tailvex->oriPosition.setX( collisionPoint.x() );
	event->tailvex->oriPosition.setY( collisionPoint.y() );
	event->tailvex->startTime = event->vanishTime;
	event->headvex->oriPosition.setX( collisionPoint.x() );
	event->headvex->oriPosition.setY( collisionPoint.y() );
	event->headvex->startTime = event->vanishTime;
	//分别找到两个顶点对应的多边形上的出边和入边
	//规定顶点的firstin和firstout即为多边形上的入边和出边,在创建图结构的时候维持这一性质
	PSLGEdge *tin, *tout, *hin, *hout;
	tin = event->tailvex->firstin;
	tout = event->tailvex->firstout;
	hin = event->headvex->firstin;
	hout = event->headvex->firstout;
    tout->tedge = NULL;
	hin->hedge = NULL;

	if ( tout->headvex == hin->tailvex ){
		//event、tout、hin构成的三角形将消失
		skeleton.push_back( QLineF( tout->headvex->oriPosition, collisionPoint ) );
		//保留event->tailvertex、tin、hout
		event->tailvex->firstout = hout;
		hout->tailvex = event->tailvex;
		PSLGGraph::calcVertexProperty( event->tailvex );
		eventQueue->heapUpdateKey( tin->heapIndex, PSLGGraph::calcEdgeVanishTime( tin ) );
		eventQueue->heapUpdateKey( hout->heapIndex, PSLGGraph::calcEdgeVanishTime( hout ) );
		//删除 tout、hin、tout->headvex、event、event->headvertex
		delete tout->headvex;
		eventQueue->minHeapRemove( tout->heapIndex );
		delete tout;
		eventQueue->minHeapRemove( hin->heapIndex );
		delete hin;
		delete event->headvex;
		delete event;
		return;
	} else if ( tin->tailvex == hout->headvex ) {
		//event、tin、hout构成的三角形将消失
		skeleton.push_back( QLineF( tin->tailvex->oriPosition, collisionPoint ) );
		//保留event->tailvertex、tout、hin
		event->tailvex->firstin = hin;
		hin->headvex = event->tailvex;
		PSLGGraph::calcVertexProperty( event->tailvex );
		eventQueue->heapUpdateKey( tout->heapIndex, PSLGGraph::calcEdgeVanishTime( tout ) );
		eventQueue->heapUpdateKey( hin->heapIndex, PSLGGraph::calcEdgeVanishTime( hin ) );
		//删除 tin、hout、tin->tailvex、event、event->headvertex
		delete tin->tailvex;
		eventQueue->minHeapRemove( tin->heapIndex );
		delete tin;
		eventQueue->minHeapRemove( hout->heapIndex );
		delete hout;
		delete event->headvex;
		delete event;
		return;
	}
	
    //改变两个端点的边链接关系
	event->tailvex->firstout = hout;
	hout->tailvex = event->tailvex;
	event->headvex->firstout = tout;
	tout->tailvex = event->headvex;
	event->tailvex->type = PSLGVertexType::CONVEX_VERTEX;
	//更新两个顶点的速度及四条邻边的消失时间,如果新顶点的两条边平行,新顶点的速度为0,邻边消失时间为当前时间
	//更新尾结点的速度和邻边消失时间
	if ( std::abs( PSLGGraph::determinant( event->tailvex->firstin->tailvex, event->tailvex, event->tailvex->firstout->headvex ) ) < eps ) {
		//event->tailvex->type = PSLGVertexType::CONVEX_VERTEX;
		event->tailvex->speed.setX( 0 );
		event->tailvex->speed.setY( 0 );
		eventQueue->heapUpdateKey( event->tailvex->firstin->heapIndex, event->vanishTime );
		eventQueue->heapUpdateKey( event->tailvex->firstout->heapIndex, event->vanishTime );
	} else {
		//更新两个顶点的速度
		//PSLGGraph::calcVertexProperty( event->tailvex );
		PSLGGraph::calcConvexVertexSpeed( event->tailvex );
		//更新四条邻边的消失时间
		double t = PSLGGraph::calcEdgeVanishTime( event->tailvex->firstin );
		eventQueue->heapUpdateKey( event->tailvex->firstin->heapIndex, t );
		t = PSLGGraph::calcEdgeVanishTime( event->tailvex->firstout );
		eventQueue->heapUpdateKey( event->tailvex->firstout->heapIndex, t );
	}
	//更新头结点的速度和邻边消失时间
	event->headvex->type = PSLGVertexType::CONVEX_VERTEX;
	if ( std::abs( PSLGGraph::determinant( event->headvex->firstin->tailvex, event->headvex, event->headvex->firstout->headvex ) ) < eps ) {
		//event->headvex->type = PSLGVertexType::CONVEX_VERTEX;
		event->headvex->speed.setX( 0 );
		event->headvex->speed.setY( 0 );
		eventQueue->heapUpdateKey( event->headvex->firstin->heapIndex, event->vanishTime );
		eventQueue->heapUpdateKey( event->headvex->firstout->heapIndex, event->vanishTime );
	} else {
		PSLGGraph::calcConvexVertexSpeed( event->headvex );

		double t = PSLGGraph::calcEdgeVanishTime( event->headvex->firstin );
		eventQueue->heapUpdateKey( event->headvex->firstin->heapIndex, t );
		t = PSLGGraph::calcEdgeVanishTime( event->headvex->firstout );
		eventQueue->heapUpdateKey( event->headvex->firstout->heapIndex, t );
	}

	delete event;
	event = NULL;
}