// 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; } }
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; } } }
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; } }
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 ) ); }
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 ) ); }
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; }