bool kbLine::OkeForContour( kbLine* const nextline, double factor, kbNode* LastLeft, kbNode* LastRight, LinkStatus& _outproduct ) { assert( m_link ); assert( m_valid_parameters ); assert( nextline->m_link ); assert( nextline->m_valid_parameters ); factor = fabs( factor ); // PointStatus status=ON_AREA; double distance = 0; kbNode offs_end_next( nextline->m_link->GetEndNode(), m_GC ); _outproduct = m_link->OutProduct( nextline->m_link, m_GC->GetAccur() ); switch ( _outproduct ) { // current line lies on leftside of prev line case IS_RIGHT : { nextline->Virtual_Point( &offs_end_next, -factor ); // status= nextline->PointOnLine( LastRight, distance, m_GC->GetAccur() ); if ( distance > factor ) { PointOnLine( &offs_end_next, distance, m_GC->GetAccur() ); if ( distance > factor ) return( true ); } } break; // current line lies on rightside of prev line case IS_LEFT : { nextline->Virtual_Point( &offs_end_next, factor ); // status= nextline->PointOnLine( LastLeft, distance, m_GC->GetAccur() ); if ( distance < -factor ) { PointOnLine( &offs_end_next, distance, m_GC->GetAccur() ); if ( distance < -factor ) return( true ); } } break; // current line lies on prev line case IS_ON : { return( true ); } }//end switch return( false ); }
//------------------------------------------------------------------------------------------------------ //function that checks if line segment collides with another sphere object //------------------------------------------------------------------------------------------------------ bool Line3D::IsColliding(const Sphere3D& secondSphere) const { glm::vec3 distanceFromLine; //calculate the distance the sphere and point on line segment are apart from each other //this makes use of inner function that calculates the point on line segment closest to sphere distanceFromLine = secondSphere.GetPosition() - PointOnLine(secondSphere.GetPosition().x, secondSphere.GetPosition().y, secondSphere.GetPosition().z); //return flag based on if line segment intersects with sphere return (glm::length(distanceFromLine) <= secondSphere.GetRadius()); }
// // test if a point lies in the linesegment. If the point isn't on the line // the function returns a value that indicates on which side of the // line the point is (in linedirection from first point to second point // // returns LEFT_SIDE, when point lies on the left side of the line // RIGHT_SIDE, when point lies on the right side of the line // ON_AREA, when point lies on the infinite line within a range // IN_AREA, when point lies in the area of the linesegment // the returnvalues are declared in (LINE.H) PointStatus kbLine::PointInLine( kbNode *a_node, double& Distance, double Marge ) { Distance = 0; //Punt must exist assert( a_node ); // link must exist to get beginnode and endnode via link assert( m_link ); // get the nodes form the line via the link kbNode *bp, *ep; bp = m_link->GetBeginNode(); ep = m_link->GetEndNode(); // both node must exist assert( bp && ep ); // node may not be the same assert( bp != ep ); //quick test if point is begin or endpoint if ( a_node == bp || a_node == ep ) return IN_AREA; int Result_of_BBox = false; PointStatus Result_of_Online; // Checking if point is in bounding-box with marge B_INT xmin = bmin( bp->GetX(), ep->GetX() ); B_INT xmax = bmax( bp->GetX(), ep->GetX() ); B_INT ymin = bmin( bp->GetY(), ep->GetY() ); B_INT ymax = bmax( bp->GetY(), ep->GetY() ); if ( a_node->GetX() >= ( xmin - Marge ) && a_node->GetX() <= ( xmax + Marge ) && a_node->GetY() >= ( ymin - Marge ) && a_node->GetY() <= ( ymax + Marge ) ) Result_of_BBox = true; // Checking if point is on the infinite line Result_of_Online = PointOnLine( a_node, Distance, Marge ); // point in boundingbox of the line and is on the line then the point is IN_AREA if ( ( Result_of_BBox ) && ( Result_of_Online == ON_AREA ) ) return IN_AREA; else return Result_of_Online; }
bool C_CoordinateTransform::CalcTransformationMatrix() { for ( unsigned int j = 0; j < p->m_oMarkerPoints.height - 1; ++j ) { for ( unsigned int i = 0; i < p->m_oMarkerPoints.width - 1; ++i ) { Point2f oIP1 = p->m_oImagePoints.get_element(i, j); Point2f oIP2 = p->m_oImagePoints.get_element(i + 1, j); Point2f oIP3 = p->m_oImagePoints.get_element(i, j + 1); Point2f oIP4 = p->m_oImagePoints.get_element(i + 1, j + 1); Point2f oDP1 = p->m_oDisplayPoints.get_element(i, j); Point2f oDP2 = p->m_oDisplayPoints.get_element(i + 1, j); Point2f oDP3 = p->m_oDisplayPoints.get_element(i, j + 1); Point2f oDP4 = p->m_oDisplayPoints.get_element(i + 1, j + 1); long lHE = (p->m_oTransformationMatrix.matrix_size.height / (p->m_oMarkerPoints.height - 1)); long lWE = (p->m_oTransformationMatrix.matrix_size.width / (p->m_oMarkerPoints.width - 1)); for ( long lY = 0; lY < lHE; ++lY ) { for ( long lX = 0; lX < lWE; ++lX ) { Point2f oIPy1, oIPy2; PointOnLine(oIPy1, oIP1, oIP3, (float)lY / (float)lHE ); PointOnLine(oIPy2, oIP2, oIP4, (float)lY / (float)lHE ); Point2f oIP; PointOnLine(oIP, oIPy1, oIPy2, (float)lX / (float)lWE ); Point2f oDPy1, oDPy2; PointOnLine(oDPy1, oDP1, oDP3, (float)lY / (float)lHE ); PointOnLine(oDPy2, oDP2, oDP4, (float)lY / (float)lHE ); Point2f oDP; PointOnLine(oDP, oDPy1, oDPy2, (float)lX / (float)lWE ); p->m_oTransformationMatrix.set_element((unsigned int)oIP.x, (unsigned int)oIP.y, Point2i( (long)oDP.x, (long)oDP.y )); } } } } p->m_oCoordinateTransformationSystemStatus = E_ctssCALIBRATED; return true; }
// Find closest points to each other from two lines (or segments). uint32_t plClosest::PointsOnLines(const hsPoint3& p0, const hsVector3& v0, const hsPoint3& p1, const hsVector3& v1, hsPoint3& cp0, hsPoint3& cp1, uint32_t clamp) { float invV0Sq = v0.MagnitudeSquared(); // First handle degenerate cases. // v0 is zero length. Resolves to finding closest point on p1+v1 to p0 if( invV0Sq < kRealSmall ) { cp0 = p0; return kClamp0 | PointOnLine(p0, p1, v1, cp1, clamp); } invV0Sq = 1.f / invV0Sq; // The real thing here, two non-zero length segments. (v1 can // be zero length, it doesn't affect the math like |v0|=0 does, // so we don't even bother to check. Only means maybe doing extra // work, since we're using segment-segment math when all we really // need is point-segment.) // The parameterized points for along each of the segments are // P(t0) = p0 + v0*t0 // P(t1) = p1 + v1*t1 // // The closest point on p0+v0 to P(t1) is: // cp0 = p0 + ((P(t1) - p0) dot v0) * v0 / ||v0|| ||x|| is mag squared here // cp0 = p0 + v0*t0 => t0 = ((P(t1) - p0) dot v0 ) / ||v0|| // t0 = ((p1 + v1*t1 - p0) dot v0) / ||v0|| // // The distance squared from P(t1) to cp0 is: // (cp0 - P(t1)) dot (cp0 - P(t1)) // // This expands out to: // // CV0 dot CV0 + 2 CV0 dot DV0 * t1 + (DV0 dot DV0) * t1^2 // // where // // CV0 = p0 - p1 + ((p1 - p0) dot v0) / ||v0||) * v0 == vector from p1 to closest point on p0+v0 // and // DV0 = ((v1 dot v0) / ||v0||) * v0 - v1 == ortho divergence vector of v1 from v0 negated. // // Taking the first derivative to find the local minimum of the function gives // // t1 = - (CV0 dot DV0) / (DV0 dot DV0) // and // t0 = ((p1 - v1 * t1 - p0) dot v0) / ||v0|| // // which seems kind of obvious in retrospect. hsVector3 p0subp1(&p0, &p1); hsVector3 CV0 = p0subp1; CV0 += v0 * p0subp1.InnerProduct(v0) * -invV0Sq; hsVector3 DV0 = v0 * (v1.InnerProduct(v0) * invV0Sq) - v1; // Check for the vectors v0 and v1 being parallel, in which case // following the lines won't get us to any closer point. float DV0dotDV0 = DV0.InnerProduct(DV0); if( DV0dotDV0 < kRealSmall ) { // If neither is clamped, return any two corresponding points. // If one is clamped, return closest points in its clamp range. // If both are clamped, well, both are clamped. The distance between // points will no longer be the distance between lines. // In any case, the distance between the points should be correct. uint32_t clamp1 = PointOnLine(p0, p1, v1, cp1, clamp); uint32_t clamp0 = PointOnLine(cp1, p0, v0, cp0, clamp >> 1); return clamp1 | (clamp0 << 1); }
bool Line::PointOnLine(const Point& pt) const { DoublePoint dblPt(pt); return PointOnLine(dblPt); }