KiCad PCB EDA Suite
util.h File Reference
#include <config.h>
#include <cmath>
#include <cstdint>
#include <limits>
#include <typeinfo>
#include <type_traits>

Go to the source code of this file.

Functions

void kimathLogDebug (const char *aFormatString,...)
 Helper to avoid directly including wx/log.h for the templated functions in kimath. More...
 
template<typename T >
constexpr T Clamp (const T &lower, const T &value, const T &upper)
 Limit value within the range lower <= value <= upper. More...
 
template<typename fp_type , typename ret_type = int>
constexpr ret_type KiROUND (fp_type v)
 Round a floating point number to an integer using "round halfway cases away from zero". More...
 
template<typename T >
rescale (T aNumerator, T aValue, T aDenominator)
 Scale a number (value) by rational (numerator/denominator). More...
 
template<typename T >
int sign (T val)
 
template<>
int rescale (int aNumerator, int aValue, int aDenominator)
 
template<>
int64_t rescale (int64_t aNumerator, int64_t aValue, int64_t aDenominator)
 
template<class T >
std::enable_if< std::is_floating_point< T >::value, bool >::type equals (T aFirst, T aSecond, T aEpsilon=std::numeric_limits< T >::epsilon())
 Template to compare two floating point values for equality within a required epsilon. More...
 

Function Documentation

◆ Clamp()

template<typename T >
constexpr T Clamp ( const T &  lower,
const T &  value,
const T &  upper 
)
inlineconstexpr

Limit value within the range lower <= value <= upper.

It will work on temporary expressions, since they are evaluated only once, and it should work on most if not all numeric types, string types, or any type for which "operator < ()" is present. The arguments are accepted in this order so you can remember the expression as a memory aid:

result is: lower <= value <= upper

Definition at line 59 of file util.h.

60{
61 if( value < lower )
62 return lower;
63 else if( upper < value )
64 return upper;
65 return value;
66}

Referenced by LSET::AllCuMask(), SIM_PLOT_FRAME::applyTuners(), DIALOG_PAGES_SETTINGS::GetCustomSizeMilsFromDialog(), SCH_SEXPR_PARSER::parseEDA_TEXT(), SCH_SEXPR_PARSER::parseFill(), SCH_SEXPR_PARSER::parseJunction(), STROKE_PARAMS_PARSER::ParseStroke(), DRAWING_SHEET_PARSER::parseText(), BRDITEMS_PLOTTER::plotOneDrillMark(), PCB_PLOT_PARAMS::SetSvgPrecision(), and DIALOG_PAGES_SETTINGS::UpdateDrawingSheetExample().

◆ equals()

template<class T >
std::enable_if< std::is_floating_point< T >::value, bool >::type equals ( aFirst,
aSecond,
aEpsilon = std::numeric_limits<T>::epsilon() 
)

Template to compare two floating point values for equality within a required epsilon.

Parameters
aFirstvalue to compare.
aSecondvalue to compare.
aEpsilonallowed error.
Returns
true if the values considered equal within the specified epsilon, otherwise false.

Definition at line 134 of file util.h.

135{
136 T diff = std::abs( aFirst - aSecond );
137
138 if( diff < aEpsilon )
139 {
140 return true;
141 }
142
143 aFirst = std::abs( aFirst );
144 aSecond = std::abs( aSecond );
145 T largest = aFirst > aSecond ? aFirst : aSecond;
146
147 if( diff <= largest * aEpsilon )
148 {
149 return true;
150 }
151
152 return false;
153}
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:401

References std::abs().

◆ kimathLogDebug()

void kimathLogDebug ( const char *  aFormatString,
  ... 
)

Helper to avoid directly including wx/log.h for the templated functions in kimath.

Definition at line 43 of file util.cpp.

44{
45 if( wxLog::IsLevelEnabled( wxLOG_Debug, wxString::FromAscii( wxLOG_COMPONENT ) ) )
46 {
47 va_list argList;
48 va_start( argList, aFormatString );
49
50 wxVLogWarning( aFormatString, argList );
51
52 va_end( argList );
53 }
54}

Referenced by KiROUND(), and rescale().

◆ KiROUND()

template<typename fp_type , typename ret_type = int>
constexpr ret_type KiROUND ( fp_type  v)
constexpr

Round a floating point number to an integer using "round halfway cases away from zero".

In Debug build an assert fires if will not fit into the return type.

Definition at line 80 of file util.h.

81{
82 using max_ret = long long int;
83 fp_type ret = v < 0 ? v - 0.5 : v + 0.5;
84
85 if( std::numeric_limits<ret_type>::max() < ret ||
86 std::numeric_limits<ret_type>::lowest() > ret )
87 {
88 kimathLogDebug( "Overflow KiROUND converting value %f to %s", double( v ),
89 typeid( ret_type ).name() );
90 return 0;
91 }
92
93 return ret_type( max_ret( ret ) );
94}
const char * name
Definition: DXF_plotter.cpp:56
void kimathLogDebug(const char *aFormatString,...)
Helper to avoid directly including wx/log.h for the templated functions in kimath.
Definition: util.cpp:43

References kimathLogDebug(), and name.

Referenced by CADSTAR_PCB_ARCHIVE_LOADER::addAttribute(), ZONE_FILLER::addHatchFillTypeOnZone(), PCAD2KICAD::PCB_POLYGON::AddToBoard(), GRID_HELPER::AlignGrid(), PCB_GRID_HELPER::AlignToArc(), Altium2KiCadUnit(), CADSTAR_PCB_ARCHIVE_LOADER::applyDimensionSettings(), CADSTAR_SCH_ARCHIVE_LOADER::applyTextSettings(), CADSTAR_SCH_ARCHIVE_LOADER::applyTransform(), HPGL_PLOTTER::Arc(), PDF_PLOTTER::Arc(), PLOTTER::Arc(), EDA_ANGLE::AsTenthsOfADegree(), SCH_DIRECTIVE_LABEL::AutoplaceFields(), SCH_SHEET::AutoplaceFields(), PCB_GRID_HELPER::BestSnapAnchor(), LEGACY_PLUGIN::biuParse(), BuildCornersList_S_Shape(), PAD::BuildEffectivePolygon(), DIRECTION_45::BuildInitialTrace(), ZONE_FILLER::buildThermalSpokes(), CalcArcCenter(), EDA_SHAPE::calcEdit(), PCAD2KICAD::CalculateTextLengthSize(), KIGFX::WX_VIEW_CONTROLS::CenterOnCursor(), SHAPE_POLY_SET::chamferFilletPolygon(), EE_INSPECTION_TOOL::CheckSymbol(), CircleToEndSegmentDeltaRadius(), Clamp_Text_PenSize(), EE_SELECTION_TOOL::CollectHits(), SCH_LINE_WIRE_BUS_TOOL::computeBreakPoint(), computeCenter(), ConfigureHPGLPenSizes(), ALTIUM_PCB::ConvertArcs6ToBoardItemOnLayer(), ALTIUM_PCB::ConvertArcs6ToPcbShape(), ConvertArcToPolyline(), convertPolygon(), AM_PRIMITIVE::ConvertShapeToPolygon(), ALTIUM_PARSER::ConvertToKicadUnit(), SHAPE_ARC::ConvertToPolyline(), PCAD2KICAD::CorrectTextPosition(), FOOTPRINT::CoverageRatio(), SCH_DIRECTIVE_LABEL::CreateGraphicShape(), MICROWAVE_TOOL::createMicrowaveInductor(), MICROWAVE_TOOL::createPolygonShape(), BOARD_ADAPTER::createTrack(), SCH_EDIT_TOOL::DeleteItemCursor(), PL_EDIT_TOOL::DeleteItemCursor(), PCB_CONTROL::DeleteItemCursor(), EDIT_TOOL::DragArcTrack(), KIGFX::SCH_PAINTER::draw(), KIGFX::PCB_PAINTER::draw(), KIGFX::OPENGL_GAL::DrawArcSegment(), AM_PRIMITIVE::DrawBasicShape(), BITMAP_BASE::DrawBitmap(), KIGFX::OPENGL_GAL::drawBitmapChar(), CADSTAR_PCB_ARCHIVE_LOADER::drawCadstarText(), KIGFX::CAIRO_GAL_BASE::DrawGrid(), KIGFX::OPENGL_GAL::DrawGrid(), GERBER_PLOTTER::emitDcode(), PCB_EXPR_EVALUATOR::Evaluate(), GERBER_FILE_IMAGE::ExecuteRS274XCommand(), EDIT_POINTS::FindPoint(), HPGL_PLOTTER::FlashPadCircle(), HPGL_PLOTTER::FlashPadOval(), HPGL_PLOTTER::FlashPadRect(), HPGL_PLOTTER::FlashPadRoundRect(), FootprintWriteShape(), DS_DATA_MODEL_IO::format(), EDA_TEXT::Format(), STROKE_PARAMS::Format(), formatFill(), BM2CMP_FRAME::FormatOutputSize(), gen_arc(), GENDRILL_WRITER_BASE::genDrillMapFile(), RENDER_3D_OPENGL::generate3dGrid(), WX_HTML_REPORT_BOX::generateHtml(), GERBER_DRAW_ITEM::GetABPosition(), SCH_LINE::GetAngleFrom(), GetArcToSegmentCount(), CADSTAR_SCH_ARCHIVE_LOADER::getCadstarAngle(), GetClampedCoords(), FOOTPRINT::GetCoverageArea(), DIALOG_PAGES_SETTINGS::GetCustomSizeMilsFromDialog(), DS_DATA_ITEM::GetEndPosUi(), GRID_HELPER::GetGrid(), KIGFX::GAL::GetGridPoint(), getGUIFont(), EDA_TEXT::GetInterline(), GetKnockoutTextMargin(), SCH_LABEL_BASE::GetLabelBoxExpansion(), EDA_DRAW_FRAME::GetNearestGridPosition(), EDA_DRAW_FRAME::GetNearestHalfGridPosition(), EE_SELECTION_TOOL::GetNode(), IMAGE_SIZE::GetOutputDPI(), GetPenSizeForBold(), GetPenSizeForNormal(), DS_DATA_ITEM::GetPenSizeUi(), DS_DATA_ITEM_POLYGONS::GetPenSizeUi(), DS_DATA_ITEM_TEXT::GetPenSizeUi(), EDA_SHAPE::GetRadius(), SCH_LINE::GetReverseAngleFrom(), PAD::GetRoundRectCornerRadius(), BITMAP_BASE::GetSize(), PAD::GetSolderPasteMargin(), DS_DATA_ITEM::GetStartPosUi(), KIFONT::OUTLINE_FONT::getTextAsGlyphs(), KIFONT::OUTLINE_FONT::GetTextAsGlyphs(), KIFONT::STROKE_FONT::GetTextAsGlyphs(), EDA_TEXT::GetTextBox(), CADSTAR_SCH_ARCHIVE_LOADER::getTextHeightFromTextCode(), LIB_TEXTBOX::GetTextMargin(), SCH_TEXTBOX::GetTextMargin(), FP_TEXTBOX::GetTextMargin(), PCB_TEXTBOX::GetTextMargin(), SCH_TEXT::GetTextOffset(), GERBER_DRAW_ITEM::GetXYPosition(), GraphicTextWidth(), EE_SELECTION_TOOL::GuessSelectionCandidates(), ZONE::HatchBorder(), ALTIUM_PCB::HelperParseDimensions6Leader(), HelperShapeLineChainFromAltiumVertices(), DIALOG_PLOT::init_Dialog(), initializePlotter(), GENERAL_COLLECTOR::Inspect(), CIRCLE::Intersect(), CN_ANCHOR::IsDangling(), PCB_TRACK::IsPointOnEnds(), iu_to_d356(), KiScaledBitmap(), EAGLE_PLUGIN::Load(), CADSTAR_SCH_ARCHIVE_LOADER::loadDocumentationSymbols(), SCH_EAGLE_PLUGIN::loadFrame(), CADSTAR_SCH_ARCHIVE_LOADER::loadGraphicStaightSegment(), SCH_EAGLE_PLUGIN::loadLabel(), EAGLE_PLUGIN::loadPlain(), EAGLE_PLUGIN::loadPolygon(), EAGLE_PLUGIN::loadSignals(), CADSTAR_SCH_ARCHIVE_LOADER::loadSymbolFieldAttribute(), PCB_SELECTION_TOOL::Main(), DSN::SPECCTRA_DB::makePADSTACK(), GRAPHICS_IMPORTER_PCBNEW::MapCoordinate(), PLOTTER::markerSquare(), EDA_UNIT_UTILS::Mils2mm(), GERBVIEW_PRINTOUT::milsToIU(), PCBNEW_PRINTOUT::milsToIU(), EDA_UNIT_UTILS::Mm2mils(), ACTION_TOOLBAR::OnCustomRender(), DIALOG_POSITION_RELATIVE::OnOkClick(), BM2CMP_FRAME::OpenProjectFiles(), VECTOR2< T >::operator/(), EAGLE_PLUGIN::orientFPText(), EAGLE_PLUGIN::packagePad(), EAGLE_PLUGIN::packagePolygon(), EAGLE_PLUGIN::packageText(), DIALOG_PAD_PROPERTIES::padValuesOK(), PANEL_PACKAGE::PANEL_PACKAGE(), PCAD2KICAD::PCB_ARC::Parse(), SCH_ALTIUM_PLUGIN::ParseArc(), PCB_PARSER::parseBoardUnits(), GPCB_FPL_CACHE::parseFOOTPRINT(), parseInt(), SCH_SEXPR_PARSER::parseInternalUnits(), SCH_TEXT::Plot(), GERBER_PLOTTER::plotArc(), BRDITEMS_PLOTTER::PlotFootprintShape(), PS_PLOTTER::PlotImage(), PDF_PLOTTER::PlotImage(), GERBER_PLOTTER::plotRoundRectAsRegion(), PSLIKE_PLOTTER::postscriptOverlinePositions(), SCH_TEXT::Print(), GERBER_DRAW_ITEM::Print(), FABMASTER::processArc(), FABMASTER::processFootprints(), FABMASTER::processLine(), FABMASTER::processPadStacks(), FABMASTER::processPins(), FABMASTER::processRectangle(), FABMASTER::processText(), FABMASTER::processVias(), GERBER_FILE_IMAGE::ReadIJCoord(), PARAM_CFG_INT_WITH_SCALE::ReadParam(), EXCELLON_IMAGE::readToolInformation(), GERBER_FILE_IMAGE::ReadXYCoord(), PANEL_SETUP_PINMAP::reBuildMatrixPanel(), VECTOR2< T >::Resize(), PSLIKE_PLOTTER::returnPostscriptTextWidth(), RotatePoint(), rotationFromString(), SCH_SEXPR_PLUGIN::saveJunction(), SCH_SEXPR_PLUGIN::saveSheet(), EDA_SHAPE::scale(), DSN::scale(), scaletoIU(), SCH_JUNCTION::SCH_JUNCTION(), PLOTTER::segmentAsOval(), PNS::SegmentHull(), SegmentIntersectsSegment(), PL_SELECTION_TOOL::SelectPoint(), DS_DATA_ITEM_TEXT::SetConstrainedTextSize(), PCAD2KICAD::SetTextSizeFromStrokeFontHeight(), PCAD2KICAD::SetTextSizeFromTrueTypeFontHeight(), SHAPE_ARC::SHAPE_ARC(), snapAngle(), PS_PLOTTER::StartPlot(), KIFONT::FONT::StringBoundaryLimits(), PGPROPERTY_DISTANCE::StringToDistance(), STROKE_PARAMS::Stroke(), PCAD2KICAD::StrToInt1Units(), PCAD2KICAD::StrToIntUnits(), KIFONT::OUTLINE_FONT::subscriptSize(), DS_DATA_ITEM_TEXT::SyncDrawItems(), CONNECTIVITY_DATA::TestTrackEndpointDangling(), AR_MATRIX::traceArc(), AR_MATRIX::traceCircle(), AR_MATRIX::TraceFilledRectangle(), DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataFromWindow(), PANEL_EESCHEMA_DISPLAY_OPTIONS::TransferDataFromWindow(), DIALOG_MOVE_EXACT::TransferDataFromWindow(), DIALOG_PAD_PRIMITIVES_TRANSFORM::Transform(), TransformOvalToPolygon(), TransformRoundChamferedRectToPolygon(), TransformTrapezoidToPolygon(), SHAPE_ARC::update_bbox(), DIALOG_PAGES_SETTINGS::UpdateDrawingSheetExample(), PCB_DIM_ALIGNED::updateGeometry(), PCB_DIM_ORTHOGONAL::updateGeometry(), PCB_DIM_RADIAL::updateGeometry(), TUNER_SLIDER::updateSlider(), PCB_DIM_RADIAL::updateText(), DIALOG_DRC::updateUI(), KIGFX::ORIGIN_VIEWITEM::ViewDraw(), and EXCELLON_WRITER::writeCoordinates().

◆ rescale() [1/3]

template<>
int rescale ( int  aNumerator,
int  aValue,
int  aDenominator 
)

Definition at line 58 of file util.cpp.

59{
60 int64_t numerator = (int64_t) aNumerator * (int64_t) aValue;
61
62 // round to nearest
63 if( ( numerator < 0 ) ^ ( aDenominator < 0 ) )
64 return ( numerator - aDenominator / 2 ) / aDenominator;
65 else
66 return ( numerator + aDenominator / 2 ) / aDenominator;
67
68}

◆ rescale() [2/3]

template<>
int64_t rescale ( int64_t  aNumerator,
int64_t  aValue,
int64_t  aDenominator 
)

Definition at line 72 of file util.cpp.

73{
74#if defined( _M_X64 ) && ( _MSC_VER >= 1920 )
75 int64_t productHi;
76 uint64_t productLo = static_cast<uint64_t>( _mul128( aNumerator, aValue, &productHi ) );
77
78 int64_t r = ( ( productHi < 0 ) ^ ( aDenominator < 0 ) ) ? -aDenominator / 2 : aDenominator / 2;
79
80 uint64_t rLo = static_cast<uint64_t>( r );
81 int64_t rHi = r < 0 ? -1ll : 0ll;
82
83 productLo += rLo;
84 productHi += rHi + ( productLo < rLo );
85
86 __try
87 {
88 int64_t remainder;
89 int64_t result = _div128( productHi, productLo, aDenominator, &remainder );
90
91 return result;
92 }
93 __except( ( GetExceptionCode() == EXCEPTION_INT_OVERFLOW ) ? EXCEPTION_EXECUTE_HANDLER
94 : EXCEPTION_CONTINUE_SEARCH )
95 {
96 kimathLogDebug( "Overflow in rescale (%lld * %lld + %lld) / %lld", aNumerator, aValue, r,
97 aDenominator );
98 }
99
100 return 0;
101
102#elif defined( __SIZEOF_INT128__ )
103 __int128_t numerator = (__int128_t) aNumerator * (__int128_t) aValue;
104
105 if( ( numerator < 0 ) ^ ( aDenominator < 0 ) )
106 return ( numerator - aDenominator / 2 ) / aDenominator;
107 else
108 return ( numerator + aDenominator / 2 ) / aDenominator;
109
110#else
111 int64_t r = 0;
112 int64_t sign = ( ( aNumerator < 0 ) ? -1 : 1 ) * ( aDenominator < 0 ? -1 : 1 ) *
113 ( aValue < 0 ? -1 : 1 );
114
115 int64_t a = std::abs( aNumerator );
116 int64_t b = std::abs( aValue );
117 int64_t c = std::abs( aDenominator );
118
119 r = c / 2;
120
121 if( b <= INT_MAX && c <= INT_MAX )
122 {
123 if( a <= INT_MAX )
124 return sign * ( ( a * b + r ) / c );
125 else
126 return sign * ( a / c * b + ( a % c * b + r ) / c);
127 }
128 else
129 {
130 uint64_t a0 = a & 0xFFFFFFFF;
131 uint64_t a1 = a >> 32;
132 uint64_t b0 = b & 0xFFFFFFFF;
133 uint64_t b1 = b >> 32;
134 uint64_t t1 = a0 * b1 + a1 * b0;
135 uint64_t t1a = t1 << 32;
136 int i;
137
138 a0 = a0 * b0 + t1a;
139 a1 = a1 * b1 + ( t1 >> 32 ) + ( a0 < t1a );
140 a0 += r;
141 a1 += a0 < (uint64_t)r;
142
143 for( i = 63; i >= 0; i-- )
144 {
145 a1 += a1 + ( ( a0 >> i ) & 1 );
146 t1 += t1;
147
148 if( (uint64_t) c <= a1 )
149 {
150 a1 -= c;
151 t1++;
152 }
153 }
154
155 return t1 * sign;
156 }
157#endif
158}
E_SERIE r
Definition: eserie.cpp:41
void kimathLogDebug(const char *aFormatString,...)
Helper to avoid directly including wx/log.h for the templated functions in kimath.
Definition: util.cpp:43
int sign(T val)
Definition: util.h:111

References std::abs(), kimathLogDebug(), r, and sign().

◆ rescale() [3/3]

template<typename T >
T rescale ( aNumerator,
aValue,
aDenominator 
)

Scale a number (value) by rational (numerator/denominator).

Numerator must be <= denominator.

Definition at line 105 of file util.h.

106{
107 return aNumerator * aValue / aDenominator;
108}

Referenced by BOOST_AUTO_TEST_CASE(), commonParallelProjection(), PNS::commonParallelProjection(), PAD::GetBestAnchorPosition(), SEG::intersects(), SEG::LineDistance(), SEG::LineProject(), SEG::NearestPoint(), NearestPointFixpt(), SHAPE_LINE_CHAIN_BASE::PointInside(), processEdge(), SEG::ReflectPoint(), and VECTOR2< T >::Resize().

◆ sign()