?? geometry.c
字號:
int iSol; double dSol1, dSol2; double h = circle.getCenter().getX(); double k = circle.getCenter().getY(); // line: x = -c/b (if a = 0) // circle: (x-h)^2 + (y-k)^2 = r^2, with h = center.x and k = center.y // fill in:(-c/b-h)^2 + y^2 -2ky + k^2 - r^2 = 0 // y^2 -2ky + (-c/b-h)^2 + k^2 - r^2 = 0 // and determine solutions for y using abc-formula if( fabs(m_a) < EPSILON ) { iSol = Geometry::abcFormula( 1, -2*k, ((-m_c/m_b) - h)*((-m_c/m_b) - h) + k*k - circle.getRadius()*circle.getRadius(), &dSol1, &dSol2); posSolution1->setVecPosition( (-m_c/m_b), dSol1 ); posSolution2->setVecPosition( (-m_c/m_b), dSol2 ); return iSol; } // ay + bx + c = 0 => y = -b/a x - c/a, with da = -b/a and db = -c/a // circle: (x-h)^2 + (y-k)^2 = r^2, with h = center.x and k = center.y // fill in:x^2 -2hx + h^2 + (da*x-db)^2 -2k(da*x-db) + k^2 - r^2 = 0 // x^2 -2hx + h^2 + da^2*x^2 + 2da*db*x + db^2 -2k*da*x -2k*db // + k^2 - r^2 = 0 // (1+da^2)*x^2 + 2(da*db-h-k*da)*x + h2 + db^2 -2k*db + k^2 - r^2 = 0 // and determine solutions for x using abc-formula // fill in x in original line equation to get y coordinate double da = -m_b/m_a; double db = -m_c/m_a; double dA = 1 + da*da; double dB = 2*( da*db - h - k*da ); double dC = h*h + db*db - 2*k*db + k*k - circle.getRadius()*circle.getRadius(); iSol = Geometry::abcFormula( dA, dB, dC, &dSol1, &dSol2 ); posSolution1->setVecPosition( dSol1, da*dSol1 + db ); posSolution2->setVecPosition( dSol2, da*dSol2 + db ); return iSol;}/*! This method returns the tangent line to a VecPosition. This is the line between the specified position and the closest point on the line to this position. \param pos VecPosition point with which tangent line is calculated. \return Line line tangent to this position */Line Line::getTangentLine( VecPosition pos ){ // ay + bx + c = 0 -> y = (-b/a)x + (-c/a) // tangent: y = (a/b)*x + C1 -> by - ax + C2 = 0 => C2 = ax - by // with pos.y = y, pos.x = x return Line( m_b, -m_a, m_a*pos.getX() - m_b*pos.getY() );}/*! This method returns the closest point on a line to a given position. \param pos point to which closest point should be determined \return VecPosition closest point on line to 'pos'. */VecPosition Line::getPointOnLineClosestTo( VecPosition pos ){ Line l2 = getTangentLine( pos ); // get tangent line return getIntersection( l2 ); // and intersection between the two lines}/*! This method returns the distance between a specified position and the closest point on the given line. \param pos position to which distance should be calculated \return double indicating the distance to the line. */double Line::getDistanceWithPoint( VecPosition pos ){ return pos.getDistanceTo( getPointOnLineClosestTo( pos ) );}/*! This method determines whether the projection of a point on the current line lies between two other points ('point1' and 'point2') that lie on the same line. \param pos point of which projection is checked. \param point1 first point on line \param point2 second point on line \return true when projection of 'pos' lies between 'point1' and 'point2'.*/bool Line::isInBetween( VecPosition pos, VecPosition point1, VecPosition point2){ pos = getPointOnLineClosestTo( pos ); // get closest point double dDist = point1.getDistanceTo( point2 ); // get distance between 2 pos // if the distance from both points to the projection is smaller than this // dist, the pos lies in between. return pos.getDistanceTo( point1 ) <= dDist && pos.getDistanceTo( point2 ) <= dDist;}/*! This method calculates the y coordinate given the x coordinate \param x coordinate \return y coordinate on this line */double Line::getYGivenX( double x ){ if( m_a == 0 ) { cerr << "(Line::getYGivenX) Cannot calculate Y coordinate: " ; show( cerr ); cerr << endl; return 0; } // ay + bx + c = 0 ==> ay = -(b*x + c)/a return -(m_b*x+m_c)/m_a;}/*! This method calculates the x coordinate given the x coordinate \param y coordinate \return x coordinate on this line */double Line::getXGivenY( double y ){ if( m_b == 0 ) { cerr << "(Line::getXGivenY) Cannot calculate X coordinate\n" ; return 0; } // ay + bx + c = 0 ==> bx = -(a*y + c)/a return -(m_a*y+m_c)/m_b;}/*! This method creates a line given two points. \param pos1 first point \param pos2 second point \return line that passes through the two specified points. */Line Line::makeLineFromTwoPoints( VecPosition pos1, VecPosition pos2 ){ // 1*y + bx + c = 0 => y = -bx - c // with -b the direction coefficient (or slope) // and c = - y - bx double dA=1.0, dB, dC; double dTemp = pos2.getX() - pos1.getX(); // determine the slope if( fabs(dTemp) < EPSILON ) { // ay + bx + c = 0 with vertical slope=> a = 0, b = 1 dA = 0.0; dB = 1.0; } else { // y = (-b)x -c with -b the slope of the line dA = 1.0; dB = -(pos2.getY() - pos1.getY())/dTemp; } // ay + bx + c = 0 ==> c = -a*y - b*x dC = - dA*pos2.getY() - dB * pos2.getX(); return Line( dA, dB, dC );}/*! This method creates a line given a position and an angle. \param vec position through which the line passes \param angle direction of the line. \return line that goes through position 'vec' with angle 'angle'. */Line Line::makeLineFromPositionAndAngle( VecPosition vec, AngDeg angle ){ // calculate point somewhat further in direction 'angle' and make // line from these two points. return makeLineFromTwoPoints( vec, vec+VecPosition(1,angle,POLAR));}/*! This method returns the a coefficient from the line ay + bx + c = 0. \return a coefficient of the line. */double Line::getACoefficient() const{ return m_a;}/*! This method returns the b coefficient from the line ay + bx + c = 0. \return b coefficient of the line. */double Line::getBCoefficient() const{ return m_b;}/*! This method returns the c coefficient from the line ay + bx + c = 0. \return c coefficient of the line. */double Line::getCCoefficient() const{ return m_c;}/******************************************************************************//********************** CLASS RECTANGLE ***************************************//******************************************************************************//*! This is the constructor of a Rectangle. Two points will be given. The order does not matter as long as two opposite points are given (left top and right bottom or right top and left bottom). \param pos first point that defines corner of rectangle \param pos2 second point that defines other corner of rectangle \return rectangle with 'pos' and 'pos2' as opposite corners. */Rectangle::Rectangle( VecPosition pos, VecPosition pos2 ){ setRectanglePoints( pos, pos2 );}/*! This method sets the upper left and right bottom point of the current rectangle. \param pos first point that defines corner of rectangle \param pos2 second point that defines other corner of rectangle */void Rectangle::setRectanglePoints( VecPosition pos1, VecPosition pos2 ){ m_posLeftTop.setX ( max( pos1.getX(), pos2.getX() ) ); m_posLeftTop.setY ( min( pos1.getY(), pos2.getY() ) ); m_posRightBottom.setX( min( pos1.getX(), pos2.getX() ) ); m_posRightBottom.setY( max( pos1.getY(), pos2.getY() ) );}/*! This method prints the rectangle to the specified output stream in the format rect( top_left_point, bottom_right_point ). \param os output stream to which rectangle is written. */void Rectangle::show( ostream& os ){ cout << "rect(" << m_posLeftTop << " " << m_posRightBottom << ")";}/*! This method determines whether the given position lies inside the current rectangle. \param pos position which is checked whether it lies in rectangle \return true when 'pos' lies in the rectangle, false otherwise */bool Rectangle::isInside( VecPosition pos ){ return pos.isBetweenX( m_posRightBottom.getX(), m_posLeftTop.getX() ) && pos.isBetweenY( m_posLeftTop.getY(), m_posRightBottom.getY() );}/*! This method sets the top left position of the rectangle \param pos new top left position of the rectangle \return true when update was successful */bool Rectangle::setPosLeftTop( VecPosition pos ){ m_posLeftTop = pos; return true;}/*! This method returns the top left position of the rectangle \return top left position of the rectangle */VecPosition Rectangle::getPosLeftTop( VecPosition pos ){ return m_posLeftTop;}/*! This method sets the right bottom position of the rectangle \param pos new right bottom position of the rectangle \return true when update was succesfull */bool Rectangle::setPosRightBottom( VecPosition pos ){ m_posRightBottom = pos; return true;}/*! This method returns the right bottom position of the rectangle \return top right bottom of the rectangle */VecPosition Rectangle::getPosRightBottom( VecPosition pos ){ return m_posRightBottom;}/******************************************************************************//********************** TESTING PURPOSES *************************************//******************************************************************************//*#include<iostream.h>int main( void ){ double dFirst = 1.0; double dRatio = 2.5; double dSum = 63.4375; double dLength = 4.0; printf( "sum: %f\n", Geometry::getSumGeomSeries( dFirst, dRatio, dLength)); printf( "length: %f\n", Geometry::getLengthGeomSeries( dFirst, dRatio, dSum));}int main( void ){ Line l1(1,-1,3 ); Line l2(1,-0.2,10 ); Line l3 = Line::makeLineFromTwoPoints( VecPosition(1,-1), VecPosition(2,-2) ); l3.show(); cout << endl; l1.show(); l2.show(); l1.getIntersection( l2 ).show();}int main( void ){ Line l( 1, -1, 0 ); VecPosition s1, s2; int i = l.getCircleIntersectionPoints( Circle( VecPosition(1,1),1) &s1, &s2 ); printf( "number of solutions: %d\n", i ); if( i == 2 ) { cout << s1 << " " << s2 ; } else if( i == 1 ) { cout << s1; } cout << "line: " << l;}int main( void ){ Circle c11( VecPosition( 10, 0 ), 10); Circle c12( VecPosition( 40, 3 ), 40 ); Circle c21( VecPosition( 0,0 ), 5); Circle c22( VecPosition( 3,0 ), 40 ); VecPosition p1, p2; cout << c11.getIntersectionArea( c21 ) << endl; cout << c12.getIntersectionArea( c21 ) << endl; cout << c22.getIntersectionArea( c11 ) << endl; cout << c12.getIntersectionArea( c22 ) << endl; return 0;}int main( void ){ cout << getBisectorTwoAngles( -155.3, 179.0 ) << endl; cout << getBisectorTwoAngles( -179.3, 179.0 ) << endl;}*/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -