// DragTo void OffsetCenterState::DragTo(BPoint current, uint32 modifiers) { // apply the pivot offset on a temporary copy, // calculate the effect on the translation and compensate it fParent->InverseTransform(¤t); AdvancedTransform t(*fParent); BPoint originA(B_ORIGIN); t.Transform(&originA); t.SetPivot(t.Pivot() + (current - fOrigin)); BPoint originB(B_ORIGIN); t.Transform(&originB); originA = originA - originB; fParent->SetTransformation(t.Pivot(), t.Translation() + originA, t.LocalRotation(), t.LocalXScale(), t.LocalYScale()); fOrigin = current; }
double capsuleBoxDistance(const Vector3d& a_start, const Vector3d& a_end, const double a_radius, const Vector3d& b_center, const Vector3d& b_half_length, Vector3d& direction) { btTransform tr[2]; Matrix3d rotationA; rotation_from_tangent((a_start - a_end).normalized(), rotationA); btMatrix3x3 basisA; basisA.setValue(rotationA(0,1), rotationA(0,0), rotationA(0,2), rotationA(1,1), rotationA(1,0), rotationA(1,2), rotationA(2,1), rotationA(2,0), rotationA(2,2)); btMatrix3x3 basisB; basisB.setIdentity(); tr[0].setBasis(basisA); tr[1].setBasis(basisB); Vector3d mid_point = (a_start + a_end)/2.0; btVector3 originA(mid_point(0), mid_point(1), mid_point(2)); btVector3 originB(b_center(0), b_center(1), b_center(2)); tr[0].setOrigin(originA); tr[1].setOrigin(originB); btCollisionShape* shapePtr[2]; btCapsuleShape capsule(btScalar(a_radius), btScalar((a_start-a_end).norm())); btBoxShape box(btVector3(b_half_length(0), b_half_length(1), b_half_length(2))); shapePtr[0] = &capsule; shapePtr[1] = &box; btDefaultCollisionConfiguration collisionConfiguration; btCollisionDispatcher dispatcher(&collisionConfiguration); btDbvtBroadphase pairCache; btCollisionWorld world (&dispatcher,&pairCache,&collisionConfiguration); world.getDispatchInfo().m_convexMaxDistanceUseCPT = true; MyContactResultCallback result; btCollisionObject obA; obA.setCollisionShape(shapePtr[0]); obA.setWorldTransform(tr[0]); btCollisionObject obB; obB.setCollisionShape(shapePtr[1]); obB.setWorldTransform(tr[1]); world.contactPairTest(&obA,&obB,result); direction = result.positionWorldOnB - result.positionWorldOnA; return result.distance; }
//Returns the minimun distance between a sphere and a box. If the distance is positive, the sphere is not colliding. If the distance is negative, the absolute value of it is the minimun intersecting distance. //direction is a vector describing the minimun movement the sphere needs to take in order to fix the interesection. double sphereBoxDistance(const Vector3d& a_center, const double a_radius, const Vector3d& b_center, const Vector3d& b_half_length, Vector3d& direction) { btTransform tr[2]; btMatrix3x3 basisA; basisA.setIdentity(); btMatrix3x3 basisB; basisB.setIdentity(); tr[0].setBasis(basisA); tr[1].setBasis(basisB); btVector3 originA(a_center(0), a_center(1), a_center(2)); btVector3 originB(b_center(0), b_center(1), b_center(2)); tr[0].setOrigin(originA); tr[1].setOrigin(originB); btConvexShape* shapePtr[2]; btCapsuleShape sphere(btScalar(a_radius), btScalar(0)); btBoxShape box(btVector3(b_half_length(0), b_half_length(1), b_half_length(2))); shapePtr[0] = &sphere; shapePtr[1] = &box; btDefaultCollisionConfiguration collisionConfiguration; btCollisionDispatcher dispatcher(&collisionConfiguration); btDbvtBroadphase pairCache; btCollisionWorld world (&dispatcher,&pairCache,&collisionConfiguration); world.getDispatchInfo().m_convexMaxDistanceUseCPT = true; MyContactResultCallback result; btCollisionObject obA; obA.setCollisionShape(shapePtr[0]); obA.setWorldTransform(tr[0]); btCollisionObject obB; obB.setCollisionShape(shapePtr[1]); obB.setWorldTransform(tr[1]); world.contactPairTest(&obA,&obB,result); direction = result.positionWorldOnB - result.positionWorldOnA; return result.distance; }
EDA_RECT EDA_RECT::Common( const EDA_RECT& aRect ) const { EDA_RECT r; if( Intersects( aRect ) ) { wxPoint originA( std::min( GetOrigin().x, GetEnd().x ), std::min( GetOrigin().y, GetEnd().y ) ); wxPoint originB( std::min( aRect.GetOrigin().x, aRect.GetEnd().x ), std::min( aRect.GetOrigin().y, aRect.GetEnd().y ) ); wxPoint endA( std::max( GetOrigin().x, GetEnd().x ), std::max( GetOrigin().y, GetEnd().y ) ); wxPoint endB( std::max( aRect.GetOrigin().x, aRect.GetEnd().x ), std::max( aRect.GetOrigin().y, aRect.GetEnd().y ) ); r.SetOrigin( wxPoint( std::max( originA.x, originB.x ), std::max( originA.y, originB.y ) ) ); r.SetEnd ( wxPoint( std::min( endA.x, endB.x ), std::min( endA.y, endB.y ) ) ); } return r; }