KiCad PCB EDA Suite
trigo.h File Reference
#include <cmath>
#include <math/vector2d.h>
#include <wx/gdicmn.h>

Go to the source code of this file.

Functions

bool IsPointOnSegment (const wxPoint &aSegStart, const wxPoint &aSegEnd, const wxPoint &aTestPoint)
 Test if aTestPoint is on line defined by aSegStart and aSegEnd. More...
 
bool SegmentIntersectsSegment (const wxPoint &a_p1_l1, const wxPoint &a_p2_l1, const wxPoint &a_p1_l2, const wxPoint &a_p2_l2, wxPoint *aIntersectionPoint=nullptr)
 Test if two lines intersect. More...
 
void RotatePoint (int *pX, int *pY, double angle)
 
void RotatePoint (int *pX, int *pY, int cx, int cy, double angle)
 
void RotatePoint (wxPoint *point, double angle)
 
void RotatePoint (VECTOR2I &point, double angle)
 
void RotatePoint (VECTOR2I &point, const VECTOR2I &centre, double angle)
 
void RotatePoint (wxPoint *point, const wxPoint &centre, double angle)
 
void RotatePoint (double *pX, double *pY, double angle)
 
void RotatePoint (double *pX, double *pY, double cx, double cy, double angle)
 
const VECTOR2I GetArcCenter (const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
 Determine the center of an arc or circle given three points on its circumference. More...
 
const VECTOR2D GetArcCenter (const VECTOR2D &aStart, const VECTOR2D &aMid, const VECTOR2D &aEnd)
 
const wxPoint GetArcCenter (const wxPoint &aStart, const wxPoint &aMid, const wxPoint &aEnd)
 
const wxPoint GetArcCenter (VECTOR2I aStart, VECTOR2I aEnd, double aAngle)
 
double GetArcAngle (const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
 Returns the subtended angle for a given arc. More...
 
const VECTOR2I GetArcMid (const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aCenter, bool aMinArcAngle=true)
 Returns the middle point of an arc, half-way between aStart and aEnd. More...
 
double ArcTangente (int dy, int dx)
 
double EuclideanNorm (const wxPoint &vector)
 Euclidean norm of a 2D vector. More...
 
double EuclideanNorm (const wxSize &vector)
 
double DistanceLinePoint (const wxPoint &linePointA, const wxPoint &linePointB, const wxPoint &referencePoint)
 Compute the distance between a line and a reference point Reference: http://mathworld.wolfram.com/Point-LineDistance2-Dimensional.html. More...
 
bool HitTestPoints (const wxPoint &pointA, const wxPoint &pointB, double threshold)
 Test, if two points are near each other. More...
 
double CrossProduct (const wxPoint &vectorA, const wxPoint &vectorB)
 Determine the cross product. More...
 
bool TestSegmentHit (const wxPoint &aRefPoint, wxPoint aStart, wxPoint aEnd, int aDist)
 Test if aRefPoint is with aDistance on the line defined by aStart and aEnd. More...
 
double GetLineLength (const wxPoint &aPointA, const wxPoint &aPointB)
 Return the length of a line segment defined by aPointA and aPointB. More...
 
double DEG2RAD (double deg)
 
double RAD2DEG (double rad)
 
double DECIDEG2RAD (double deg)
 
double RAD2DECIDEG (double rad)
 
template<class T >
NormalizeAngle360Max (T Angle)
 Normalize angle to be >=-360.0 and <= 360.0 Angle can be equal to -360 or +360. More...
 
template<class T >
NormalizeAngle360Min (T Angle)
 Normalize angle to be > -360.0 and < 360.0 Angle equal to -360 or +360 are set to 0. More...
 
template<class T >
NormalizeAngleNeg (T Angle)
 Normalize angle to be in the 0.0 . More...
 
template<class T >
NormalizeAnglePos (T Angle)
 Normalize angle to be in the 0.0 . More...
 
template<class T >
void NORMALIZE_ANGLE_POS (T &Angle)
 
double NormalizeAngleDegreesPos (double Angle)
 Normalize angle to be in the 0.0 . More...
 
void NORMALIZE_ANGLE_DEGREES_POS (double &Angle)
 
double NormalizeAngleRadiansPos (double Angle)
 
double NormalizeAngleDegrees (double Angle, double aMin, double aMax)
 Normalize angle to be aMin < angle <= aMax angle is in degrees. More...
 
template<class T , class T2 >
AddAngles (T a1, T2 a2)
 Add two angles (keeping the result normalized). T2 is here. More...
 
template<class T >
NegateAndNormalizeAnglePos (T Angle)
 
template<class T >
void NEGATE_AND_NORMALIZE_ANGLE_POS (T &Angle)
 
template<class T >
NormalizeAngle90 (T Angle)
 Normalize angle to be in the -90.0 .. 90.0 range. More...
 
template<class T >
void NORMALIZE_ANGLE_90 (T &Angle)
 
template<class T >
NormalizeAngle180 (T Angle)
 Normalize angle to be in the -180.0 .. 180.0 range. More...
 
template<class T >
void NORMALIZE_ANGLE_180 (T &Angle)
 
bool InterceptsPositiveX (double aStartAngle, double aEndAngle)
 Test if an arc from aStartAngle to aEndAngle crosses the positive X axis (0 degrees). More...
 
bool InterceptsNegativeX (double aStartAngle, double aEndAngle)
 Test if an arc from aStartAngle to aEndAngle crosses the negative X axis (180 degrees). More...
 
double sindecideg (double r, double a)
 Circle generation utility: computes r * sin(a) Where a is in decidegrees, not in radians. More...
 
double cosdecideg (double r, double a)
 Circle generation utility: computes r * cos(a) Where a is in decidegrees, not in radians. More...
 

Function Documentation

◆ AddAngles()

template<class T , class T2 >
T AddAngles ( a1,
T2  a2 
)
inline

Add two angles (keeping the result normalized). T2 is here.

Definition at line 335 of file trigo.h.

336 {
337  a1 += a2;
338  NORMALIZE_ANGLE_POS( a1 );
339  return a1;
340 }
void NORMALIZE_ANGLE_POS(T &Angle)
Definition: trigo.h:288

References NORMALIZE_ANGLE_POS().

Referenced by PSLIKE_PLOTTER::FlashPadOval(), DXF_PLOTTER::FlashPadOval(), HPGL_PLOTTER::FlashPadOval(), and PLOTTER::sketchOval().

◆ ArcTangente()

double ArcTangente ( int  dy,
int  dx 
)

Definition at line 182 of file trigo.cpp.

183 {
184 
185  /* gcc is surprisingly smart in optimizing these conditions in
186  a tree! */
187 
188  if( dx == 0 && dy == 0 )
189  return 0;
190 
191  if( dy == 0 )
192  {
193  if( dx >= 0 )
194  return 0;
195  else
196  return -1800;
197  }
198 
199  if( dx == 0 )
200  {
201  if( dy >= 0 )
202  return 900;
203  else
204  return -900;
205  }
206 
207  if( dx == dy )
208  {
209  if( dx >= 0 )
210  return 450;
211  else
212  return -1800 + 450;
213  }
214 
215  if( dx == -dy )
216  {
217  if( dx >= 0 )
218  return -450;
219  else
220  return 1800 - 450;
221  }
222 
223  // Of course dy and dx are treated as double
224  return RAD2DECIDEG( std::atan2( (double) dy, (double) dx ) );
225 }
double RAD2DECIDEG(double rad)
Definition: trigo.h:236

References RAD2DECIDEG().

Referenced by BuildCornersList_S_Shape(), LIB_ARC::CalcEdit(), LIB_ARC::CalcRadiusAngles(), AM_PRIMITIVE::ConvertShapeToPolygon(), AR_MATRIX::drawSegmentQcq(), fillArcPOLY(), ARC::GetAngle(), SCH_LINE::GetAngleFrom(), PCB_SHAPE::GetArcAngleEnd(), ARC::GetArcAngleEnd(), PCB_SHAPE::GetArcAngleStart(), ARC::GetArcAngleStart(), GetArcMid(), SHAPE_ARC::GetCentralAngle(), CADSTAR_SCH_ARCHIVE_LOADER::getPolarAngle(), CADSTAR_PCB_ARCHIVE_LOADER::getPolarAngle(), SCH_LINE::GetReverseAngleFrom(), GRCSegm(), PCB_SHAPE::HitTest(), ARC::HitTest(), PCAD2KICAD::PCB_ARC::Parse(), BRDITEMS_PLOTTER::PlotFootprintGraphicItem(), BRDITEMS_PLOTTER::PlotPcbShape(), PLOTTER::segmentAsOval(), SHAPE_ARC::SHAPE_ARC(), and AR_MATRIX::traceArc().

◆ cosdecideg()

double cosdecideg ( double  r,
double  a 
)
inline

Circle generation utility: computes r * cos(a) Where a is in decidegrees, not in radians.

Definition at line 439 of file trigo.h.

440 {
441  return r * cos( DECIDEG2RAD( a ) );
442 }
double DECIDEG2RAD(double deg)
Definition: trigo.h:235

References DECIDEG2RAD().

Referenced by HPGL_PLOTTER::Arc(), PLOTTER::Arc(), PDF_PLOTTER::Arc(), PCAD2KICAD::PCB_ARC::Parse(), GERBER_PLOTTER::plotArc(), GERBER_PLOTTER::plotRoundRectAsRegion(), AR_MATRIX::traceArc(), and AR_MATRIX::traceCircle().

◆ CrossProduct()

double CrossProduct ( const wxPoint &  vectorA,
const wxPoint &  vectorB 
)
inline

Determine the cross product.

Parameters
vectorATwo-dimensional vector
vectorBTwo-dimensional vector

Definition at line 200 of file trigo.h.

201 {
202  // As before the cast is to avoid int overflow
203  return (double)vectorA.x * vectorB.y - (double)vectorA.y * vectorB.x;
204 }

Referenced by LIB_ARC::HitTest().

◆ DECIDEG2RAD()

◆ DEG2RAD()

◆ DistanceLinePoint()

double DistanceLinePoint ( const wxPoint &  linePointA,
const wxPoint &  linePointB,
const wxPoint &  referencePoint 
)
inline

Compute the distance between a line and a reference point Reference: http://mathworld.wolfram.com/Point-LineDistance2-Dimensional.html.

Parameters
linePointAPoint on line
linePointBPoint on line
referencePointReference point

Definition at line 165 of file trigo.h.

168 {
169  // Some of the multiple double casts are redundant. However in the previous
170  // definition the cast was (implicitly) done too late, just before
171  // the division (EuclideanNorm gives a double so from int it would
172  // be promoted); that means that the whole expression were
173  // vulnerable to overflow during int multiplications
174  return fabs( ( static_cast<double>( linePointB.x - linePointA.x ) *
175  static_cast<double>( linePointA.y - referencePoint.y ) -
176  static_cast<double>( linePointA.x - referencePoint.x ) *
177  static_cast<double>( linePointB.y - linePointA.y) )
178  / EuclideanNorm( linePointB - linePointA ) );
179 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:148

References EuclideanNorm().

Referenced by LIB_POLYLINE::AddCorner().

◆ EuclideanNorm() [1/2]

double EuclideanNorm ( const wxPoint &  vector)
inline

Euclidean norm of a 2D vector.

Parameters
vectorTwo-dimensional vector
Returns
Euclidean norm of the vector

Definition at line 148 of file trigo.h.

149 {
150  // this is working with doubles
151  return hypot( vector.x, vector.y );
152 }

Referenced by PCB_GRID_HELPER::AlignToArc(), PCB_GRID_HELPER::AlignToSegment(), EE_GRID_HELPER::BestSnapAnchor(), BOOST_AUTO_TEST_CASE(), BuildCornersList_S_Shape(), PNS::DP_GATEWAYS::buildDpContinuation(), PAD::BuildEffectivePolygon(), PNS::DP_GATEWAYS::BuildFromPrimitivePair(), PNS::DP_GATEWAYS::BuildGeneric(), PNS::DP_GATEWAYS::BuildOrthoProjections(), LIB_ARC::CalcRadiusAngles(), SHAPE_ARC::Collide(), PCB_GRID_HELPER::computeAnchors(), CIRCLE::ConstructFromTanTanPt(), AM_PRIMITIVE::ConvertShapeToPolygon(), MICROWAVE_TOOL::createMicrowaveInductor(), PNS::DP_PRIMITIVE_PAIR::CursorOrientation(), CN_ANCHOR::Dist(), DistanceLinePoint(), EDIT_TOOL::DragArcTrack(), KIGFX::CAIRO_GAL_BASE::DrawSegment(), DRAWING_TOOL::DrawVia(), PCB_POINT_EDITOR::editArcMidKeepEndpoints(), PAD_TOOL::EnumeratePads(), extractDiffPairCoupledItems(), PNS::findCoupledVertices(), PNS::DIFF_PAIR_PLACER::FindDpPrimitivePair(), gen_arc(), GetArcCenter(), PAD::GetBestAnchorPosition(), DS_DRAW_ITEM_LINE::GetSelectMenuText(), SCH_LINE::GetSelectMenuText(), BOARD::GetTrackLength(), EE_SELECTION_TOOL::GuessSelectionCandidates(), ALTIUM_PCB::HelperParseDimensions6Leader(), ALTIUM_PCB::HelperParseDimensions6Linear(), PCB_SHAPE::HitTest(), ARC::HitTest(), CIRCLE::IntersectLine(), GEOM_TEST::IsPointAtDistance(), PNS::makeGapVector(), PNS::MEANDERED_LINE::MeanderSegment(), PNS::TOPOLOGY::NearestUnconnectedItem(), VECTOR3< double >::Normalize(), SHAPE_LINE_CHAIN::compareOriginDistance::operator()(), compareOriginDistance::operator()(), GPCB_FPL_CACHE::parseFOOTPRINT(), SHAPE_LINE_CHAIN::PathLength(), pushoutForce(), PNS::DIFF_PAIR_PLACER::routeHead(), PLOTTER::segmentAsOval(), PNS::LINE::snapDraggedCorner(), PNS::DRAGGER::startDragSegment(), DRC_TEST_PROVIDER_HOLE_CLEARANCE::testHoleAgainstHole(), TransformOvalToPolygon(), and PCB_POINT_EDITOR::updateItem().

◆ EuclideanNorm() [2/2]

double EuclideanNorm ( const wxSize &  vector)
inline

Definition at line 154 of file trigo.h.

155 {
156  // this is working with doubles, too
157  return hypot( vector.x, vector.y );
158 }

◆ GetArcAngle()

double GetArcAngle ( const VECTOR2I aStart,
const VECTOR2I aMid,
const VECTOR2I aEnd 
)

Returns the subtended angle for a given arc.

Definition at line 492 of file trigo.cpp.

493 {
494  VECTOR2I center = GetArcCenter( aStart, aMid, aEnd );
495 
496  // Check if the new arc is CW or CCW
497  VECTOR2D startLine = aStart - center;
498  VECTOR2D endLine = aEnd - center;
499  double angle = RAD2DECIDEG( endLine.Angle() - startLine.Angle() );
500 
501  VECTOR2D v1, v2;
502  v1 = aStart - aMid;
503  v2 = aEnd - aMid;
504  double theta = RAD2DECIDEG( v1.Angle() );
505 
506  RotatePoint( &( v1.x ), &( v1.y ), theta );
507  RotatePoint( &( v2.x ), &( v2.y ), theta );
508 
509  bool clockwise = ( ( v1.Angle() - v2.Angle() ) > 0 );
510 
511  // Normalize the angle
512  if( clockwise && angle < 0.0 )
513  angle += 3600.0;
514  else if( !clockwise && angle > 0.0 )
515  angle -= 3600.0;
516 
517  return angle;
518 }
VECTOR2I v2(1, 0)
Test suite for KiCad math code.
Define a general 2D-vector/point.
Definition: vector2d.h:61
double RAD2DECIDEG(double rad)
Definition: trigo.h:236
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:228
double Angle() const
Compute the angle of the vector.
Definition: vector2d.h:307
const wxPoint GetArcCenter(VECTOR2I aStart, VECTOR2I aEnd, double aAngle)
Definition: trigo.cpp:361
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)

References PNS::angle(), VECTOR2< T >::Angle(), GetArcCenter(), RAD2DECIDEG(), RotatePoint(), v2, VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by CONVERT_TOOL::SegmentToArc().

◆ GetArcCenter() [1/4]

const VECTOR2I GetArcCenter ( const VECTOR2I aStart,
const VECTOR2I aMid,
const VECTOR2I aEnd 
)

Determine the center of an arc or circle given three points on its circumference.

Parameters
aStartThe starting point of the circle (equivalent to aEnd)
aMidThe point on the arc, half-way between aStart and aEnd
aEndThe ending point of the circle (equivalent to aStart)
Returns
The center of the circle

Definition at line 450 of file trigo.cpp.

451 {
452  VECTOR2D dStart( static_cast<double>( aStart.x ), static_cast<double>( aStart.y ) );
453  VECTOR2D dMid( static_cast<double>( aMid.x ), static_cast<double>( aMid.y ) );
454  VECTOR2D dEnd( static_cast<double>( aEnd.x ), static_cast<double>( aEnd.y ) );
455  VECTOR2D dCenter = GetArcCenter( dStart, dMid, dEnd );
456 
457  VECTOR2I iCenter;
458 
459  iCenter.x = KiROUND( Clamp<double>( double( std::numeric_limits<int>::min() / 2.0 ),
460  dCenter.x,
461  double( std::numeric_limits<int>::max() / 2.0 ) ) );
462 
463  iCenter.y = KiROUND( Clamp<double>( double( std::numeric_limits<int>::min() / 2.0 ),
464  dCenter.y,
465  double( std::numeric_limits<int>::max() / 2.0 ) ) );
466 
467  return iCenter;
468 }
const wxPoint GetArcCenter(VECTOR2I aStart, VECTOR2I aEnd, double aAngle)
Definition: trigo.cpp:361
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:68

References GetArcCenter(), KiROUND(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by SHAPE_ARC::ConstructFromStartEndAngle(), SHAPE_ARC::GetCenter(), ARC::GetPosition(), ARC::GetRadius(), SCH_SEXPR_PARSER::parseArc(), CONVERT_TOOL::SegmentToArc(), PCB_SHAPE::SetArcGeometry(), and DIALOG_GRAPHIC_ITEM_PROPERTIES::TransferDataFromWindow().

◆ GetArcCenter() [2/4]

const VECTOR2D GetArcCenter ( const VECTOR2D aStart,
const VECTOR2D aMid,
const VECTOR2D aEnd 
)

Definition at line 386 of file trigo.cpp.

387 {
388  VECTOR2D center;
389  double yDelta_21 = aMid.y - aStart.y;
390  double xDelta_21 = aMid.x - aStart.x;
391  double yDelta_32 = aEnd.y - aMid.y;
392  double xDelta_32 = aEnd.x - aMid.x;
393 
394  // This is a special case for aMid as the half-way point when aSlope = 0 and bSlope = inf
395  // or the other way around. In that case, the center lies in a straight line between
396  // aStart and aEnd
397  if( ( ( xDelta_21 == 0.0 ) && ( yDelta_32 == 0.0 ) ) ||
398  ( ( yDelta_21 == 0.0 ) && ( xDelta_32 == 0.0 ) ) )
399  {
400  center.x = ( aStart.x + aEnd.x ) / 2.0;
401  center.y = ( aStart.y + aEnd.y ) / 2.0 ;
402  return center;
403  }
404 
405  // Prevent div=0 errors
406  if( xDelta_21 == 0.0 )
407  xDelta_21 = std::numeric_limits<double>::epsilon();
408 
409  if( xDelta_32 == 0.0 )
410  xDelta_32 = -std::numeric_limits<double>::epsilon();
411 
412  double aSlope = yDelta_21 / xDelta_21;
413  double bSlope = yDelta_32 / xDelta_32;
414 
415  if( aSlope == bSlope )
416  {
417  if( aStart == aEnd )
418  {
419  // This is a special case for a 360 degrees arc. In this case, the center is halfway between
420  // the midpoint and either end point
421  center.x = ( aStart.x + aMid.x ) / 2.0;
422  center.y = ( aStart.y + aMid.y ) / 2.0 ;
423  return center;
424  }
425  else
426  {
427  // If the points are colinear, the center is at infinity, so offset
428  // the slope by a minimal amount
429  // Warning: This will induce a small error in the center location
430  aSlope += std::numeric_limits<double>::epsilon();
431  bSlope -= std::numeric_limits<double>::epsilon();
432  }
433  }
434 
435  // Prevent divide by zero error
436  if( aSlope == 0.0 )
437  aSlope = std::numeric_limits<double>::epsilon();
438 
439  center.x = ( aSlope * bSlope * ( aStart.y - aEnd.y ) +
440  bSlope * ( aStart.x + aMid.x ) -
441  aSlope * ( aMid.x + aEnd.x ) ) / ( 2 * ( bSlope - aSlope ) );
442 
443  center.y = ( ( ( aStart.x + aMid.x ) / 2.0 - center.x ) / aSlope +
444  ( aStart.y + aMid.y ) / 2.0 );
445 
446  return center;
447 }

References VECTOR2< T >::x, and VECTOR2< T >::y.

◆ GetArcCenter() [3/4]

const wxPoint GetArcCenter ( const wxPoint &  aStart,
const wxPoint &  aMid,
const wxPoint &  aEnd 
)

Definition at line 471 of file trigo.cpp.

472 {
473  VECTOR2D dStart( static_cast<double>( aStart.x ), static_cast<double>( aStart.y ) );
474  VECTOR2D dMid( static_cast<double>( aMid.x ), static_cast<double>( aMid.y ) );
475  VECTOR2D dEnd( static_cast<double>( aEnd.x ), static_cast<double>( aEnd.y ) );
476  VECTOR2D dCenter = GetArcCenter( dStart, dMid, dEnd );
477 
478  wxPoint iCenter;
479 
480  iCenter.x = KiROUND( Clamp<double>( double( std::numeric_limits<int>::min() / 2.0 ),
481  dCenter.x,
482  double( std::numeric_limits<int>::max() / 2.0 ) ) );
483 
484  iCenter.y = KiROUND( Clamp<double>( double( std::numeric_limits<int>::min() / 2.0 ),
485  dCenter.y,
486  double( std::numeric_limits<int>::max() / 2.0 ) ) );
487 
488  return iCenter;
489 }
const wxPoint GetArcCenter(VECTOR2I aStart, VECTOR2I aEnd, double aAngle)
Definition: trigo.cpp:361
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:68

References GetArcCenter(), KiROUND(), VECTOR2< T >::x, and VECTOR2< T >::y.

◆ GetArcCenter() [4/4]

const wxPoint GetArcCenter ( VECTOR2I  aStart,
VECTOR2I  aEnd,
double  aAngle 
)

Definition at line 361 of file trigo.cpp.

362 {
363  if( aAngle < 0 )
364  {
365  std::swap( aStart, aEnd );
366  aAngle = abs( aAngle );
367  }
368 
369  if( aAngle > 180 )
370  {
371  std::swap( aStart, aEnd );
372  aAngle = 360 - aAngle;
373  }
374 
375  int chord = ( aStart - aEnd ).EuclideanNorm();
376  int r = ( chord / 2 ) / sin( aAngle * M_PI / 360.0 );
377 
378  VECTOR2I vec = aEnd - aStart;
379  vec = vec.Resize( r );
380  vec = vec.Rotate( ( 180.0 - aAngle ) * M_PI / 360.0 );
381 
382  return (wxPoint) ( aStart + vec );
383 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:148
Define a general 2D-vector/point.
Definition: vector2d.h:61
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
Definition: vector2d.h:404
VECTOR2< T > Rotate(double aAngle) const
Rotate the vector by a given angle.
Definition: vector2d.h:371

References EuclideanNorm(), VECTOR2< T >::Resize(), and VECTOR2< T >::Rotate().

Referenced by GetArcAngle(), and GetArcCenter().

◆ GetArcMid()

const VECTOR2I GetArcMid ( const VECTOR2I aStart,
const VECTOR2I aEnd,
const VECTOR2I aCenter,
bool  aMinArcAngle = true 
)

Returns the middle point of an arc, half-way between aStart and aEnd.

There are two possible solutions which can be found by toggling aMinArcAngle. The behaviour is undefined for semicircles (i.e. 180 degree arcs).

Parameters
aStartThe starting point of the arc (for calculating the radius)
aEndThe end point of the arc (for determining the arc angle)
aCenterThe center point of the arc
aMinArcAngleIf true, returns the point that results in the smallest arc angle.
Returns
The middle point of the arc

Definition at line 162 of file trigo.cpp.

164 {
165  VECTOR2I startVector = aStart - aCenter;
166  VECTOR2I endVector = aEnd - aCenter;
167 
168  double startAngle = ArcTangente( startVector.y, startVector.x );
169  double endAngle = ArcTangente( endVector.y, endVector.x );
170  double midPointRotAngleDeciDeg = NormalizeAngle180( startAngle - endAngle ) / 2;
171 
172  if( !aMinArcAngle )
173  midPointRotAngleDeciDeg += 1800.0;
174 
175  VECTOR2I newMid = aStart;
176  RotatePoint( newMid, aCenter, midPointRotAngleDeciDeg );
177 
178  return newMid;
179 }
Define a general 2D-vector/point.
Definition: vector2d.h:61
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:228
T NormalizeAngle180(T Angle)
Normalize angle to be in the -180.0 .. 180.0 range.
Definition: trigo.h:376
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:182

References ArcTangente(), NormalizeAngle180(), RotatePoint(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by CIRCLE::ConstructFromTanTanPt(), and EDIT_TOOL::DragArcTrack().

◆ GetLineLength()

double GetLineLength ( const wxPoint &  aPointA,
const wxPoint &  aPointB 
)
inline

◆ HitTestPoints()

bool HitTestPoints ( const wxPoint &  pointA,
const wxPoint &  pointB,
double  threshold 
)
inline

Test, if two points are near each other.

Parameters
pointAFirst point
pointBSecond point
thresholdThe maximum distance
Returns
True or false

Definition at line 186 of file trigo.h.

187 {
188  wxPoint vectorAB = pointB - pointA;
189 
190  // Compare the distances squared. The double is needed to avoid
191  // overflow during int multiplication
192  double sqdistance = (double)vectorAB.x * vectorAB.x + (double)vectorAB.y * vectorAB.y;
193 
194  return sqdistance < threshold * threshold;
195 }

Referenced by LIB_ARC::HitTest(), GERBER_DRAW_ITEM::HitTest(), and EE_SELECTION_TOOL::narrowSelection().

◆ InterceptsNegativeX()

bool InterceptsNegativeX ( double  aStartAngle,
double  aEndAngle 
)
inline

Test if an arc from aStartAngle to aEndAngle crosses the negative X axis (180 degrees).

Testing is performed in the quadrant 1 to quadrant 4 direction (counter-clockwise).

Parameters
aStartAngleThe arc start angle in degrees.
aEndAngleThe arc end angle in degrees.

Definition at line 416 of file trigo.h.

417 {
418  double end = aEndAngle;
419 
420  if( aStartAngle > aEndAngle )
421  end += 360.0;
422 
423  return aStartAngle < 180.0 && end > 180.0;
424 }

Referenced by BOOST_AUTO_TEST_CASE().

◆ InterceptsPositiveX()

bool InterceptsPositiveX ( double  aStartAngle,
double  aEndAngle 
)
inline

Test if an arc from aStartAngle to aEndAngle crosses the positive X axis (0 degrees).

Testing is performed in the quadrant 1 to quadrant 4 direction (counter-clockwise).

Parameters
aStartAngleThe arc start angle in degrees.
aEndAngleThe arc end angle in degrees.

Definition at line 398 of file trigo.h.

399 {
400  double end = aEndAngle;
401 
402  if( aStartAngle > aEndAngle )
403  end += 360.0;
404 
405  return aStartAngle < 360.0 && end > 360.0;
406 }

Referenced by BOOST_AUTO_TEST_CASE().

◆ IsPointOnSegment()

bool IsPointOnSegment ( const wxPoint &  aSegStart,
const wxPoint &  aSegEnd,
const wxPoint &  aTestPoint 
)

Test if aTestPoint is on line defined by aSegStart and aSegEnd.

This function is faster than TestSegmentHit() because aTestPoint should be exactly on the line. This works fine only for H, V and 45 degree line segments.

Parameters
aSegStartThe first point of the line segment.
aSegEndThe second point of the line segment.
aTestPointThe point to test.
Returns
true if the point is on the line segment.

Definition at line 42 of file trigo.cpp.

44 {
45  wxPoint vectSeg = aSegEnd - aSegStart; // Vector from S1 to S2
46  wxPoint vectPoint = aTestPoint - aSegStart; // Vector from S1 to P
47 
48  // Use long long here to avoid overflow in calculations
49  if( (long long) vectSeg.x * vectPoint.y - (long long) vectSeg.y * vectPoint.x )
50  return false; /* Cross product non-zero, vectors not parallel */
51 
52  if( ( (long long) vectSeg.x * vectPoint.x + (long long) vectSeg.y * vectPoint.y ) <
53  ( (long long) vectPoint.x * vectPoint.x + (long long) vectPoint.y * vectPoint.y ) )
54  return false; /* Point not on segment */
55 
56  return true;
57 }

Referenced by SCH_LINE_WIRE_BUS_TOOL::AddJunctionsIfNeeded(), SCH_EDIT_FRAME::BreakSegments(), SCH_LINE_WIRE_BUS_TOOL::finishSegments(), SCH_EDIT_FRAME::TrimWire(), SCH_BUS_WIRE_ENTRY::UpdateDanglingState(), and SCH_BUS_BUS_ENTRY::UpdateDanglingState().

◆ NEGATE_AND_NORMALIZE_ANGLE_POS()

template<class T >
void NEGATE_AND_NORMALIZE_ANGLE_POS ( T &  Angle)
inline

Definition at line 353 of file trigo.h.

354 {
355  Angle = NegateAndNormalizeAnglePos( Angle );
356 }
T NegateAndNormalizeAnglePos(T Angle)
Definition: trigo.h:343

References NegateAndNormalizeAnglePos().

Referenced by CreateComponentsSection().

◆ NegateAndNormalizeAnglePos()

template<class T >
T NegateAndNormalizeAnglePos ( Angle)
inline

Definition at line 343 of file trigo.h.

344 {
345  Angle = -Angle;
346  while( Angle < 0 )
347  Angle += 3600;
348  while( Angle >= 3600 )
349  Angle -= 3600;
350  return Angle;
351 }

Referenced by NEGATE_AND_NORMALIZE_ANGLE_POS().

◆ NORMALIZE_ANGLE_180()

template<class T >
void NORMALIZE_ANGLE_180 ( T &  Angle)
inline

Definition at line 385 of file trigo.h.

386 {
387  Angle = NormalizeAngle180( Angle );
388 }
T NormalizeAngle180(T Angle)
Normalize angle to be in the -180.0 .. 180.0 range.
Definition: trigo.h:376

References NormalizeAngle180().

Referenced by HPGL_PLOTTER::Arc(), FOOTPRINT::Flip(), DIALOG_PAD_PROPERTIES::initValues(), CADSTAR_PCB_ARCHIVE_LOADER::loadComponents(), and FOOTPRINT::SetOrientation().

◆ NORMALIZE_ANGLE_90()

template<class T >
void NORMALIZE_ANGLE_90 ( T &  Angle)
inline

Definition at line 369 of file trigo.h.

370 {
371  Angle = NormalizeAngle90( Angle );
372 }
T NormalizeAngle90(T Angle)
Normalize angle to be in the -90.0 .. 90.0 range.
Definition: trigo.h:360

References NormalizeAngle90().

Referenced by GERBER_DRAW_ITEM::GetTextD_CodePrms().

◆ NORMALIZE_ANGLE_DEGREES_POS()

void NORMALIZE_ANGLE_DEGREES_POS ( double &  Angle)
inline

Definition at line 306 of file trigo.h.

307 {
308  Angle = NormalizeAngleDegreesPos( Angle );
309 }
double NormalizeAngleDegreesPos(double Angle)
Normalize angle to be in the 0.0 .
Definition: trigo.h:296

References NormalizeAngleDegreesPos().

Referenced by DSN::SPECCTRA_DB::FromBOARD(), and DSN::SPECCTRA_DB::makeIMAGE().

◆ NORMALIZE_ANGLE_POS()

◆ NormalizeAngle180()

template<class T >
T NormalizeAngle180 ( Angle)
inline

Normalize angle to be in the -180.0 .. 180.0 range.

Definition at line 376 of file trigo.h.

377 {
378  while( Angle <= -1800 )
379  Angle += 3600;
380  while( Angle > 1800 )
381  Angle -= 3600;
382  return Angle;
383 }

Referenced by DIALOG_COPPER_ZONE::AcceptOptions(), SEG::AngleDegrees(), ARC::GetAngle(), GetArcMid(), SHAPE_ARC::GetCentralAngle(), CADSTAR_SCH_ARCHIVE_LOADER::getComponentOrientation(), CADSTAR_SCH_ARCHIVE_LOADER::getSpinStyleDeciDeg(), CADSTAR_SCH_ARCHIVE_LOADER::loadSchematicSymbol(), CADSTAR_SCH_ARCHIVE_LOADER::loadSymDefIntoLibrary(), NORMALIZE_ANGLE_180(), and SHAPE_ARC::SHAPE_ARC().

◆ NormalizeAngle360Max()

template<class T >
T NormalizeAngle360Max ( Angle)
inline

Normalize angle to be >=-360.0 and <= 360.0 Angle can be equal to -360 or +360.

Definition at line 243 of file trigo.h.

244 {
245  while( Angle < -3600 )
246  Angle += 3600;
247  while( Angle > 3600 )
248  Angle -= 3600;
249  return Angle;
250 }

Referenced by PCB_SHAPE::SetAngle().

◆ NormalizeAngle360Min()

template<class T >
T NormalizeAngle360Min ( Angle)
inline

Normalize angle to be > -360.0 and < 360.0 Angle equal to -360 or +360 are set to 0.

Definition at line 254 of file trigo.h.

255 {
256  while( Angle <= -3600 )
257  Angle += 3600;
258  while( Angle >= 3600 )
259  Angle -= 3600;
260  return Angle;
261 }

Referenced by PCB_IO::format(), PAD::Rotate(), PCB_TEXT::SetTextAngle(), FP_TEXT::SetTextAngle(), and DS_DRAW_ITEM_TEXT::SetTextAngle().

◆ NormalizeAngle90()

template<class T >
T NormalizeAngle90 ( Angle)
inline

Normalize angle to be in the -90.0 .. 90.0 range.

Definition at line 360 of file trigo.h.

361 {
362  while( Angle < -900 )
363  Angle += 1800;
364  while( Angle > 900 )
365  Angle -= 1800;
366  return Angle;
367 }

Referenced by NORMALIZE_ANGLE_90().

◆ NormalizeAngleDegrees()

double NormalizeAngleDegrees ( double  Angle,
double  aMin,
double  aMax 
)
inline

Normalize angle to be aMin < angle <= aMax angle is in degrees.

Definition at line 323 of file trigo.h.

324 {
325  while( Angle < aMin )
326  Angle += 360.0;
327  while( Angle >= aMax )
328  Angle -= 360.0;
329  return Angle;
330 }

Referenced by SHAPE_ARC::GetEndAngle(), PAD::GetMsgPanelInfo(), SHAPE_ARC::GetStartAngle(), and ALTIUM_PCB::ParseComponentsBodies6Data().

◆ NormalizeAngleDegreesPos()

double NormalizeAngleDegreesPos ( double  Angle)
inline

Normalize angle to be in the 0.0 .

. 360.0 range: angle is in degrees

Definition at line 296 of file trigo.h.

297 {
298  while( Angle < 0 )
299  Angle += 360.0;
300  while( Angle >= 360.0 )
301  Angle -= 360.0;
302  return Angle;
303 }

Referenced by SHAPE_ARC::Collide(), ALTIUM_PCB::HelperCreateBoardOutline(), HelperShapeLineChainFromAltiumVertices(), NORMALIZE_ANGLE_DEGREES_POS(), ALTIUM_PCB::ParseArcs6Data(), and ALTIUM_PCB::ParsePads6Data().

◆ NormalizeAngleNeg()

template<class T >
T NormalizeAngleNeg ( Angle)
inline

Normalize angle to be in the 0.0 .

. -360.0 range: angle is in 1/10 degrees

Definition at line 267 of file trigo.h.

268 {
269  while( Angle <= -3600 )
270  Angle += 3600;
271  while( Angle > 0 )
272  Angle -= 3600;
273  return Angle;
274 }

Referenced by CADSTAR_PCB_ARCHIVE_LOADER::getDrawSegmentFromVertex(), and CADSTAR_SCH_ARCHIVE_LOADER::loadShapeVertices().

◆ NormalizeAnglePos()

template<class T >
T NormalizeAnglePos ( Angle)
inline

◆ NormalizeAngleRadiansPos()

double NormalizeAngleRadiansPos ( double  Angle)
inline

Definition at line 312 of file trigo.h.

313 {
314  while( Angle < 0 )
315  Angle += (2 * M_PI );
316  while( Angle >= ( 2 * M_PI ) )
317  Angle -= ( 2 * M_PI );
318  return Angle;
319 }

Referenced by GERBER_DRAW_ITEM::HitTest().

◆ RAD2DECIDEG()

◆ RAD2DEG()

◆ RotatePoint() [1/8]

void RotatePoint ( int *  pX,
int *  pY,
double  angle 
)

Definition at line 228 of file trigo.cpp.

229 {
230  int tmp;
231 
233 
234  // Cheap and dirty optimizations for 0, 90, 180, and 270 degrees.
235  if( angle == 0 )
236  return;
237 
238  if( angle == 900 ) /* sin = 1, cos = 0 */
239  {
240  tmp = *pX;
241  *pX = *pY;
242  *pY = -tmp;
243  }
244  else if( angle == 1800 ) /* sin = 0, cos = -1 */
245  {
246  *pX = -*pX;
247  *pY = -*pY;
248  }
249  else if( angle == 2700 ) /* sin = -1, cos = 0 */
250  {
251  tmp = *pX;
252  *pX = -*pY;
253  *pY = tmp;
254  }
255  else
256  {
257  double fangle = DECIDEG2RAD( angle );
258  double sinus = sin( fangle );
259  double cosinus = cos( fangle );
260  double fpx = (*pY * sinus ) + (*pX * cosinus );
261  double fpy = (*pY * cosinus ) - (*pX * sinus );
262  *pX = KiROUND( fpx );
263  *pY = KiROUND( fpy );
264  }
265 }
void NORMALIZE_ANGLE_POS(T &Angle)
Definition: trigo.h:288
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
double DECIDEG2RAD(double deg)
Definition: trigo.h:235
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:68

References PNS::angle(), DECIDEG2RAD(), KiROUND(), and NORMALIZE_ANGLE_POS().

Referenced by CADSTAR_PCB_ARCHIVE_LOADER::addAttribute(), PCAD2KICAD::PCB_FOOTPRINT::AddToBoard(), PCAD2KICAD::PCB_PAD::AddToFootprint(), CADSTAR_SCH_ARCHIVE_LOADER::applyTransform(), SVG_PLOTTER::Arc(), BuildConvexHull(), BuildCornersList_S_Shape(), PAD::BuildEffectiveShapes(), LIB_ARC::CalcEdit(), PCB_SHAPE::computeArcBBox(), PSLIKE_PLOTTER::computeTextParameters(), SHAPE_ARC::ConstructFromStartEndAngle(), ConvertOutlineToPolygon(), AM_PRIMITIVE::ConvertShapeToPolygon(), D_CODE::ConvertShapeToPolygon(), PCAD2KICAD::CorrectTextPosition(), EXCELLON_WRITER::createDrillFile(), MICROWAVE_TOOL::createFootprint(), SCH_GLOBALLABEL::CreateGraphicShape(), AM_PRIMITIVE::DrawBasicShape(), CADSTAR_PCB_ARCHIVE_LOADER::drawCadstarText(), DrawHalfOpenCylinder(), AR_MATRIX::drawSegmentQcq(), GBR_TO_PCB_EXPORTER::export_segarc_copper_item(), EXPORTER_PCB_VRML::ExportVrmlFootprint(), fillArcPOLY(), CADSTAR_ARCHIVE_PARSER::FixTextPositionNoAlignment(), GERBER_PLOTTER::FlashPadChamferRoundRect(), GERBER_PLOTTER::FlashPadCustom(), PSLIKE_PLOTTER::FlashPadOval(), HPGL_PLOTTER::FlashPadOval(), PSLIKE_PLOTTER::FlashPadRect(), DXF_PLOTTER::FlashPadRect(), HPGL_PLOTTER::FlashPadRect(), PSLIKE_PLOTTER::FlashPadTrapez(), DXF_PLOTTER::FlashPadTrapez(), HPGL_PLOTTER::FlashPadTrapez(), GERBER_PLOTTER::FlashPadTrapez(), GERBER_PLOTTER::FlashRegularPolygon(), FootprintWriteShape(), geom_transf(), GERBER_DRAW_ITEM::GetABPosition(), CN_ITEM::GetAnchor(), GetArcAngle(), GetArcMid(), PCB_SHAPE::GetArcMid(), LIB_TEXT::GetBoundingBox(), SCH_FIELD::GetBoundingBox(), LIB_FIELD::GetBoundingBox(), LIB_PIN::GetBoundingBox(), SCH_TEXT::GetBoundingBox(), PCB_SHAPE::GetBoundingBox(), SCH_LABEL::GetBoundingBox(), EDA_RECT::GetBoundingBoxRotated(), DS_DATA_ITEM_POLYGONS::GetCornerPosition(), CADSTAR_PCB_ARCHIVE_LOADER::getKiCadPad(), EDA_TEXT::GetLinePositions(), CADSTAR_SCH_ARCHIVE_LOADER::getLocationOfNetElement(), PCB_SHAPE::GetRectCorners(), ARRAY_CIRCULAR_OPTIONS::GetTransform(), GERBER_DRAW_ITEM::GetXYPosition(), GRArc(), GRCSegm(), GRFilledArc(), ALTIUM_PCB::HelperParseDimensions6Center(), ALTIUM_PCB::HelperParseDimensions6Leader(), idf_export_footprint(), RENDER_3D_RAYTRACE::insertHole(), EDA_RECT::Intersects(), SCH_LEGACY_PLUGIN_CACHE::loadArc(), LEGACY_PLUGIN::loadPAD(), EAGLE_PLUGIN::loadPlain(), CADSTAR_SCH_ARCHIVE_LOADER::loadSchematicSymbolInstances(), CADSTAR_SCH_ARCHIVE_LOADER::loadSymDefIntoLibrary(), FOOTPRINT::MoveAnchorPosition(), EAGLE_PLUGIN::packageCircle(), ALTIUM_PCB::ParseComponentsBodies6Data(), GPCB_FPL_CACHE::parseFOOTPRINT(), PCB_PARSER::parseFOOTPRINT_unchecked(), BRDITEMS_PLOTTER::PlotFootprintGraphicItem(), GERBER_PLOTTER::plotRoundRectAsRegion(), FABMASTER::processArc(), SCH_JUNCTION::Rotate(), LIB_RECTANGLE::Rotate(), LIB_ARC::Rotate(), LIB_CIRCLE::Rotate(), LIB_BEZIER::Rotate(), PCB_TARGET::Rotate(), SCH_NO_CONNECT::Rotate(), PCB_TEXT::Rotate(), LIB_POLYLINE::Rotate(), SCH_BUS_ENTRY_BASE::Rotate(), LIB_TEXT::Rotate(), TRACK::Rotate(), FP_TEXT::Rotate(), SCH_BITMAP::Rotate(), SCH_FIELD::Rotate(), SCH_SHEET_PIN::Rotate(), SCH_LINE::Rotate(), LIB_FIELD::Rotate(), LIB_PIN::Rotate(), DIMENSION_BASE::Rotate(), FOOTPRINT::Rotate(), SCH_TEXT::Rotate(), ARC::Rotate(), PCB_SHAPE::Rotate(), SCH_SHEET::Rotate(), SCH_GLOBALLABEL::Rotate(), ZONE::Rotate(), SCH_COMPONENT::Rotate(), PAD::Rotate(), SCH_GLOBALLABEL::Rotate90(), SCH_LINE::RotateEnd(), RotatePoint(), SCH_LINE::RotateStart(), FP_SHAPE::SetAngle(), PCB_SHAPE::SetAngle(), DS_DATA_ITEM_POLYGONS::SetBoundingBox(), FP_SHAPE::SetDrawCoord(), FP_TEXT::SetDrawCoord(), PAD::SetDrawCoord(), FP_SHAPE::SetLocalCoord(), FP_TEXT::SetLocalCoord(), PAD::SetLocalCoord(), SHAPE_ARC::SHAPE_ARC(), PAD::ShapePos(), PLOTTER::sketchOval(), PNS_KICAD_IFACE_BASE::syncPad(), FP_TEXT::TextHitTest(), EDA_TEXT::TextHitTest(), AR_MATRIX::TraceFilledRectangle(), DIALOG_PAD_PROPERTIES::TransferDataFromWindow(), EAGLE_PLUGIN::transferPad(), BOARD_ADAPTER::transformArcToSegments(), EDA_TEXT::TransformBoundingBoxWithClearanceToPolygon(), TransformCircleToPolygon(), TransformOvalToPolygon(), TransformRoundRectToPolygon(), PCB_SHAPE::TransformShapeWithClearanceToPolygon(), PAD::TransformShapeWithClearanceToPolygon(), PCB_POINT_EDITOR::updateItem(), and GERBER_PLOTTER::writeApertureList().

◆ RotatePoint() [2/8]

void RotatePoint ( int *  pX,
int *  pY,
int  cx,
int  cy,
double  angle 
)

Definition at line 268 of file trigo.cpp.

269 {
270  int ox, oy;
271 
272  ox = *pX - cx;
273  oy = *pY - cy;
274 
275  RotatePoint( &ox, &oy, angle );
276 
277  *pX = ox + cx;
278  *pY = oy + cy;
279 }
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:228
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)

References PNS::angle(), and RotatePoint().

◆ RotatePoint() [3/8]

void RotatePoint ( wxPoint *  point,
double  angle 
)
inline

Definition at line 81 of file trigo.h.

82 {
83  RotatePoint( &point->x, &point->y, angle );
84 }
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:228
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)

References PNS::angle(), and RotatePoint().

◆ RotatePoint() [4/8]

void RotatePoint ( VECTOR2I point,
double  angle 
)
inline

Definition at line 86 of file trigo.h.

87 {
88  RotatePoint( &point.x, &point.y, angle );
89 }
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:228
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)

References PNS::angle(), RotatePoint(), VECTOR2< T >::x, and VECTOR2< T >::y.

◆ RotatePoint() [5/8]

void RotatePoint ( VECTOR2I point,
const VECTOR2I centre,
double  angle 
)

Definition at line 294 of file trigo.cpp.

295 {
296  wxPoint c( centre.x, centre.y );
297  wxPoint p( point.x, point.y );
298 
299  RotatePoint(&p, c, angle);
300 
301  point.x = p.x;
302  point.y = p.y;
303 }
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:228
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)

References PNS::angle(), RotatePoint(), VECTOR2< T >::x, and VECTOR2< T >::y.

◆ RotatePoint() [6/8]

void RotatePoint ( wxPoint *  point,
const wxPoint &  centre,
double  angle 
)

Definition at line 282 of file trigo.cpp.

283 {
284  int ox, oy;
285 
286  ox = point->x - centre.x;
287  oy = point->y - centre.y;
288 
289  RotatePoint( &ox, &oy, angle );
290  point->x = ox + centre.x;
291  point->y = oy + centre.y;
292 }
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:228
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)

References PNS::angle(), and RotatePoint().

◆ RotatePoint() [7/8]

void RotatePoint ( double *  pX,
double *  pY,
double  angle 
)

Definition at line 320 of file trigo.cpp.

321 {
322  double tmp;
323 
325 
326  // Cheap and dirty optimizations for 0, 90, 180, and 270 degrees.
327  if( angle == 0 )
328  return;
329 
330  if( angle == 900 ) /* sin = 1, cos = 0 */
331  {
332  tmp = *pX;
333  *pX = *pY;
334  *pY = -tmp;
335  }
336  else if( angle == 1800 ) /* sin = 0, cos = -1 */
337  {
338  *pX = -*pX;
339  *pY = -*pY;
340  }
341  else if( angle == 2700 ) /* sin = -1, cos = 0 */
342  {
343  tmp = *pX;
344  *pX = -*pY;
345  *pY = tmp;
346  }
347  else
348  {
349  double fangle = DECIDEG2RAD( angle );
350  double sinus = sin( fangle );
351  double cosinus = cos( fangle );
352 
353  double fpx = (*pY * sinus ) + (*pX * cosinus );
354  double fpy = (*pY * cosinus ) - (*pX * sinus );
355  *pX = fpx;
356  *pY = fpy;
357  }
358 }
void NORMALIZE_ANGLE_POS(T &Angle)
Definition: trigo.h:288
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
double DECIDEG2RAD(double deg)
Definition: trigo.h:235

References PNS::angle(), DECIDEG2RAD(), and NORMALIZE_ANGLE_POS().

◆ RotatePoint() [8/8]

void RotatePoint ( double *  pX,
double *  pY,
double  cx,
double  cy,
double  angle 
)

Definition at line 306 of file trigo.cpp.

307 {
308  double ox, oy;
309 
310  ox = *pX - cx;
311  oy = *pY - cy;
312 
313  RotatePoint( &ox, &oy, angle );
314 
315  *pX = ox + cx;
316  *pY = oy + cy;
317 }
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:228
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)

References PNS::angle(), and RotatePoint().

◆ SegmentIntersectsSegment()

bool SegmentIntersectsSegment ( const wxPoint &  a_p1_l1,
const wxPoint &  a_p2_l1,
const wxPoint &  a_p1_l2,
const wxPoint &  a_p2_l2,
wxPoint *  aIntersectionPoint = nullptr 
)

Test if two lines intersect.

Parameters
a_p1_l1The first point of the first line.
a_p2_l1The second point of the first line.
a_p1_l2The first point of the second line.
a_p2_l2The second point of the second line.
aIntersectionPointis filled with the intersection point if it exists
Returns
bool - true if the two segments defined by four points intersect. (i.e. if the 2 segments have at least a common point)

Definition at line 61 of file trigo.cpp.

64 {
65 
66  //We are forced to use 64bit ints because the internal units can overflow 32bit ints when
67  // multiplied with each other, the alternative would be to scale the units down (i.e. divide
68  // by a fixed number).
69  int64_t dX_a, dY_a, dX_b, dY_b, dX_ab, dY_ab;
70  int64_t num_a, num_b, den;
71 
72  //Test for intersection within the bounds of both line segments using line equations of the
73  // form:
74  // x_k(u_k) = u_k * dX_k + x_k(0)
75  // y_k(u_k) = u_k * dY_k + y_k(0)
76  // with 0 <= u_k <= 1 and k = [ a, b ]
77 
78  dX_a = int64_t{ a_p2_l1.x } - a_p1_l1.x;
79  dY_a = int64_t{ a_p2_l1.y } - a_p1_l1.y;
80  dX_b = int64_t{ a_p2_l2.x } - a_p1_l2.x;
81  dY_b = int64_t{ a_p2_l2.y } - a_p1_l2.y;
82  dX_ab = int64_t{ a_p1_l2.x } - a_p1_l1.x;
83  dY_ab = int64_t{ a_p1_l2.y } - a_p1_l1.y;
84 
85  den = dY_a * dX_b - dY_b * dX_a ;
86 
87  //Check if lines are parallel
88  if( den == 0 )
89  return false;
90 
91  num_a = dY_ab * dX_b - dY_b * dX_ab;
92  num_b = dY_ab * dX_a - dY_a * dX_ab;
93 
94  // Only compute the intersection point if requested
95  if( aIntersectionPoint )
96  {
97  *aIntersectionPoint = a_p1_l1;
98  aIntersectionPoint->x += KiROUND( dX_a * ( double )num_a / ( double )den );
99  aIntersectionPoint->y += KiROUND( dY_a * ( double )num_b / ( double )den );
100  }
101 
102  if( den < 0 )
103  {
104  den = -den;
105  num_a = -num_a;
106  num_b = -num_b;
107  }
108 
109  //Test sign( u_a ) and return false if negative
110  if( num_a < 0 )
111  return false;
112 
113  //Test sign( u_b ) and return false if negative
114  if( num_b < 0 )
115  return false;
116 
117  //Test to ensure (u_a <= 1)
118  if( num_a > den )
119  return false;
120 
121  //Test to ensure (u_b <= 1)
122  if( num_b > den )
123  return false;
124 
125  return true;
126 }
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:68

References KiROUND().

Referenced by EDA_RECT::Intersects().

◆ sindecideg()

double sindecideg ( double  r,
double  a 
)
inline

Circle generation utility: computes r * sin(a) Where a is in decidegrees, not in radians.

Definition at line 430 of file trigo.h.

431 {
432  return r * sin( DECIDEG2RAD( a ) );
433 }
double DECIDEG2RAD(double deg)
Definition: trigo.h:235

References DECIDEG2RAD().

Referenced by HPGL_PLOTTER::Arc(), PLOTTER::Arc(), PDF_PLOTTER::Arc(), PCAD2KICAD::PCB_ARC::Parse(), GERBER_PLOTTER::plotArc(), GERBER_PLOTTER::plotRoundRectAsRegion(), and AR_MATRIX::traceCircle().

◆ TestSegmentHit()

bool TestSegmentHit ( const wxPoint &  aRefPoint,
wxPoint  aStart,
wxPoint  aEnd,
int  aDist 
)

Test if aRefPoint is with aDistance on the line defined by aStart and aEnd.

Parameters
aRefPoint= reference point to test
aStartis the first end-point of the line segment
aEndis the second end-point of the line segment
aDist= maximum distance for hit

Definition at line 129 of file trigo.cpp.

130 {
131  int xmin = aStart.x;
132  int xmax = aEnd.x;
133  int ymin = aStart.y;
134  int ymax = aEnd.y;
135  wxPoint delta = aStart - aRefPoint;
136 
137  if( xmax < xmin )
138  std::swap( xmax, xmin );
139 
140  if( ymax < ymin )
141  std::swap( ymax, ymin );
142 
143  // First, check if we are outside of the bounding box
144  if( ( ymin - aRefPoint.y > aDist ) || ( aRefPoint.y - ymax > aDist ) )
145  return false;
146 
147  if( ( xmin - aRefPoint.x > aDist ) || ( aRefPoint.x - xmax > aDist ) )
148  return false;
149 
150  // Next, eliminate easy cases
151  if( aStart.x == aEnd.x && aRefPoint.y > ymin && aRefPoint.y < ymax )
152  return std::abs( delta.x ) <= aDist;
153 
154  if( aStart.y == aEnd.y && aRefPoint.x > xmin && aRefPoint.x < xmax )
155  return std::abs( delta.y ) <= aDist;
156 
157  SEG segment( aStart, aEnd );
158  return segment.SquaredDistance( aRefPoint ) < SEG::Square( aDist + 1 );
159 }
static SEG::ecoord Square(int a)
Definition: seg.h:123
Definition: seg.h:41

References SEG::Square(), and SEG::SquaredDistance().

Referenced by SCH_EAGLE_PLUGIN::addBusEntries(), EE_GRID_HELPER::computeAnchors(), DRAWING_TOOL::DrawVia(), LIB_RECTANGLE::HitTest(), LIB_BEZIER::HitTest(), SCH_BUS_ENTRY_BASE::HitTest(), DS_DRAW_ITEM_LINE::HitTest(), TRACK::HitTest(), GERBER_DRAW_ITEM::HitTest(), SCH_LINE::HitTest(), DS_DRAW_ITEM_RECT::HitTest(), PCB_SHAPE::HitTest(), SCH_EAGLE_PLUGIN::moveLabels(), and SCH_TEXT::UpdateDanglingState().