Clarify CIRCLE::ConstructFromTanTanPt
Remove unused bool aAlternateSolution and add doxygen comments
This commit is contained in:
parent
48823c0723
commit
99d203feae
|
@ -43,23 +43,20 @@ public:
|
|||
CIRCLE( const CIRCLE& aOther );
|
||||
|
||||
/**
|
||||
* Constructs this circle such that it is tangent to the given lines and passes through the
|
||||
* given point. There are two possible solutions, controlled by aAlternateSolution.
|
||||
* Constructs this circle such that it is tangent to the given segmetns and passes through the
|
||||
* given point, generating the solution which can be used to fillet both segments.
|
||||
*
|
||||
* When aAlternateSolution is false, find the best solution that can be used to fillet both
|
||||
* lines (i.e. choose the most likely quadrant and find the solution with smallest arc angle
|
||||
* between the tangent points on the lines)
|
||||
* The caller is responsible for ensuring it is providing a solvable problem. This function will
|
||||
* assert if this is not the case.
|
||||
*
|
||||
* @param aLineA is the first tangent line. Treated as an infinite line except for the purpose
|
||||
* of selecting the solution to return.
|
||||
* @param aLineB is the second tangent line. Treated as an infinite line except for the purpose
|
||||
* of selecting the solution to return.
|
||||
* @param aP is the point to pass through
|
||||
* @param aAlternateSolution If true, returns the other solution.
|
||||
* @return *this
|
||||
*/
|
||||
CIRCLE& ConstructFromTanTanPt( const SEG& aLineA, const SEG& aLineB, const VECTOR2I& aP,
|
||||
bool aAlternateSolution = false );
|
||||
CIRCLE& ConstructFromTanTanPt( const SEG& aLineA, const SEG& aLineB, const VECTOR2I& aP );
|
||||
|
||||
/**
|
||||
* Function NearestPoint()
|
||||
|
|
|
@ -48,8 +48,7 @@ CIRCLE::CIRCLE( const CIRCLE& aOther )
|
|||
}
|
||||
|
||||
|
||||
CIRCLE& CIRCLE::ConstructFromTanTanPt( const SEG& aLineA, const SEG& aLineB, const VECTOR2I& aP,
|
||||
bool aAlternateSolution )
|
||||
CIRCLE& CIRCLE::ConstructFromTanTanPt( const SEG& aLineA, const SEG& aLineB, const VECTOR2I& aP )
|
||||
{
|
||||
//fixme: There might be more efficient / accurate solution than using geometrical constructs
|
||||
|
||||
|
@ -91,7 +90,7 @@ CIRCLE& CIRCLE::ConstructFromTanTanPt( const SEG& aLineA, const SEG& aLineB, con
|
|||
// The radius will be half the distance between the two lines
|
||||
// The possible centers can be found by intersection
|
||||
|
||||
SEG perpendicularAtoB( aLineA.A, aLineB.LineProject( aLineA.A ) );
|
||||
SEG perpendicularAtoB( aLineA.A, aLineB.LineProject( aLineA.A ) );
|
||||
VECTOR2I midPt = perpendicularAtoB.Center();
|
||||
Radius = ( midPt - aLineA.A ).EuclideanNorm();
|
||||
|
||||
|
@ -103,10 +102,9 @@ CIRCLE& CIRCLE::ConstructFromTanTanPt( const SEG& aLineA, const SEG& aLineB, con
|
|||
wxCHECK_MSG( possibleCenters.size() > 0, *this, "No solutions exist!" );
|
||||
intersectPoint = aLineA.A; // just for the purpose of deciding which solution to return
|
||||
|
||||
if( aAlternateSolution )
|
||||
Center = closestToIntersect( possibleCenters.front(), possibleCenters.back() );
|
||||
else
|
||||
Center = furthestFromIntersect( possibleCenters.front(), possibleCenters.back() );
|
||||
// For the special case of the two segments being parallel, we will return the solution
|
||||
// whose center is closest to aLineA.A
|
||||
Center = closestToIntersect( possibleCenters.front(), possibleCenters.back() );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -126,32 +124,26 @@ CIRCLE& CIRCLE::ConstructFromTanTanPt( const SEG& aLineA, const SEG& aLineB, con
|
|||
}
|
||||
|
||||
// Calculate bisector
|
||||
VECTOR2I lineApt = furthestFromIntersect( aLineA.A, aLineA.B );
|
||||
VECTOR2I lineBpt = furthestFromIntersect( aLineB.A, aLineB.B );
|
||||
VECTOR2I bisectorPt = GetArcMid( lineApt, lineBpt, intersectPoint, true );
|
||||
VECTOR2I lineApt = furthestFromIntersect( aLineA.A, aLineA.B );
|
||||
VECTOR2I lineBpt = furthestFromIntersect( aLineB.A, aLineB.B );
|
||||
VECTOR2I bisectorPt = GetArcMid( lineApt, lineBpt, intersectPoint, true );
|
||||
|
||||
anglebisector.A = intersectPoint;
|
||||
anglebisector.B = bisectorPt;
|
||||
|
||||
if( aAlternateSolution && ( aLineA.Contains( aP ) || aLineB.Contains( aP ) ) )
|
||||
anglebisector = anglebisector.PerpendicularSeg( intersectPoint );
|
||||
|
||||
// Create an arbitrary circle that is tangent to both lines
|
||||
CIRCLE hSolution;
|
||||
hSolution.Center = anglebisector.LineProject( aP );
|
||||
hSolution.Radius = aLineA.LineDistance( hSolution.Center );
|
||||
|
||||
// Find the homothetic image of aP in the construction circle (hSolution)
|
||||
SEG throughaP( intersectPoint, aP );
|
||||
SEG throughaP( intersectPoint, aP );
|
||||
std::vector<VECTOR2I> hProjections = hSolution.Intersect( throughaP );
|
||||
wxCHECK_MSG( hProjections.size() > 0, *this, "No solutions exist!" );
|
||||
|
||||
VECTOR2I hSelected;
|
||||
|
||||
if( aAlternateSolution )
|
||||
hSelected = furthestFromIntersect( hProjections.front(), hProjections.back() );
|
||||
else
|
||||
hSelected = closestToIntersect( hProjections.front(), hProjections.back() );
|
||||
// We want to create a fillet, so the projection of homothetic projection of aP
|
||||
// should be the one closest to the intersection
|
||||
VECTOR2I hSelected = closestToIntersect( hProjections.front(), hProjections.back() );
|
||||
|
||||
VECTOR2I hTanLineA = aLineA.LineProject( hSolution.Center );
|
||||
VECTOR2I hTanLineB = aLineB.LineProject( hSolution.Center );
|
||||
|
@ -160,7 +152,7 @@ CIRCLE& CIRCLE::ConstructFromTanTanPt( const SEG& aLineA, const SEG& aLineB, con
|
|||
if( ( hTanLineA - aP ).EuclideanNorm() > ( hTanLineB - aP ).EuclideanNorm() )
|
||||
{
|
||||
// Find the tangent at line A by homothetic inversion
|
||||
SEG hT( hTanLineA, hSelected );
|
||||
SEG hT( hTanLineA, hSelected );
|
||||
OPT_VECTOR2I actTanA = hT.ParallelSeg( aP ).IntersectLines( aLineA );
|
||||
wxCHECK_MSG( actTanA, *this, "No solutions exist!" );
|
||||
|
||||
|
|
|
@ -399,74 +399,11 @@ int EDIT_TOOL::DragArcTrack( const TOOL_EVENT& aEvent )
|
|||
|
||||
// Constrain cursor
|
||||
// Fix-me: this is a bit ugly but it works
|
||||
if( tanStartSide != tanStart.Side( m_cursor ) )
|
||||
if( tanStartSide != tanStart.Side( m_cursor )
|
||||
|| tanEndSide != tanEnd.Side( m_cursor )
|
||||
|| constraintSegSide != constraintSeg.Side( m_cursor ) )
|
||||
{
|
||||
VECTOR2I projected = tanStart.LineProject( m_cursor );
|
||||
|
||||
if( tanEndSide != tanEnd.Side( projected ) )
|
||||
{
|
||||
m_cursor = tanEnd.LineProject( m_cursor );
|
||||
|
||||
if( tanStartSide != tanStart.Side( m_cursor ) )
|
||||
m_cursor = optInterectTan.get();
|
||||
}
|
||||
else if( constraintSegSide != constraintSeg.Side( projected ) )
|
||||
{
|
||||
m_cursor = constraintSeg.LineProject( m_cursor );
|
||||
|
||||
if( tanStartSide != tanStart.Side( m_cursor ) )
|
||||
m_cursor = maxTanPtStart;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cursor = projected;
|
||||
}
|
||||
}
|
||||
else if( tanEndSide != tanEnd.Side( m_cursor ) )
|
||||
{
|
||||
VECTOR2I projected = tanEnd.LineProject( m_cursor );
|
||||
|
||||
if( tanStartSide != tanStart.Side( projected ) )
|
||||
{
|
||||
m_cursor = tanStart.LineProject( m_cursor );
|
||||
|
||||
if( tanEndSide != tanEnd.Side( m_cursor ) )
|
||||
m_cursor = optInterectTan.get();
|
||||
}
|
||||
else if( constraintSegSide != constraintSeg.Side( projected ) )
|
||||
{
|
||||
m_cursor = constraintSeg.LineProject( m_cursor );
|
||||
|
||||
if( tanEndSide != tanEnd.Side( m_cursor ) )
|
||||
m_cursor = maxTanPtEnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cursor = projected;
|
||||
}
|
||||
}
|
||||
else if( constraintSegSide != constraintSeg.Side( m_cursor ) )
|
||||
{
|
||||
VECTOR2I projected = constraintSeg.LineProject( m_cursor );
|
||||
|
||||
if( tanStartSide != tanStart.Side( projected ) )
|
||||
{
|
||||
m_cursor = tanStart.LineProject( m_cursor );
|
||||
|
||||
if( constraintSegSide != constraintSeg.Side( m_cursor ) )
|
||||
m_cursor = maxTanPtStart;
|
||||
}
|
||||
else if( tanEndSide != tanEnd.Side( projected ) )
|
||||
{
|
||||
m_cursor = tanEnd.LineProject( m_cursor );
|
||||
|
||||
if( constraintSegSide != constraintSeg.Side( m_cursor ) )
|
||||
m_cursor = maxTanPtEnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cursor = projected;
|
||||
}
|
||||
}
|
||||
|
||||
if( ( m_cursor - maxTangentCircle.Center ).EuclideanNorm() < maxTangentCircle.Radius )
|
||||
|
|
|
@ -617,7 +617,6 @@ BOOST_AUTO_TEST_CASE( SegSegPerpendicular )
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Struct to hold cases for operations with a #SEG, and a #VECTOR2I
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue