Revert "Use less-sophisticated arc editing math."
This reverts commit 3b424d3868
. And fixes
issue with rouding causing arc errors
This commit is contained in:
parent
1eb6902b82
commit
b8dfcb34c4
|
@ -501,8 +501,10 @@ VECTOR2<T> VECTOR2<T>::operator*( const T& aFactor ) const
|
||||||
template <class T>
|
template <class T>
|
||||||
VECTOR2<T> VECTOR2<T>::operator/( const T& aFactor ) const
|
VECTOR2<T> VECTOR2<T>::operator/( const T& aFactor ) const
|
||||||
{
|
{
|
||||||
VECTOR2<T> vector( KiROUND( x / aFactor ), KiROUND( y / aFactor ) );
|
if( std::is_integral<T>::value )
|
||||||
return vector;
|
return VECTOR2<T>( KiROUND( x / aFactor ), KiROUND( y / aFactor ) );
|
||||||
|
else
|
||||||
|
return VECTOR2<T>( x / aFactor, y / aFactor );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -441,29 +441,6 @@ double PCB_SHAPE::GetArcAngleEnd() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PCB_SHAPE::SetArcGeometry( const wxPoint& aStart, const wxPoint& aMid, const wxPoint& aEnd )
|
|
||||||
{
|
|
||||||
SetArcStart( aStart );
|
|
||||||
SetArcEnd( aEnd );
|
|
||||||
|
|
||||||
// Sadly we currently store center and angle rather than mid. So we have to calculate
|
|
||||||
// those.
|
|
||||||
wxPoint center = GetArcCenter( aStart, aMid, aEnd );
|
|
||||||
VECTOR2D startLine = aStart - center;
|
|
||||||
VECTOR2D endLine = aEnd - center;
|
|
||||||
bool clockwise = GetAngle() > 0;
|
|
||||||
double angle = RAD2DECIDEG( endLine.Angle() - startLine.Angle() );
|
|
||||||
|
|
||||||
if( clockwise && angle < 0.0 )
|
|
||||||
angle += 3600.0;
|
|
||||||
else if( !clockwise && angle > 0.0 )
|
|
||||||
angle -= 3600.0;
|
|
||||||
|
|
||||||
SetAngle( angle, false );
|
|
||||||
SetCenter( center );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PCB_SHAPE::SetAngle( double aAngle, bool aUpdateEnd )
|
void PCB_SHAPE::SetAngle( double aAngle, bool aUpdateEnd )
|
||||||
{
|
{
|
||||||
// m_Angle must be >= -360 and <= +360 degrees
|
// m_Angle must be >= -360 and <= +360 degrees
|
||||||
|
|
|
@ -227,14 +227,6 @@ public:
|
||||||
*/
|
*/
|
||||||
void SetCenter( const wxPoint& aCenterPoint ) { m_start = aCenterPoint; }
|
void SetCenter( const wxPoint& aCenterPoint ) { m_start = aCenterPoint; }
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the three controlling points for an arc.
|
|
||||||
*
|
|
||||||
* NB: these are NOT what's currently stored, so we have to do some calculations behind
|
|
||||||
* the scenes. However, they are what SHOULD be stored.
|
|
||||||
*/
|
|
||||||
void SetArcGeometry( const wxPoint& aStart, const wxPoint& aMid, const wxPoint& aEnd );
|
|
||||||
|
|
||||||
const wxPoint GetFocusPosition() const override
|
const wxPoint GetFocusPosition() const override
|
||||||
{
|
{
|
||||||
return GetCenter();
|
return GetCenter();
|
||||||
|
|
|
@ -24,7 +24,9 @@
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
using namespace std::placeholders;
|
using namespace std::placeholders;
|
||||||
|
#include <advanced_config.h>
|
||||||
#include <tool/tool_manager.h>
|
#include <tool/tool_manager.h>
|
||||||
#include <view/view_controls.h>
|
#include <view/view_controls.h>
|
||||||
#include <geometry/seg.h>
|
#include <geometry/seg.h>
|
||||||
|
@ -207,10 +209,16 @@ std::shared_ptr<EDIT_POINTS> PCB_POINT_EDITOR::makePoints( EDA_ITEM* aItem )
|
||||||
points->AddPoint( shape->GetArcMid() );
|
points->AddPoint( shape->GetArcMid() );
|
||||||
points->AddPoint( shape->GetArcEnd() );
|
points->AddPoint( shape->GetArcEnd() );
|
||||||
|
|
||||||
|
// Set constraints
|
||||||
|
// Arc end has to stay at the same radius as the start
|
||||||
|
points->Point( ARC_END ).SetConstraint( new EC_CIRCLE( points->Point( ARC_END ),
|
||||||
|
points->Point( ARC_CENTER ),
|
||||||
|
points->Point( ARC_START ) ) );
|
||||||
|
|
||||||
|
points->Point( ARC_MID ).SetConstraint( new EC_LINE( points->Point( ARC_MID ),
|
||||||
|
points->Point( ARC_CENTER ) ) );
|
||||||
|
|
||||||
points->Point( ARC_MID ).SetGridConstraint( IGNORE_GRID );
|
points->Point( ARC_MID ).SetGridConstraint( IGNORE_GRID );
|
||||||
points->Point( ARC_START ).SetGridConstraint( SNAP_TO_GRID );
|
|
||||||
points->Point( ARC_CENTER ).SetGridConstraint( SNAP_BY_GRID );
|
|
||||||
points->Point( ARC_END ).SetGridConstraint( SNAP_TO_GRID );
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case S_CIRCLE:
|
case S_CIRCLE:
|
||||||
|
@ -587,6 +595,172 @@ int PCB_POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PCB_POINT_EDITOR::editArcEndpointKeepTangent( PCB_SHAPE* aArc, VECTOR2I aCenter, VECTOR2I aStart,
|
||||||
|
VECTOR2I aMid, VECTOR2I aEnd,
|
||||||
|
const VECTOR2I aCursor ) const
|
||||||
|
{
|
||||||
|
VECTOR2D startLine = aStart - aCenter;
|
||||||
|
VECTOR2D endLine = aEnd - aCenter;
|
||||||
|
double newAngle = RAD2DECIDEG( endLine.Angle() - startLine.Angle() );
|
||||||
|
|
||||||
|
bool clockwise;
|
||||||
|
bool movingStart;
|
||||||
|
bool arcValid = true;
|
||||||
|
|
||||||
|
VECTOR2I *p1, *p2, *p3;
|
||||||
|
// p1 does not move, p2 does.
|
||||||
|
|
||||||
|
if( aStart != aArc->GetArcStart() )
|
||||||
|
{
|
||||||
|
aStart = aCursor;
|
||||||
|
p1 = &aEnd;
|
||||||
|
p2 = &aStart;
|
||||||
|
p3 = &aMid;
|
||||||
|
movingStart = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
aEnd = aCursor;
|
||||||
|
p1 = &aStart;
|
||||||
|
p2 = &aEnd;
|
||||||
|
p3 = &aMid;
|
||||||
|
movingStart = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
VECTOR2D v1, v2, v3, v4;
|
||||||
|
|
||||||
|
// Move the coordinate system
|
||||||
|
v1 = *p1 - aCenter;
|
||||||
|
v2 = *p2 - aCenter;
|
||||||
|
v3 = *p3 - aCenter;
|
||||||
|
|
||||||
|
VECTOR2D u1, u2, u3;
|
||||||
|
|
||||||
|
// A point cannot be both the center and on the arc.
|
||||||
|
if( ( v1.EuclideanNorm() == 0 ) || ( v2.EuclideanNorm() == 0 ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
u1 = v1 / v1.EuclideanNorm();
|
||||||
|
u2 = v3 - ( u1.x * v3.x + u1.y * v3.y ) * u1;
|
||||||
|
u2 = u2 / u2.EuclideanNorm();
|
||||||
|
|
||||||
|
// [ u1, u3 ] is a base centered on the circle with:
|
||||||
|
// u1 : unit vector toward the point that does not move
|
||||||
|
// u2 : unit vector toward the mid point.
|
||||||
|
|
||||||
|
// Get vectors v1, and v2 in that coordinate system.
|
||||||
|
|
||||||
|
double det = u1.x * u2.y - u2.x * u1.y;
|
||||||
|
|
||||||
|
// u1 and u2 are unit vectors, and perpendicular.
|
||||||
|
// det should not be 0. In case it is, do not change the arc.
|
||||||
|
if( det == 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
double tmpx = v1.x * u2.y - v1.y * u2.x;
|
||||||
|
double tmpy = -v1.x * u1.y + v1.y * u1.x;
|
||||||
|
v1.x = tmpx;
|
||||||
|
v1.y = tmpy;
|
||||||
|
v1 = v1 / det;
|
||||||
|
|
||||||
|
tmpx = v2.x * u2.y - v2.y * u2.x;
|
||||||
|
tmpy = -v2.x * u1.y + v2.y * u1.x;
|
||||||
|
v2.x = tmpx;
|
||||||
|
v2.y = tmpy;
|
||||||
|
v2 = v2 / det;
|
||||||
|
|
||||||
|
double R = v1.EuclideanNorm();
|
||||||
|
bool transformCircle = false;
|
||||||
|
|
||||||
|
/* p2
|
||||||
|
* X***
|
||||||
|
* ** <---- This is the arc
|
||||||
|
* y ^ **
|
||||||
|
* | R *
|
||||||
|
* | <-----------> *
|
||||||
|
* x------x------>--------x p1
|
||||||
|
* C' <----> C x
|
||||||
|
* delta
|
||||||
|
*
|
||||||
|
* p1 does not move, and the tangent at p1 remains the same.
|
||||||
|
* => The new center, C', will be on the C-p1 axis.
|
||||||
|
* p2 moves
|
||||||
|
*
|
||||||
|
* The radius of the new circle is delta + R
|
||||||
|
*
|
||||||
|
* || C' p2 || = || C' P1 ||
|
||||||
|
* is the same as :
|
||||||
|
* ( delta + p2.x ) ^ 2 + p2.y ^ 2 = ( R + delta ) ^ 2
|
||||||
|
*
|
||||||
|
* delta = ( R^2 - p2.x ^ 2 - p2.y ^2 ) / ( 2 * p2.x - 2 * R )
|
||||||
|
*
|
||||||
|
* We can use this equation for any point p2 with p2.x < R
|
||||||
|
*/
|
||||||
|
|
||||||
|
if( v2.x == R )
|
||||||
|
{
|
||||||
|
// Straight line, do nothing
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( v2.x > R )
|
||||||
|
{
|
||||||
|
// If we need to invert the curvature.
|
||||||
|
// We modify the input so we can use the same equation
|
||||||
|
transformCircle = true;
|
||||||
|
v2.x = 2 * R - v2.x;
|
||||||
|
}
|
||||||
|
// We can keep the tangent constraint.
|
||||||
|
double delta = ( R * R - v2.x * v2.x - v2.y * v2.y ) / ( 2 * v2.x - 2 * R );
|
||||||
|
|
||||||
|
// This is just to limit the radius, so nothing overflows later when drawing.
|
||||||
|
if( abs( v2.y / ( R - v2.x ) ) > ADVANCED_CFG::GetCfg().m_DrawArcCenterMaxAngle )
|
||||||
|
{
|
||||||
|
arcValid = false;
|
||||||
|
}
|
||||||
|
// Never recorded a problem, but still checking.
|
||||||
|
if( !std::isfinite( delta ) )
|
||||||
|
{
|
||||||
|
arcValid = false;
|
||||||
|
}
|
||||||
|
// v4 is the new center
|
||||||
|
v4 = ( !transformCircle ) ? VECTOR2D( -delta, 0 ) : VECTOR2D( 2 * R + delta, 0 );
|
||||||
|
|
||||||
|
clockwise = aArc->GetAngle() > 0;
|
||||||
|
|
||||||
|
if( transformCircle )
|
||||||
|
clockwise = !clockwise;
|
||||||
|
|
||||||
|
tmpx = v4.x * u1.x + v4.y * u2.x;
|
||||||
|
tmpy = v4.x * u1.y + v4.y * u2.y;
|
||||||
|
v4.x = tmpx;
|
||||||
|
v4.y = tmpy;
|
||||||
|
|
||||||
|
aCenter = v4 + aCenter;
|
||||||
|
|
||||||
|
startLine = aStart - aCenter;
|
||||||
|
endLine = aEnd - aCenter;
|
||||||
|
newAngle = RAD2DECIDEG( endLine.Angle() - startLine.Angle() );
|
||||||
|
|
||||||
|
if( clockwise && newAngle < 0.0 )
|
||||||
|
newAngle += 3600.0;
|
||||||
|
else if( !clockwise && newAngle > 0.0 )
|
||||||
|
newAngle -= 3600.0;
|
||||||
|
|
||||||
|
if( arcValid )
|
||||||
|
{
|
||||||
|
aArc->SetAngle( newAngle, false );
|
||||||
|
aArc->SetCenter( wxPoint( aCenter.x, aCenter.y ) );
|
||||||
|
|
||||||
|
if( movingStart )
|
||||||
|
aArc->SetArcStart( wxPoint( aStart.x, aStart.y ) );
|
||||||
|
else
|
||||||
|
aArc->SetArcEnd( wxPoint( aEnd.x, aEnd.y ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the coordinates of 4 corners of a rectangle, according to pad constraints and the
|
* Update the coordinates of 4 corners of a rectangle, according to pad constraints and the
|
||||||
* moved corner
|
* moved corner
|
||||||
|
@ -689,25 +863,9 @@ static void pinEditedCorner( int aEditedPointIndex, int aMinWidth, int aMinHeigh
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PCB_POINT_EDITOR::editArcEndpointKeepShape( PCB_SHAPE* aArc, VECTOR2I aStart, VECTOR2I aMid,
|
void PCB_POINT_EDITOR::editArcEndpointKeepCenter( PCB_SHAPE* aArc, VECTOR2I aCenter, VECTOR2I aStart,
|
||||||
VECTOR2I aEnd, const VECTOR2I aCursor ) const
|
VECTOR2I aMid, VECTOR2I aEnd,
|
||||||
{
|
const VECTOR2I aCursor ) const
|
||||||
VECTOR2I diff;
|
|
||||||
|
|
||||||
if( aStart != aArc->GetArcStart() )
|
|
||||||
diff = aStart - aArc->GetArcStart();
|
|
||||||
else
|
|
||||||
diff = aEnd - aArc->GetArcEnd();
|
|
||||||
|
|
||||||
aMid = VECTOR2I( aArc->GetArcMid() ) + diff / 2;
|
|
||||||
|
|
||||||
aArc->SetArcGeometry( (wxPoint) aStart, (wxPoint) aMid, (wxPoint) aEnd );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PCB_POINT_EDITOR::editArcEndpointKeepCenter( PCB_SHAPE* aArc, VECTOR2I aCenter,
|
|
||||||
VECTOR2I aStart, VECTOR2I aMid, VECTOR2I aEnd,
|
|
||||||
const VECTOR2I aCursor ) const
|
|
||||||
{
|
{
|
||||||
bool clockwise;
|
bool clockwise;
|
||||||
bool movingStart;
|
bool movingStart;
|
||||||
|
@ -841,20 +999,82 @@ void PCB_POINT_EDITOR::editArcMidKeepCenter( PCB_SHAPE* aArc, VECTOR2I aCenter,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PCB_POINT_EDITOR::editArcMidKeepEndpoints( PCB_SHAPE* aArc, VECTOR2I aStart, VECTOR2I aEnd,
|
void PCB_POINT_EDITOR::editArcMidKeepEnpoints( PCB_SHAPE* aArc, VECTOR2I aCenter, VECTOR2I aStart,
|
||||||
const VECTOR2I aCursor ) const
|
VECTOR2I aMid, VECTOR2I aEnd, const VECTOR2I aCursor ) const
|
||||||
{
|
{
|
||||||
// Let 'm' be the middle point of the chord between the start and end points
|
bool clockwise;
|
||||||
VECTOR2I m = ( aStart + aEnd ) / 2;
|
VECTOR2I oldCenter = aArc->GetCenter();
|
||||||
|
|
||||||
// Legal midpoints lie on a vector starting just off the chord midpoint and extending out
|
|
||||||
// past the existing midpoint. We do not allow arc inflection while point editing.
|
|
||||||
const int JUST_OFF = ( aStart - aEnd ).EuclideanNorm() / 100;
|
|
||||||
VECTOR2I v = (VECTOR2I) aArc->GetArcMid() - m;
|
|
||||||
SEG legal( m + v.Resize( JUST_OFF ), m + v.Resize( INT_MAX / 2 ) );
|
|
||||||
VECTOR2I mid = legal.NearestPoint( aCursor );
|
|
||||||
|
|
||||||
aArc->SetArcGeometry( (wxPoint) aStart, (wxPoint) mid, (wxPoint) aEnd );
|
// This allows the user to go on the sides of the arc
|
||||||
|
aMid = aCursor;
|
||||||
|
// Find the new center
|
||||||
|
aCenter = GetArcCenter( aStart, aMid, aEnd );
|
||||||
|
|
||||||
|
aArc->SetCenter( (wxPoint) aCenter );
|
||||||
|
|
||||||
|
// Check if the new arc is CW or CCW
|
||||||
|
VECTOR2D startLine = aStart - aCenter;
|
||||||
|
VECTOR2D endLine = aEnd - aCenter;
|
||||||
|
double newAngle = RAD2DECIDEG( endLine.Angle() - startLine.Angle() );
|
||||||
|
VECTOR2D v1, v2;
|
||||||
|
|
||||||
|
v1 = aStart - aMid;
|
||||||
|
v2 = aEnd - aMid;
|
||||||
|
double theta = RAD2DECIDEG( v1.Angle() );
|
||||||
|
RotatePoint( &( v1.x ), &( v1.y ), theta );
|
||||||
|
RotatePoint( &( v2.x ), &( v2.y ), theta );
|
||||||
|
clockwise = ( ( v1.Angle() - v2.Angle() ) > 0 );
|
||||||
|
|
||||||
|
// Normalize the angle
|
||||||
|
if( clockwise && newAngle < 0.0 )
|
||||||
|
newAngle += 3600.0;
|
||||||
|
else if( !clockwise && newAngle > 0.0 )
|
||||||
|
newAngle -= 3600.0;
|
||||||
|
|
||||||
|
// Accuracy test
|
||||||
|
// First, get the angle
|
||||||
|
VECTOR2I endTest = aStart;
|
||||||
|
RotatePoint( &( endTest.x ), &( endTest.y ), aCenter.x, aCenter.y, -newAngle );
|
||||||
|
double distance = ( endTest - aEnd ).SquaredEuclideanNorm();
|
||||||
|
|
||||||
|
if( distance > ADVANCED_CFG::GetCfg().m_DrawArcAccuracy )
|
||||||
|
{
|
||||||
|
// Cancel Everything
|
||||||
|
// If the accuracy is low, we can't draw precisely the arc.
|
||||||
|
// It may happen when the radius is *high*
|
||||||
|
aArc->SetCenter( (wxPoint) oldCenter );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
aArc->SetAngle( newAngle, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now, update the edit point position
|
||||||
|
// Express the point in a cercle-centered coordinate system.
|
||||||
|
aMid = aCursor - aCenter;
|
||||||
|
|
||||||
|
double sqRadius = ( aEnd - aCenter ).SquaredEuclideanNorm();
|
||||||
|
|
||||||
|
// Special case, because the tangent would lead to +/- infinity
|
||||||
|
if( aMid.x == 0 )
|
||||||
|
{
|
||||||
|
aMid.y = aMid.y > 0 ? sqrt( sqRadius ) : -sqrt( sqRadius );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Circle : x^2 + y^2 = R ^ 2
|
||||||
|
// In this coordinate system, the angular position of the cursor is (r, theta)
|
||||||
|
// The line coming from the center of the circle is y = start.y / start.x * x
|
||||||
|
// The intersection fulfills : x^2 = R^2 / ( 1 + ( start.y / start.x ) ^ 2 )
|
||||||
|
|
||||||
|
double tan = aMid.y / static_cast<double>( aMid.x );
|
||||||
|
double tmp = sqrt( sqRadius / ( 1.0 + tan * tan ) );
|
||||||
|
// Move to the correct quadrant
|
||||||
|
tmp = aMid.x > 0 ? tmp : -tmp;
|
||||||
|
aMid.y = aMid.y / static_cast<double>( aMid.x ) * tmp;
|
||||||
|
aMid.x = tmp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -949,7 +1169,7 @@ void PCB_POINT_EDITOR::updateItem() const
|
||||||
if( m_altEditMethod )
|
if( m_altEditMethod )
|
||||||
editArcMidKeepCenter( shape, center, start, mid, end, cursorPos );
|
editArcMidKeepCenter( shape, center, start, mid, end, cursorPos );
|
||||||
else
|
else
|
||||||
editArcMidKeepEndpoints( shape, start, end, cursorPos );
|
editArcMidKeepEnpoints( shape, center, start, mid, end, cursorPos );
|
||||||
}
|
}
|
||||||
else if( isModified( m_editPoints->Point( ARC_START ) )
|
else if( isModified( m_editPoints->Point( ARC_START ) )
|
||||||
|| isModified( m_editPoints->Point( ARC_END ) ) )
|
|| isModified( m_editPoints->Point( ARC_END ) ) )
|
||||||
|
@ -959,7 +1179,7 @@ void PCB_POINT_EDITOR::updateItem() const
|
||||||
if( m_altEditMethod )
|
if( m_altEditMethod )
|
||||||
editArcEndpointKeepCenter( shape, center, start, mid, end, cursorPos );
|
editArcEndpointKeepCenter( shape, center, start, mid, end, cursorPos );
|
||||||
else
|
else
|
||||||
editArcEndpointKeepShape( shape, start, mid, end, cursorPos );
|
editArcEndpointKeepTangent( shape, center, start, mid, end, cursorPos );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -131,26 +131,26 @@ private:
|
||||||
int removeCorner( const TOOL_EVENT& aEvent );
|
int removeCorner( const TOOL_EVENT& aEvent );
|
||||||
int modifiedSelection( const TOOL_EVENT& aEvent );
|
int modifiedSelection( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
/**
|
/** Move an end point of the arc, while keeping the tangent at the other endpoint.
|
||||||
* Move an end point of the arc, while keeping the same subtended angle.
|
*
|
||||||
*/
|
*/
|
||||||
void editArcEndpointKeepShape( PCB_SHAPE* aArc, VECTOR2I aStart, VECTOR2I aMid, VECTOR2I aEnd,
|
void editArcEndpointKeepTangent( PCB_SHAPE* aArc, VECTOR2I aCenter, VECTOR2I aStart,
|
||||||
const VECTOR2I aCursor ) const;
|
VECTOR2I aMid, VECTOR2I aEnd, const VECTOR2I aCursor ) const;
|
||||||
|
|
||||||
/**
|
/** Move an end point of the arc, while keeping radius, and the other point position.
|
||||||
* Move an end point of the arc around the circumference.
|
*
|
||||||
*/
|
*/
|
||||||
void editArcEndpointKeepCenter( PCB_SHAPE* aArc, VECTOR2I aCenter, VECTOR2I aStart,
|
void editArcEndpointKeepCenter( PCB_SHAPE* aArc, VECTOR2I aCenter, VECTOR2I aStart,
|
||||||
VECTOR2I aMid, VECTOR2I aEnd, const VECTOR2I aCursor ) const;
|
VECTOR2I aMid, VECTOR2I aEnd, const VECTOR2I aCursor ) const;
|
||||||
|
|
||||||
/**
|
/** Move the mid point of the arc, while keeping the two endpoints.
|
||||||
* Move the mid point of the arc, while keeping the two endpoints.
|
*
|
||||||
*/
|
*/
|
||||||
void editArcMidKeepEndpoints( PCB_SHAPE* aArc, VECTOR2I aStart, VECTOR2I aEnd,
|
void editArcMidKeepEnpoints( PCB_SHAPE* aArc, VECTOR2I aCenter, VECTOR2I aStart,
|
||||||
const VECTOR2I aCursor ) const;
|
VECTOR2I aMid, VECTOR2I aEnd, const VECTOR2I aCursor ) const;
|
||||||
|
|
||||||
/**
|
/** Move the mid point of the arc, while keeping the angle.
|
||||||
* Move the mid point of the arc, while keeping the angle.
|
*
|
||||||
*/
|
*/
|
||||||
void editArcMidKeepCenter( PCB_SHAPE* aArc, VECTOR2I aCenter, VECTOR2I aStart, VECTOR2I aMid,
|
void editArcMidKeepCenter( PCB_SHAPE* aArc, VECTOR2I aCenter, VECTOR2I aStart, VECTOR2I aMid,
|
||||||
VECTOR2I aEnd, const VECTOR2I aCursor ) const;
|
VECTOR2I aEnd, const VECTOR2I aCursor ) const;
|
||||||
|
|
Loading…
Reference in New Issue