Clarify CIRCLE::ConstructFromTanTanPt

Remove unused bool aAlternateSolution and add doxygen comments
This commit is contained in:
Roberto Fernandez Bautista 2021-01-11 21:06:00 +00:00 committed by Jon Evans
parent 48823c0723
commit 99d203feae
4 changed files with 21 additions and 96 deletions

View File

@ -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()

View File

@ -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
@ -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 )
// 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
Center = furthestFromIntersect( possibleCenters.front(), possibleCenters.back() );
}
else
{
@ -133,9 +131,6 @@ CIRCLE& CIRCLE::ConstructFromTanTanPt( const SEG& aLineA, const SEG& aLineB, con
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 );
@ -146,12 +141,9 @@ CIRCLE& CIRCLE::ConstructFromTanTanPt( const SEG& aLineA, const SEG& aLineB, con
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 );

View File

@ -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 )

View File

@ -617,7 +617,6 @@ BOOST_AUTO_TEST_CASE( SegSegPerpendicular )
}
/**
* Struct to hold cases for operations with a #SEG, and a #VECTOR2I
*/