mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-04-20 23:11:41 +00:00
Angle and distances cleanup (preparing for angles in doubles)
- Removed spurious int casts (these are truncated anyway and will break doubles) - Applied the Distance, GetLineLength, EuclideanNorm, DEG2RAD, RAD2DEG ArcTangente and NORMALIZE* functions where possible - ArcTangente now returns double and handles the 0,0 case like atan2, so it's no longer necessary to check for it before calling - Small functions in trigo moved as inline
This commit is contained in:
parent
000ec33af2
commit
0e903dba5b
3d-viewer
common
class_plotter.cppcommon_plotGERBER_functions.cppconvert_basic_shapes_to_polygon.cppgr_basic.cpppcbcommon.cpptrigo.cpp
eeschema
gerbview
include
pcbnew
autorouter
basepcbframe.cppboard_items_to_polygon_shape_transform.cppclass_dimension.cppclass_drawsegment.cppclass_drawsegment.hclass_edge_mod.cppclass_module.cppclass_pad.cppclass_pad_draw_functions.cppclass_pcb_text.cppclass_text_mod.cppclass_track.cppclass_track.hconnect.cppdialogs
dimension.cppdragsegm.cppdrc_clearance_test_functions.cppdrc_marker_functions.cppedgemod.cppexport_gencad.cppexport_vrml.cppgen_modules_placefile.cppgpcb_plugin.cppmagnetic_tracks_functions.cppmuonde.cpppcad2kicadpcb_plugin
plot_brditems_plotter.cppscripting
specctra_export.cppzones_convert_brd_items_to_polygons_with_Boost.cpppolygon
@ -60,15 +60,15 @@ void S3D_MASTER::Set_Object_Coords( std::vector< S3D_VERTEX >& aVertices )
|
||||
aVertices[ii].y *= m_MatScale.y;
|
||||
aVertices[ii].z *= m_MatScale.z;
|
||||
|
||||
/* adjust rotation */
|
||||
// adjust rotation
|
||||
if( m_MatRotation.x )
|
||||
RotatePoint( &aVertices[ii].y, &aVertices[ii].z, (int) (m_MatRotation.x * 10) );
|
||||
RotatePoint( &aVertices[ii].y, &aVertices[ii].z, m_MatRotation.x * 10 );
|
||||
|
||||
if( m_MatRotation.y )
|
||||
RotatePoint( &aVertices[ii].z, &aVertices[ii].x, (int) (m_MatRotation.y * 10) );
|
||||
RotatePoint( &aVertices[ii].z, &aVertices[ii].x, m_MatRotation.y * 10 );
|
||||
|
||||
if( m_MatRotation.z )
|
||||
RotatePoint( &aVertices[ii].x, &aVertices[ii].y, (int) (m_MatRotation.z * 10) );
|
||||
RotatePoint( &aVertices[ii].x, &aVertices[ii].y, m_MatRotation.z * 10 );
|
||||
|
||||
/* adjust offset position (offset is given in UNIT 3D (0.1 inch) */
|
||||
#define SCALE_3D_CONV ((IU_PER_MILS * 1000) / UNITS3D_TO_UNITSPCB)
|
||||
|
@ -553,9 +553,8 @@ void EDA_3D_CANVAS::Draw3D_DrawSegment( DRAWSEGMENT* segment )
|
||||
|
||||
case S_CIRCLE:
|
||||
{
|
||||
int radius = KiROUND( hypot( double(segment->GetStart().x - segment->GetEnd().x),
|
||||
double(segment->GetStart().y - segment->GetEnd().y) )
|
||||
);
|
||||
int radius = KiROUND( GetLineLength( segment->GetStart(),
|
||||
segment->GetEnd() ) );
|
||||
Draw3D_ZaxisCylinder( segment->GetStart(), radius,
|
||||
thickness, segment->GetWidth(),
|
||||
zpos, g_Parm_3D_Visu.m_BiuTo3Dunits );
|
||||
@ -587,9 +586,8 @@ void EDA_3D_CANVAS::Draw3D_DrawSegment( DRAWSEGMENT* segment )
|
||||
|
||||
case S_CIRCLE:
|
||||
{
|
||||
int radius = KiROUND( hypot( double(segment->GetStart().x - segment->GetEnd().x),
|
||||
double(segment->GetStart().y - segment->GetEnd().y) )
|
||||
);
|
||||
int radius = KiROUND( GetLineLength( segment->GetStart(),
|
||||
segment->GetEnd() ) );
|
||||
Draw3D_ZaxisCylinder( segment->GetStart(), radius,
|
||||
thickness, segment->GetWidth(),
|
||||
zpos, g_Parm_3D_Visu.m_BiuTo3Dunits );
|
||||
@ -806,9 +804,7 @@ void EDGE_MODULE::Draw3D( EDA_3D_CANVAS* glcanvas )
|
||||
|
||||
case S_CIRCLE:
|
||||
{
|
||||
int radius = KiROUND( hypot( double(m_Start.x - m_End.x),
|
||||
double(m_Start.y - m_End.y) )
|
||||
);
|
||||
int radius = KiROUND( GetLineLength( m_Start, m_End ) );
|
||||
Draw3D_ZaxisCylinder( m_Start, radius,
|
||||
thickness, GetWidth(),
|
||||
zpos, g_Parm_3D_Visu.m_BiuTo3Dunits );
|
||||
@ -848,9 +844,7 @@ void EDGE_MODULE::Draw3D( EDA_3D_CANVAS* glcanvas )
|
||||
|
||||
case S_CIRCLE:
|
||||
{
|
||||
int radius = KiROUND( hypot( double(m_Start.x - m_End.x),
|
||||
double(m_Start.y - m_End.y) )
|
||||
);
|
||||
int radius = KiROUND( GetLineLength( m_Start, m_End ) );
|
||||
Draw3D_ZaxisCylinder( m_Start, radius,
|
||||
thickness, GetWidth(),
|
||||
zpos, g_Parm_3D_Visu.m_BiuTo3Dunits );
|
||||
|
@ -377,10 +377,9 @@ void Draw3D_ArcSegment( const wxPoint& aCenterPos, const wxPoint& aStartPoint,
|
||||
|
||||
std::vector <CPolyPt> cornerBuffer;
|
||||
TransformArcToPolygon( cornerBuffer, aCenterPos, aStartPoint, aArcAngle,
|
||||
slice, aWidth );
|
||||
slice, aWidth );
|
||||
|
||||
Draw3D_SolidHorizontalPolyPolygons( cornerBuffer, aZpos, aThickness, aBiuTo3DUnits );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -389,8 +389,7 @@ void PLOTTER::segmentAsOval( const wxPoint& start, const wxPoint& end, int width
|
||||
else
|
||||
orient = -(int) ( RAD2DEG( atan2( (double)size.y, (double)size.x ) ) * 10.0 );
|
||||
|
||||
size.x = (int) sqrt( ( (double) size.x * size.x )
|
||||
+ ( (double) size.y * size.y ) ) + width;
|
||||
size.x = KiROUND( hypot( size.x, size.y ) ) + width;
|
||||
size.y = width;
|
||||
|
||||
FlashPadOval( center, size, orient, tracemode );
|
||||
|
@ -433,11 +433,11 @@ void GERBER_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& aSize,
|
||||
wxASSERT( outputFile );
|
||||
wxSize size( aSize );
|
||||
|
||||
/* Plot as flashed. */
|
||||
switch( orient )
|
||||
// Plot as an aperture flash
|
||||
switch( int( orient ) )
|
||||
{
|
||||
case 900:
|
||||
case 2700: /* rotation of 90 degrees or 270 swaps dimensions */
|
||||
case 2700: // rotation of 90 degrees or 270 swaps sizes
|
||||
EXCHG( size.x, size.y );
|
||||
|
||||
// Pass through
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <fctsys.h>
|
||||
#include <trigo.h>
|
||||
#include <macros.h>
|
||||
#include <common.h>
|
||||
#include <convert_basic_shapes_to_polygon.h>
|
||||
|
||||
/**
|
||||
@ -85,7 +86,6 @@ void TransformRoundedEndsSegmentToPolygon( std::vector <CPolyPt>& aCornerBuffer,
|
||||
wxPoint endp = aEnd - aStart; // end point coordinate for the same segment starting at (0,0)
|
||||
wxPoint startp = aStart;
|
||||
wxPoint corner;
|
||||
int seg_len;
|
||||
CPolyPt polypoint;
|
||||
|
||||
// normalize the position in order to have endp.x >= 0;
|
||||
@ -96,7 +96,7 @@ void TransformRoundedEndsSegmentToPolygon( std::vector <CPolyPt>& aCornerBuffer,
|
||||
}
|
||||
|
||||
int delta_angle = ArcTangente( endp.y, endp.x ); // delta_angle is in 0.1 degrees
|
||||
seg_len = (int) sqrt( ( (double) endp.y * endp.y ) + ( (double) endp.x * endp.x ) );
|
||||
int seg_len = KiROUND( EuclideanNorm( endp ) );
|
||||
|
||||
int delta = 3600 / aCircleToSegmentsCount; // rot angle in 0.1 degree
|
||||
|
||||
|
@ -1075,7 +1075,7 @@ void GRArc1( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2,
|
||||
y0 = ClipBox->GetY();
|
||||
xm = ClipBox->GetRight();
|
||||
ym = ClipBox->GetBottom();
|
||||
r = (int) hypot( x1 - xc, y1 - yc );
|
||||
r = KiROUND( Distance( x1, y1, xc, yc ) );
|
||||
if( xc < ( x0 - r ) )
|
||||
return;
|
||||
if( yc < ( y0 - r ) )
|
||||
|
@ -55,6 +55,7 @@ LAYER_MSK g_TabAllCopperLayerMask[NB_COPPER_LAYERS] = {
|
||||
|
||||
DISPLAY_OPTIONS DisplayOpt; // Display options for board items
|
||||
|
||||
// This will be always be 450 or 900 (by UI design) at the moment
|
||||
int g_RotationAngle;
|
||||
|
||||
int g_AnchorColor = BLUE;
|
||||
|
@ -29,7 +29,8 @@ static inline double square( int x ) // helper function to calculate x*x
|
||||
{
|
||||
return (double) x * x;
|
||||
}
|
||||
bool TestSegmentHit( wxPoint aRefPoint, wxPoint aStart, wxPoint aEnd, int aDist )
|
||||
bool TestSegmentHit( const wxPoint &aRefPoint, wxPoint aStart,
|
||||
wxPoint aEnd, int aDist )
|
||||
{
|
||||
// test for vertical or horizontal segment
|
||||
if( aEnd.x == aStart.x )
|
||||
@ -84,7 +85,7 @@ bool TestSegmentHit( wxPoint aRefPoint, wxPoint aStart, wxPoint aEnd, int aDist
|
||||
// the distance should be carefully calculated
|
||||
if( (aStart.x - aRefPoint.x) <= aDist )
|
||||
{
|
||||
double dd = square( aRefPoint.x - aStart.x) +
|
||||
double dd = square( aRefPoint.x - aStart.x ) +
|
||||
square( aRefPoint.y - aStart.y );
|
||||
if( dd <= square( aDist ) )
|
||||
return true;
|
||||
@ -92,8 +93,8 @@ bool TestSegmentHit( wxPoint aRefPoint, wxPoint aStart, wxPoint aEnd, int aDist
|
||||
|
||||
if( (aRefPoint.x - aEnd.x) <= aDist )
|
||||
{
|
||||
double dd = square(aRefPoint.x - aEnd.x) +
|
||||
square( aRefPoint.y - aEnd.y);
|
||||
double dd = square( aRefPoint.x - aEnd.x ) +
|
||||
square( aRefPoint.y - aEnd.y );
|
||||
if( dd <= square( aDist ) )
|
||||
return true;
|
||||
}
|
||||
@ -157,9 +158,14 @@ bool TestSegmentHit( wxPoint aRefPoint, wxPoint aStart, wxPoint aEnd, int aDist
|
||||
}
|
||||
|
||||
|
||||
int ArcTangente( int dy, int dx )
|
||||
double ArcTangente( int dy, int dx )
|
||||
{
|
||||
double fangle;
|
||||
|
||||
/* gcc is surprisingly smart in optimizing these conditions in
|
||||
a tree! */
|
||||
|
||||
if( dx == 0 && dy == 0 )
|
||||
return 0;
|
||||
|
||||
if( dy == 0 )
|
||||
{
|
||||
@ -193,8 +199,7 @@ int ArcTangente( int dy, int dx )
|
||||
return 1800 - 450;
|
||||
}
|
||||
|
||||
fangle = atan2( (double) dy, (double) dx ) / M_PI * 1800;
|
||||
return KiROUND( fangle );
|
||||
return atan2( dy, dx ) / M_PI * 1800;
|
||||
}
|
||||
|
||||
|
||||
@ -202,11 +207,7 @@ void RotatePoint( int* pX, int* pY, double angle )
|
||||
{
|
||||
int tmp;
|
||||
|
||||
while( angle < 0 )
|
||||
angle += 3600;
|
||||
|
||||
while( angle >= 3600 )
|
||||
angle -= 3600;
|
||||
NORMALIZE_ANGLE_POS( angle );
|
||||
|
||||
// Cheap and dirty optimizations for 0, 90, 180, and 270 degrees.
|
||||
if( angle == 0 )
|
||||
@ -287,11 +288,7 @@ void RotatePoint( double* pX, double* pY, double angle )
|
||||
{
|
||||
double tmp;
|
||||
|
||||
while( angle < 0 )
|
||||
angle += 3600;
|
||||
|
||||
while( angle >= 3600 )
|
||||
angle -= 3600;
|
||||
NORMALIZE_ANGLE_POS( angle );
|
||||
|
||||
// Cheap and dirty optimizations for 0, 90, 180, and 270 degrees.
|
||||
if( angle == 0 )
|
||||
@ -327,37 +324,3 @@ void RotatePoint( double* pX, double* pY, double angle )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double EuclideanNorm( wxPoint vector )
|
||||
{
|
||||
return hypot( (double) vector.x, (double) vector.y );
|
||||
}
|
||||
|
||||
double DistanceLinePoint( wxPoint linePointA, wxPoint linePointB, wxPoint referencePoint )
|
||||
{
|
||||
return fabs( (double) ( (linePointB.x - linePointA.x) * (linePointA.y - referencePoint.y) -
|
||||
(linePointA.x - referencePoint.x ) * (linePointB.y - linePointA.y) )
|
||||
/ EuclideanNorm( linePointB - linePointA ) );
|
||||
}
|
||||
|
||||
|
||||
bool HitTestPoints( wxPoint pointA, wxPoint pointB, double threshold )
|
||||
{
|
||||
wxPoint vectorAB = pointB - pointA;
|
||||
double distance = EuclideanNorm( vectorAB );
|
||||
|
||||
return distance < threshold;
|
||||
}
|
||||
|
||||
|
||||
double CrossProduct( wxPoint vectorA, wxPoint vectorB )
|
||||
{
|
||||
return (double)vectorA.x * vectorB.y - (double)vectorA.y * vectorB.x;
|
||||
}
|
||||
|
||||
|
||||
double GetLineLength( const wxPoint& aPointA, const wxPoint& aPointB )
|
||||
{
|
||||
return hypot( (double) aPointA.x - (double) aPointB.x,
|
||||
(double) aPointA.y - (double) aPointB.y );
|
||||
}
|
||||
|
@ -757,7 +757,7 @@ void LIB_ARC::calcEdit( const wxPoint& aPosition )
|
||||
dy = m_ArcEnd.y - m_ArcStart.y;
|
||||
cX -= m_ArcStart.x;
|
||||
cY -= m_ArcStart.y;
|
||||
angle = (int) ( atan2( (double) dy, (double) dx ) * 1800 / M_PI );
|
||||
angle = ArcTangente( dy, dx );
|
||||
RotatePoint( &dx, &dy, angle ); /* The segment dx, dy is horizontal
|
||||
* -> Length = dx, dy = 0 */
|
||||
RotatePoint( &cX, &cY, angle );
|
||||
@ -786,11 +786,9 @@ void LIB_ARC::calcRadiusAngles()
|
||||
|
||||
m_Radius = KiROUND( EuclideanNorm( centerStartVector ) );
|
||||
|
||||
m_t1 = (int) ( atan2( (double) centerStartVector.y,
|
||||
(double) centerStartVector.x ) * 1800 / M_PI );
|
||||
|
||||
m_t2 = (int) ( atan2( (double) centerEndVector.y,
|
||||
(double) centerEndVector.x ) * 1800 / M_PI );
|
||||
// Angles in eeschema are still integers
|
||||
m_t1 = KiROUND( ArcTangente( centerStartVector.y, centerStartVector.x ) );
|
||||
m_t2 = KiROUND( ArcTangente( centerEndVector.y, centerEndVector.x ) );
|
||||
|
||||
NORMALIZE_ANGLE_POS( m_t1 );
|
||||
NORMALIZE_ANGLE_POS( m_t2 ); // angles = 0 .. 3600
|
||||
|
@ -107,8 +107,7 @@ bool LIB_CIRCLE::HitTest( wxPoint aPosRef, int aThreshold, const TRANSFORM& aTra
|
||||
|
||||
wxPoint relpos = aPosRef - aTransform.TransformCoordinate( m_Pos );
|
||||
|
||||
int dist = KiROUND( sqrt( ( (double) relpos.x * relpos.x ) +
|
||||
( (double) relpos.y * relpos.y ) ) );
|
||||
int dist = KiROUND( EuclideanNorm( relpos ) );
|
||||
|
||||
if( abs( dist - m_Radius ) <= aThreshold )
|
||||
return true;
|
||||
@ -348,7 +347,7 @@ void LIB_CIRCLE::calcEdit( const wxPoint& aPosition )
|
||||
|
||||
int dx = m_Pos.x - aPosition.x;
|
||||
int dy = m_Pos.y - aPosition.y;
|
||||
m_Radius = KiROUND( sqrt( ( (double) dx * dx ) + ( (double) dy * dy ) ) );
|
||||
m_Radius = KiROUND( hypot( dx, dy ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -159,7 +159,7 @@ void SCH_BASE_FRAME::UpdateStatusBar()
|
||||
}
|
||||
|
||||
// We already decided the formatter above
|
||||
line.Printf( locformatter, dXpos, dYpos, sqrt( dXpos * dXpos + dYpos * dYpos ) );
|
||||
line.Printf( locformatter, dXpos, dYpos, hypot( dXpos, dYpos ) );
|
||||
SetStatusText( line, 3 );
|
||||
|
||||
// refresh units display
|
||||
|
@ -1,6 +1,8 @@
|
||||
|
||||
#include <macros.h>
|
||||
#include <transform.h>
|
||||
#include <common.h>
|
||||
#include <trigo.h>
|
||||
|
||||
|
||||
TRANSFORM& TRANSFORM::operator=( const TRANSFORM& aTransform )
|
||||
@ -77,7 +79,7 @@ bool TRANSFORM::MapAngles( int* aAngle1, int* aAngle2 ) const
|
||||
t = x * x1 + y * y1;
|
||||
y = x * x2 + y * y2;
|
||||
x = t;
|
||||
*aAngle1 = (int) ( atan2( y, x ) * 1800.0 / M_PI + 0.5 );
|
||||
*aAngle1 = KiROUND( ArcTangente( y, x ) );
|
||||
|
||||
x = cos( *aAngle2 * M_PI / 1800.0 );
|
||||
y = sin( *aAngle2 * M_PI / 1800.0 );
|
||||
|
@ -444,7 +444,7 @@ void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent,
|
||||
wxPoint end = mapPt( params[4].GetValue( tool ),
|
||||
params[5].GetValue( tool ), m_GerbMetric );
|
||||
wxPoint delta = end - start;
|
||||
int len = KiROUND( hypot( delta.x, delta.y ) );
|
||||
int len = KiROUND( EuclideanNorm( delta ) );
|
||||
|
||||
// To build the polygon, we must create a horizonta polygon starting to "start"
|
||||
// and rotate it to have it end point to "end"
|
||||
@ -459,7 +459,7 @@ void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent,
|
||||
aBuffer.push_back( currpt );
|
||||
|
||||
// Rotate rectangle and move it to the actual start point
|
||||
int angle = KiROUND( atan2( (double) delta.y, (double) delta.x ) * 1800.0 / M_PI );
|
||||
int angle = ArcTangente( delta.y, delta.x );
|
||||
|
||||
for( unsigned ii = 0; ii < 4; ii++ )
|
||||
{
|
||||
|
@ -360,8 +360,7 @@ void GERBER_DRAW_ITEM::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDra
|
||||
break;
|
||||
|
||||
case GBR_CIRCLE:
|
||||
radius = KiROUND(hypot( (double) ( m_End.x - m_Start.x ),
|
||||
(double) ( m_End.y - m_Start.y ) ));
|
||||
radius = KiROUND( GetLineLength( m_Start, m_End ) );
|
||||
|
||||
halfPenWidth = m_Size.x >> 1;
|
||||
|
||||
|
@ -332,7 +332,8 @@ void GBR_TO_PCB_EXPORTER::export_segarc_copper_item( GERBER_DRAW_ITEM* aGbrItem,
|
||||
{
|
||||
seg_start = curr_start;
|
||||
wxPoint curr_end = start;
|
||||
RotatePoint( &curr_end, aGbrItem->m_ArcCentre, -(int) (DELTA_ANGLE * ii * 1800 / M_PI) );
|
||||
RotatePoint( &curr_end, aGbrItem->m_ArcCentre,
|
||||
-(int) (DELTA_ANGLE * ii * 1800 / M_PI) );
|
||||
seg_end = curr_end;
|
||||
// Reverse Y axis:
|
||||
NEGATE( seg_start.y );
|
||||
|
@ -802,14 +802,10 @@ void GERBVIEW_FRAME::UpdateStatusBar()
|
||||
dx = screen->GetCrossHairPosition().x - screen->m_O_Curseur.x;
|
||||
dy = screen->GetCrossHairPosition().y - screen->m_O_Curseur.y;
|
||||
|
||||
if( dx==0 && dy==0 )
|
||||
theta = 0.0;
|
||||
else
|
||||
theta = atan2( (double) -dy, (double) dx );
|
||||
// atan2 in the 0,0 case returns 0
|
||||
theta = RAD2DEG( atan2( -dy, dx ) );
|
||||
|
||||
theta = theta * 180.0 / M_PI;
|
||||
|
||||
ro = sqrt( ( (double) dx * dx ) + ( (double) dy * dy ) );
|
||||
ro = hypot( dx, dy );
|
||||
wxString formatter;
|
||||
switch( g_UserUnit )
|
||||
{
|
||||
@ -868,7 +864,7 @@ void GERBVIEW_FRAME::UpdateStatusBar()
|
||||
dYpos = To_User_Unit( g_UserUnit, dy );
|
||||
|
||||
// We already decided the formatter above
|
||||
line.Printf( locformatter, dXpos, dYpos, sqrt( dXpos * dXpos + dYpos * dYpos ) );
|
||||
line.Printf( locformatter, dXpos, dYpos, hypot( dXpos, dYpos ) );
|
||||
SetStatusText( line, 3 );
|
||||
}
|
||||
}
|
||||
|
@ -339,8 +339,8 @@ static void fillArcPOLY( GERBER_DRAW_ITEM* aGbrItem,
|
||||
* angle is trigonometrical (counter-clockwise),
|
||||
* and axis is the X,Y gerber coordinates
|
||||
*/
|
||||
int start_angle = KiROUND(atan2( (double) start.y, (double) start.x ) * 1800 / M_PI);
|
||||
int end_angle = KiROUND(atan2( (double) end.y, (double) end.x ) * 1800 / M_PI);
|
||||
int start_angle = ArcTangente( start.y, start.x );
|
||||
int end_angle = ArcTangente( end.y, end.x );
|
||||
|
||||
// dummyTrack has right geometric parameters, but
|
||||
// fillArcGBRITEM calculates arc parameters for a draw function that expects
|
||||
|
@ -57,8 +57,8 @@ static inline const wxChar* GetChars( const wxString& s )
|
||||
#endif
|
||||
}
|
||||
|
||||
// This really need a function? anyway is used *a lot* of times
|
||||
template<class T> inline void NEGATE( T& x ) { x = -x; }
|
||||
// This really needs a function? well, it is used *a lot* of times
|
||||
template<class T> inline void NEGATE( T &x ) { x = -x; }
|
||||
|
||||
/// # of elements in an array
|
||||
#define DIM( x ) unsigned( sizeof(x) / sizeof( (x)[0] ) ) // not size_t
|
||||
|
@ -28,7 +28,8 @@
|
||||
|
||||
#ifndef TRIGO_H
|
||||
#define TRIGO_H
|
||||
|
||||
#include <math.h>
|
||||
#include <wx/gdicmn.h> // For wxPoint
|
||||
|
||||
/*
|
||||
* Calculate the new point of coord coord pX, pY,
|
||||
@ -46,7 +47,7 @@ void RotatePoint( int *pX, int *pY, int cx, int cy, double angle );
|
||||
* Calculates the new coord point point
|
||||
* for a rotation angle in (1 / 10 degree)
|
||||
*/
|
||||
static inline void RotatePoint( wxPoint* point, double angle )
|
||||
inline void RotatePoint( wxPoint* point, double angle )
|
||||
{
|
||||
RotatePoint( &point->x, &point->y, angle );
|
||||
}
|
||||
@ -64,34 +65,69 @@ void RotatePoint( double *pX, double *pY, double cx, double cy, double angle );
|
||||
/* Return the arc tangent of 0.1 degrees coord vector dx, dy
|
||||
* between -1800 and 1800
|
||||
* Equivalent to atan2 (but faster for calculations if
|
||||
* the angle is 0 to -1800, or + - 900
|
||||
* the angle is 0 to -1800, or + - 900)
|
||||
* Lorenzo: In fact usually atan2 already has to do these optimizations
|
||||
* (due to the discontinuity in tan) but this function also returns
|
||||
* in decidegrees instead of radians, so it's handier
|
||||
*/
|
||||
int ArcTangente( int dy, int dx );
|
||||
double ArcTangente( int dy, int dx );
|
||||
|
||||
//! @brief Euclidean norm of a 2D vector
|
||||
//! @param vector Two-dimensional vector
|
||||
//! @return Euclidean norm of the vector
|
||||
inline double EuclideanNorm( const wxPoint &vector )
|
||||
{
|
||||
// this is working with doubles
|
||||
return hypot( vector.x, vector.y );
|
||||
}
|
||||
|
||||
//! @brief Compute the distance between a line and a reference point
|
||||
//! Reference: http://mathworld.wolfram.com/Point-LineDistance2-Dimensional.html
|
||||
//! @param linePointA Point on line
|
||||
//! @param linePointB Point on line
|
||||
//! @param referencePoint Reference point
|
||||
double DistanceLinePoint( wxPoint linePointA, wxPoint linePointB, wxPoint referencePoint );
|
||||
|
||||
//! @brief Euclidean norm of a 2D vector
|
||||
//! @param vector Two-dimensional vector
|
||||
//! @return Euclidean norm of the vector
|
||||
double EuclideanNorm( wxPoint vector );
|
||||
inline double DistanceLinePoint( const wxPoint &linePointA,
|
||||
const wxPoint &linePointB,
|
||||
const wxPoint &referencePoint )
|
||||
{
|
||||
// Some of the multiple double casts are redundant. However in the previous
|
||||
// definition the cast was (implicitly) done too late, just before
|
||||
// the division (EuclideanNorm gives a double so from int it would
|
||||
// be promoted); that means that the whole expression were
|
||||
// vulnerable to overflow during int multiplications
|
||||
return fabs( ( double(linePointB.x - linePointA.x) *
|
||||
double(linePointA.y - referencePoint.y) -
|
||||
double(linePointA.x - referencePoint.x ) *
|
||||
double(linePointB.y - linePointA.y) )
|
||||
/ EuclideanNorm( linePointB - linePointA ) );
|
||||
}
|
||||
|
||||
//! @brief Test, if two points are near each other
|
||||
//! @param pointA First point
|
||||
//! @param pointB Second point
|
||||
//! @param threshold The maximum distance
|
||||
//! @return True or false
|
||||
bool HitTestPoints( wxPoint pointA, wxPoint pointB, double threshold );
|
||||
inline bool HitTestPoints( const wxPoint &pointA, const wxPoint &pointB,
|
||||
double threshold )
|
||||
{
|
||||
wxPoint vectorAB = pointB - pointA;
|
||||
|
||||
// Compare the distances squared. The double is needed to avoid
|
||||
// overflow during int multiplication
|
||||
double sqdistance = (double)vectorAB.x * vectorAB.x +
|
||||
(double)vectorAB.y * vectorAB.y;
|
||||
|
||||
return sqdistance < threshold * threshold;
|
||||
}
|
||||
|
||||
//! @brief Determine the cross product
|
||||
//! @param vectorA Two-dimensional vector
|
||||
//! @param vectorB Two-dimensional vector
|
||||
double CrossProduct( wxPoint vectorA, wxPoint vectorB );
|
||||
|
||||
inline double CrossProduct( const wxPoint &vectorA, const wxPoint &vectorB )
|
||||
{
|
||||
// As before the cast is to avoid int overflow
|
||||
return (double)vectorA.x * vectorB.y - (double)vectorA.y * vectorB.x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function TestSegmentHit
|
||||
@ -102,13 +138,21 @@ double CrossProduct( wxPoint vectorA, wxPoint vectorB );
|
||||
* @param aEnd is the second end-point of the line segment
|
||||
* @param aDist = maximum distance for hit
|
||||
*/
|
||||
bool TestSegmentHit( wxPoint aRefPoint, wxPoint aStart, wxPoint aEnd, int aDist );
|
||||
bool TestSegmentHit( const wxPoint &aRefPoint, wxPoint aStart,
|
||||
wxPoint aEnd, int aDist );
|
||||
|
||||
/**
|
||||
* Function GetLineLength
|
||||
* returns the length of a line segment defined by \a aPointA and \a aPointB.
|
||||
* @return Length of a line.
|
||||
* See also EuclideanNorm and Distance for the single vector or four
|
||||
* scalar versions
|
||||
* @return Length of a line (as double)
|
||||
*/
|
||||
double GetLineLength( const wxPoint& aPointA, const wxPoint& aPointB );
|
||||
inline double GetLineLength( const wxPoint& aPointA, const wxPoint& aPointB )
|
||||
{
|
||||
// Implicitly casted to double
|
||||
return hypot( aPointA.x - aPointB.x,
|
||||
aPointA.y - aPointB.y );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include <macros.h>
|
||||
#include <trigo.h>
|
||||
#include <pcbcommon.h>
|
||||
|
||||
#include <math_for_graphics.h>
|
||||
#include <class_board.h>
|
||||
#include <class_track.h>
|
||||
|
||||
@ -125,7 +125,7 @@ void PlacePad( D_PAD* aPad, int color, int marge, int op_logic )
|
||||
{
|
||||
TraceFilledRectangle( shape_pos.x - dx, shape_pos.y - dy,
|
||||
shape_pos.x + dx, shape_pos.y + dy,
|
||||
(int) aPad->GetOrientation(),
|
||||
aPad->GetOrientation(),
|
||||
aPad->GetLayerMask(), color, op_logic );
|
||||
}
|
||||
}
|
||||
@ -561,8 +561,7 @@ void TraceFilledRectangle( int ux0, int uy0, int ux1, int uy1,
|
||||
|
||||
cx = (ux0 + ux1) / 2;
|
||||
cy = (uy0 + uy1) / 2;
|
||||
radius = (int) sqrt( (double) ( cx - ux0 ) * ( cx - ux0 )
|
||||
+ (double) ( cy - uy0 ) * ( cy - uy0 ) );
|
||||
radius = KiROUND( Distance( ux0, uy0, cx, cy ) );
|
||||
|
||||
// Calculating coordinate limits belonging to the rectangle.
|
||||
row_max = ( cy + radius ) / RoutingMatrix.m_GridRouting;
|
||||
@ -689,7 +688,7 @@ void DrawSegmentQcq( int ux0, int uy0, int ux1, int uy1, int lg, LAYER_NUM layer
|
||||
|
||||
if( dx )
|
||||
{
|
||||
angle = (int) ( atan2( (double) dy, (double) dx ) * 1800 / M_PI );
|
||||
angle = ArcTangente( dy, dx );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -758,7 +757,7 @@ void TraceCircle( int ux0, int uy0, int ux1, int uy1, int lg, LAYER_NUM layer,
|
||||
int ii;
|
||||
int angle;
|
||||
|
||||
radius = (int) hypot( (double) (ux1 - ux0), (double) (uy1 - uy0) );
|
||||
radius = KiROUND( Distance( ux0, uy0, ux1, uy1 ) );
|
||||
|
||||
x0 = x1 = radius;
|
||||
y0 = y1 = 0;
|
||||
@ -803,7 +802,7 @@ void TraceArc( int ux0, int uy0, int ux1, int uy1, int ArcAngle, int lg,
|
||||
int angle, StAngle;
|
||||
|
||||
|
||||
radius = (int) hypot( (double) (ux1 - ux0), (double) (uy1 - uy0) );
|
||||
radius = KiROUND( Distance( ux0, uy0, ux1, uy1 ) );
|
||||
|
||||
x0 = ux1 - ux0;
|
||||
y0 = uy1 - uy0;
|
||||
@ -813,7 +812,7 @@ void TraceArc( int ux0, int uy0, int ux1, int uy1, int ArcAngle, int lg,
|
||||
lg = 1;
|
||||
|
||||
nb_segm = ( 2 * radius ) / lg;
|
||||
nb_segm = ( nb_segm * abs( ArcAngle ) ) / 3600;
|
||||
nb_segm = ( nb_segm * std::abs( ArcAngle ) ) / 3600;
|
||||
|
||||
if( nb_segm < 5 )
|
||||
nb_segm = 5;
|
||||
@ -826,11 +825,7 @@ void TraceArc( int ux0, int uy0, int ux1, int uy1, int ArcAngle, int lg,
|
||||
angle = ( ArcAngle * ii ) / nb_segm;
|
||||
angle += StAngle;
|
||||
|
||||
while( angle >= 3600 )
|
||||
angle -= 3600;
|
||||
|
||||
while( angle < 0 )
|
||||
angle += 3600;
|
||||
NORMALIZE_ANGLE_POS( angle );
|
||||
|
||||
x1 = (int) ( radius * cos( DEG2RAD( (double)angle / 10.0 ) ) );
|
||||
y1 = (int) ( radius * sin( DEG2RAD( (double)angle / 10.0 ) ) );
|
||||
|
@ -317,12 +317,12 @@ void PlaceCells( BOARD* aPcb, int net_code, int flag )
|
||||
layerMask = GetLayerMask( PtText->GetLayer() );
|
||||
|
||||
TraceFilledRectangle( ux0 - marge, uy0 - marge, ux1 + marge,
|
||||
uy1 + marge, (int) (PtText->GetOrientation()),
|
||||
uy1 + marge, PtText->GetOrientation(),
|
||||
layerMask, HOLE, WRITE_CELL );
|
||||
|
||||
TraceFilledRectangle( ux0 - via_marge, uy0 - via_marge,
|
||||
ux1 + via_marge, uy1 + via_marge,
|
||||
(int) (PtText->GetOrientation()),
|
||||
PtText->GetOrientation(),
|
||||
layerMask, VIA_IMPOSSIBLE, WRITE_OR_CELL );
|
||||
}
|
||||
break;
|
||||
|
@ -46,7 +46,7 @@
|
||||
#include <collectors.h>
|
||||
#include <class_drawpanel.h>
|
||||
#include <vector2d.h>
|
||||
|
||||
#include <trigo.h>
|
||||
|
||||
// Configuration entry names.
|
||||
static const wxString UserGridSizeXEntry( wxT( "PcbUserGrid_X" ) );
|
||||
@ -563,14 +563,9 @@ void PCB_BASE_FRAME::UpdateStatusBar()
|
||||
dx = screen->GetCrossHairPosition().x - screen->m_O_Curseur.x;
|
||||
dy = screen->GetCrossHairPosition().y - screen->m_O_Curseur.y;
|
||||
|
||||
if( dx==0 && dy==0 )
|
||||
theta = 0.0;
|
||||
else
|
||||
theta = atan2( (double) -dy, (double) dx );
|
||||
theta = ArcTangente( -dy, dx ) / 10;
|
||||
|
||||
theta = theta * 180.0 / M_PI;
|
||||
|
||||
ro = sqrt( ( (double) dx * dx ) + ( (double) dy * dy ) );
|
||||
ro = hypot( dx, dy );
|
||||
wxString formatter;
|
||||
switch( g_UserUnit )
|
||||
{
|
||||
@ -661,7 +656,7 @@ void PCB_BASE_FRAME::UpdateStatusBar()
|
||||
#endif
|
||||
|
||||
// We already decided the formatter above
|
||||
line.Printf( locformatter, dXpos, dYpos, sqrt( dXpos * dXpos + dYpos * dYpos ) );
|
||||
line.Printf( locformatter, dXpos, dYpos, hypot( dXpos, dYpos ) );
|
||||
SetStatusText( line, 3 );
|
||||
}
|
||||
}
|
||||
|
@ -475,7 +475,7 @@ void CreateThermalReliefPadPolygon( std::vector<CPolyPt>& aCornerBuffer,
|
||||
double dtmp = sqrt( ( (double) outer_radius * outer_radius ) -
|
||||
( (double) corner.x * corner.x ) );
|
||||
corner.y = (int) dtmp;
|
||||
RotatePoint( &corner, 90 );
|
||||
RotatePoint( &corner, 90 ); // 9 degrees is the spoke fillet size
|
||||
|
||||
// calculate the ending point of the outter arc
|
||||
corner_end.x = corner.y;
|
||||
|
@ -240,10 +240,7 @@ void DIMENSION::AdjustDimensionDetails( bool aDoNotChangeText )
|
||||
// Calculate dimension value
|
||||
measure = KiROUND( hypot( (double) deltax, (double) deltay ) );
|
||||
|
||||
if( deltax || deltay )
|
||||
angle = atan2( (double) deltay, (double) deltax );
|
||||
else
|
||||
angle = 0.0;
|
||||
angle = atan2( deltay, deltax );
|
||||
|
||||
// Calculation of parameters X and Y dimensions of the arrows and lines.
|
||||
hx = hy = ii;
|
||||
@ -266,12 +263,12 @@ void DIMENSION::AdjustDimensionDetails( bool aDoNotChangeText )
|
||||
if( m_featureLineGO.y == m_crossBarO.y )
|
||||
hy = 0;
|
||||
|
||||
angle_f = angle + (M_PI * 27.5 / 180);
|
||||
arrow_up_X = (int) ( arrowz * cos( angle_f ) );
|
||||
arrow_up_Y = (int) ( arrowz * sin( angle_f ) );
|
||||
angle_f = angle - (M_PI * 27.5 / 180);
|
||||
arrow_dw_X = (int) ( arrowz * cos( angle_f ) );
|
||||
arrow_dw_Y = (int) ( arrowz * sin( angle_f ) );
|
||||
angle_f = angle + DEG2RAD( 27.5 );
|
||||
arrow_up_X = wxRound( arrowz * cos( angle_f ) );
|
||||
arrow_up_Y = wxRound( arrowz * sin( angle_f ) );
|
||||
angle_f = angle - DEG2RAD( 27.5 );
|
||||
arrow_dw_X = wxRound( arrowz * cos( angle_f ) );
|
||||
arrow_dw_Y = wxRound( arrowz * sin( angle_f ) );
|
||||
}
|
||||
|
||||
m_arrowG1O.x = m_crossBarO.x;
|
||||
@ -312,11 +309,7 @@ void DIMENSION::AdjustDimensionDetails( bool aDoNotChangeText )
|
||||
|
||||
double newAngle = -(angle * 1800 / M_PI);
|
||||
|
||||
if( newAngle < 0 )
|
||||
newAngle += 3600;
|
||||
|
||||
if( newAngle >= 3600 )
|
||||
newAngle -= 3600;
|
||||
NORMALIZE_ANGLE_POS( newAngle );
|
||||
|
||||
if( newAngle > 900 && newAngle < 2700 )
|
||||
newAngle -= 1800;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user