Coding policy, Doxygen comment, and spelling fixes.
This commit is contained in:
parent
a17bab4182
commit
b8310efd19
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2018-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2018-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
* Test if \a aTestPoint is on line defined by \a aSegStart and \a aSegEnd.
|
* Test if \a aTestPoint is on line defined by \a aSegStart and \a aSegEnd.
|
||||||
*
|
*
|
||||||
* This function is faster than #TestSegmentHit() because \a aTestPoint should be exactly on
|
* This function is faster than #TestSegmentHit() because \a aTestPoint should be exactly on
|
||||||
* the line. This works fine only for H, V and 45 degree line segments.
|
* the line. This only works for horizontal, vertical, and 45 degree line segments.
|
||||||
*
|
*
|
||||||
* @param aSegStart The first point of the line segment.
|
* @param aSegStart The first point of the line segment.
|
||||||
* @param aSegEnd The second point of the line segment.
|
* @param aSegEnd The second point of the line segment.
|
||||||
|
@ -51,15 +51,15 @@ bool IsPointOnSegment( const VECTOR2I& aSegStart, const VECTOR2I& aSegEnd,
|
||||||
* @param a_p1_l2 The first point of the second line.
|
* @param a_p1_l2 The first point of the second line.
|
||||||
* @param a_p2_l2 The second point of the second line.
|
* @param a_p2_l2 The second point of the second line.
|
||||||
* @param aIntersectionPoint is filled with the intersection point if it exists
|
* @param aIntersectionPoint is filled with the intersection point if it exists
|
||||||
* @return bool - true if the two segments defined by four points intersect.
|
* @return bool true if the two segments defined by four points intersect.
|
||||||
* (i.e. if the 2 segments have at least a common point)
|
* (i.e. if the 2 segments have at least a common point)
|
||||||
*/
|
*/
|
||||||
bool SegmentIntersectsSegment( const VECTOR2I& a_p1_l1, const VECTOR2I& a_p2_l1,
|
bool SegmentIntersectsSegment( const VECTOR2I& a_p1_l1, const VECTOR2I& a_p2_l1,
|
||||||
const VECTOR2I& a_p1_l2, const VECTOR2I& a_p2_l2,
|
const VECTOR2I& a_p1_l2, const VECTOR2I& a_p2_l2,
|
||||||
VECTOR2I* aIntersectionPoint = nullptr );
|
VECTOR2I* aIntersectionPoint = nullptr );
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Calculate the new point of coord coord pX, pY, for a rotation center 0, 0
|
* Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
|
||||||
*/
|
*/
|
||||||
void RotatePoint( int *pX, int *pY, const EDA_ANGLE& aAngle );
|
void RotatePoint( int *pX, int *pY, const EDA_ANGLE& aAngle );
|
||||||
|
|
||||||
|
@ -69,8 +69,8 @@ inline void RotatePoint( VECTOR2I& point, const EDA_ANGLE& aAngle )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Calculate the new point of coord coord pX, pY, for a rotation center cx, cy
|
* Calculate the new point of coord coord pX, pY, for a rotation center cx, cy.
|
||||||
*/
|
*/
|
||||||
void RotatePoint( int *pX, int *pY, int cx, int cy, const EDA_ANGLE& aAngle );
|
void RotatePoint( int *pX, int *pY, int cx, int cy, const EDA_ANGLE& aAngle );
|
||||||
|
|
||||||
|
@ -80,10 +80,9 @@ inline void RotatePoint( VECTOR2I& point, const VECTOR2I& centre, const EDA_ANGL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Calculate the new coord point point for a rotation center 0, 0
|
* Calculate the new coord point point for a rotation center 0, 0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void RotatePoint( double* pX, double* pY, const EDA_ANGLE& aAngle );
|
void RotatePoint( double* pX, double* pY, const EDA_ANGLE& aAngle );
|
||||||
|
|
||||||
inline void RotatePoint( VECTOR2D& point, const EDA_ANGLE& aAngle )
|
inline void RotatePoint( VECTOR2D& point, const EDA_ANGLE& aAngle )
|
||||||
|
@ -91,7 +90,6 @@ inline void RotatePoint( VECTOR2D& point, const EDA_ANGLE& aAngle )
|
||||||
RotatePoint( &point.x, &point.y, aAngle );
|
RotatePoint( &point.x, &point.y, aAngle );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RotatePoint( double* pX, double* pY, double cx, double cy, const EDA_ANGLE& aAngle );
|
void RotatePoint( double* pX, double* pY, double cx, double cy, const EDA_ANGLE& aAngle );
|
||||||
|
|
||||||
inline void RotatePoint( VECTOR2D& point, const VECTOR2D& aCenter, const EDA_ANGLE& aAngle )
|
inline void RotatePoint( VECTOR2D& point, const VECTOR2D& aCenter, const EDA_ANGLE& aAngle )
|
||||||
|
@ -102,10 +100,10 @@ inline void RotatePoint( VECTOR2D& point, const VECTOR2D& aCenter, const EDA_ANG
|
||||||
/**
|
/**
|
||||||
* Determine the center of an arc or circle given three points on its circumference.
|
* Determine the center of an arc or circle given three points on its circumference.
|
||||||
*
|
*
|
||||||
* @param aStart The starting point of the circle (equivalent to aEnd)
|
* @param aStart The starting point of the circle (equivalent to aEnd).
|
||||||
* @param aMid The point on the arc, half-way between aStart and aEnd
|
* @param aMid The point on the arc, half-way between aStart and aEnd.
|
||||||
* @param aEnd The ending point of the circle (equivalent to aStart)
|
* @param aEnd The ending point of the circle (equivalent to aStart).
|
||||||
* @return The center of the circle
|
* @return The center of the circle.
|
||||||
*/
|
*/
|
||||||
const VECTOR2I CalcArcCenter( const VECTOR2I& aStart, const VECTOR2I& aMid, const VECTOR2I& aEnd );
|
const VECTOR2I CalcArcCenter( const VECTOR2I& aStart, const VECTOR2I& aMid, const VECTOR2I& aEnd );
|
||||||
const VECTOR2D CalcArcCenter( const VECTOR2D& aStart, const VECTOR2D& aMid, const VECTOR2D& aEnd );
|
const VECTOR2D CalcArcCenter( const VECTOR2D& aStart, const VECTOR2D& aMid, const VECTOR2D& aEnd );
|
||||||
|
@ -113,15 +111,16 @@ const VECTOR2D CalcArcCenter( const VECTOR2D& aStart, const VECTOR2D& aEnd,
|
||||||
const EDA_ANGLE& aAngle );
|
const EDA_ANGLE& aAngle );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the middle point of an arc, half-way between aStart and aEnd. There are two possible
|
* Return the middle point of an arc, half-way between aStart and aEnd.
|
||||||
* solutions which can be found by toggling aMinArcAngle. The behaviour is undefined for
|
|
||||||
* semicircles (i.e. 180 degree arcs).
|
|
||||||
*
|
*
|
||||||
* @param aStart The starting point of the arc (for calculating the radius)
|
* There are two possible solutions which can be found by toggling aMinArcAngle. The behavior
|
||||||
* @param aEnd The end point of the arc (for determining the arc angle)
|
* is undefined for semicircles (i.e. 180 degree arcs).
|
||||||
* @param aCenter The center point of the arc
|
*
|
||||||
|
* @param aStart The starting point of the arc (for calculating the radius).
|
||||||
|
* @param aEnd The end point of the arc (for determining the arc angle).
|
||||||
|
* @param aCenter The center point of the arc.
|
||||||
* @param aMinArcAngle If true, returns the point that results in the smallest arc angle.
|
* @param aMinArcAngle If true, returns the point that results in the smallest arc angle.
|
||||||
* @return The middle point of the arc
|
* @return The middle point of the arc.
|
||||||
*/
|
*/
|
||||||
const VECTOR2I CalcArcMid( const VECTOR2I& aStart, const VECTOR2I& aEnd, const VECTOR2I& aCenter,
|
const VECTOR2I CalcArcMid( const VECTOR2I& aStart, const VECTOR2I& aEnd, const VECTOR2I& aCenter,
|
||||||
bool aMinArcAngle = true );
|
bool aMinArcAngle = true );
|
||||||
|
@ -132,11 +131,15 @@ inline double EuclideanNorm( const VECTOR2I& vector )
|
||||||
return hypot( vector.x, vector.y );
|
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
|
* Compute the distance between a line and a reference point.
|
||||||
//! @param linePointA Point on line
|
*
|
||||||
//! @param linePointB Point on line
|
* Reference: http://mathworld.wolfram.com/Point-LineDistance2-Dimensional.html
|
||||||
//! @param referencePoint Reference point
|
*
|
||||||
|
* @param linePointA Point on line.
|
||||||
|
* @param linePointB Point on line.
|
||||||
|
* @param referencePoint Reference point.
|
||||||
|
*/
|
||||||
inline double DistanceLinePoint( const VECTOR2I& linePointA, const VECTOR2I& linePointB,
|
inline double DistanceLinePoint( const VECTOR2I& linePointA, const VECTOR2I& linePointB,
|
||||||
const VECTOR2I& referencePoint )
|
const VECTOR2I& referencePoint )
|
||||||
{
|
{
|
||||||
|
@ -151,11 +154,14 @@ inline double DistanceLinePoint( const VECTOR2I& linePointA, const VECTOR2I& lin
|
||||||
/ EuclideanNorm( linePointB - linePointA ) );
|
/ EuclideanNorm( linePointB - linePointA ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
//! @brief Test, if two points are near each other
|
/**
|
||||||
//! @param pointA First point
|
* Test if two points are near each other.
|
||||||
//! @param pointB Second point
|
*
|
||||||
//! @param threshold The maximum distance
|
* @param pointA First point.
|
||||||
//! @return True or false
|
* @param pointB Second point.
|
||||||
|
* @param threshold The maximum distance.
|
||||||
|
* @return true if \a pointA is within \a threshold of \a pointB otherwise false.
|
||||||
|
*/
|
||||||
inline bool HitTestPoints( const VECTOR2I& pointA, const VECTOR2I& pointB, double threshold )
|
inline bool HitTestPoints( const VECTOR2I& pointA, const VECTOR2I& pointB, double threshold )
|
||||||
{
|
{
|
||||||
VECTOR2I vectorAB = pointB - pointA;
|
VECTOR2I vectorAB = pointB - pointA;
|
||||||
|
@ -201,7 +207,9 @@ inline double RAD2DECIDEG( double rad ) { return rad * 1800.0 / M_PI; }
|
||||||
/* These are templated over T (and not simply double) because Eeschema
|
/* These are templated over T (and not simply double) because Eeschema
|
||||||
is still using int for angles in some place */
|
is still using int for angles in some place */
|
||||||
|
|
||||||
/// Normalize angle to be in the 0.0 .. 360.0 range: angle is in 1/10 degrees.
|
/**
|
||||||
|
* Normalize angle to be in the 0.0 .. 360.0 range: angle is in 1/10 degrees.
|
||||||
|
*/
|
||||||
template <class T> inline T NormalizeAnglePos( T Angle )
|
template <class T> inline T NormalizeAnglePos( T Angle )
|
||||||
{
|
{
|
||||||
while( Angle < 0 )
|
while( Angle < 0 )
|
||||||
|
@ -217,7 +225,9 @@ template <class T> inline void NORMALIZE_ANGLE_POS( T& Angle )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Normalize angle to be in the -180.0 .. 180.0 range
|
/**
|
||||||
|
* Normalize angle to be in the -180.0 .. 180.0 range.
|
||||||
|
*/
|
||||||
template <class T> inline T NormalizeAngle180( T Angle )
|
template <class T> inline T NormalizeAngle180( T Angle )
|
||||||
{
|
{
|
||||||
while( Angle <= -1800 )
|
while( Angle <= -1800 )
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
* Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||||
* Copyright (C) 2014-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2014-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -36,9 +36,7 @@
|
||||||
#include <math/vector2d.h> // for VECTOR2I
|
#include <math/vector2d.h> // for VECTOR2I
|
||||||
#include <trigo.h>
|
#include <trigo.h>
|
||||||
|
|
||||||
// Returns true if the point P is on the segment S.
|
|
||||||
// faster than TestSegmentHit() because P should be exactly on S
|
|
||||||
// therefore works fine only for H, V and 45 deg segm (suitable for wires in eeschema)
|
|
||||||
bool IsPointOnSegment( const VECTOR2I& aSegStart, const VECTOR2I& aSegEnd,
|
bool IsPointOnSegment( const VECTOR2I& aSegStart, const VECTOR2I& aSegEnd,
|
||||||
const VECTOR2I& aTestPoint )
|
const VECTOR2I& aTestPoint )
|
||||||
{
|
{
|
||||||
|
@ -47,7 +45,7 @@ bool IsPointOnSegment( const VECTOR2I& aSegStart, const VECTOR2I& aSegEnd,
|
||||||
|
|
||||||
// Use long long here to avoid overflow in calculations
|
// Use long long here to avoid overflow in calculations
|
||||||
if( (long long) vectSeg.x * vectPoint.y - (long long) vectSeg.y * vectPoint.x )
|
if( (long long) vectSeg.x * vectPoint.y - (long long) vectSeg.y * vectPoint.x )
|
||||||
return false; /* Cross product non-zero, vectors not parallel */
|
return false; /* Cross product non-zero, vectors not parallel */
|
||||||
|
|
||||||
if( ( (long long) vectSeg.x * vectPoint.x + (long long) vectSeg.y * vectPoint.y ) <
|
if( ( (long long) vectSeg.x * vectPoint.x + (long long) vectSeg.y * vectPoint.y ) <
|
||||||
( (long long) vectPoint.x * vectPoint.x + (long long) vectPoint.y * vectPoint.y ) )
|
( (long long) vectPoint.x * vectPoint.x + (long long) vectPoint.y * vectPoint.y ) )
|
||||||
|
@ -57,19 +55,18 @@ bool IsPointOnSegment( const VECTOR2I& aSegStart, const VECTOR2I& aSegEnd,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Returns true if the segment 1 intersected the segment 2.
|
|
||||||
bool SegmentIntersectsSegment( const VECTOR2I& a_p1_l1, const VECTOR2I& a_p2_l1,
|
bool SegmentIntersectsSegment( const VECTOR2I& a_p1_l1, const VECTOR2I& a_p2_l1,
|
||||||
const VECTOR2I& a_p1_l2, const VECTOR2I& a_p2_l2,
|
const VECTOR2I& a_p1_l2, const VECTOR2I& a_p2_l2,
|
||||||
VECTOR2I* aIntersectionPoint )
|
VECTOR2I* aIntersectionPoint )
|
||||||
{
|
{
|
||||||
|
|
||||||
//We are forced to use 64bit ints because the internal units can overflow 32bit ints when
|
// We are forced to use 64bit ints because the internal units can overflow 32bit ints when
|
||||||
// multiplied with each other, the alternative would be to scale the units down (i.e. divide
|
// multiplied with each other, the alternative would be to scale the units down (i.e. divide
|
||||||
// by a fixed number).
|
// by a fixed number).
|
||||||
int64_t dX_a, dY_a, dX_b, dY_b, dX_ab, dY_ab;
|
int64_t dX_a, dY_a, dX_b, dY_b, dX_ab, dY_ab;
|
||||||
int64_t num_a, num_b, den;
|
int64_t num_a, num_b, den;
|
||||||
|
|
||||||
//Test for intersection within the bounds of both line segments using line equations of the
|
// Test for intersection within the bounds of both line segments using line equations of the
|
||||||
// form:
|
// form:
|
||||||
// x_k(u_k) = u_k * dX_k + x_k(0)
|
// x_k(u_k) = u_k * dX_k + x_k(0)
|
||||||
// y_k(u_k) = u_k * dY_k + y_k(0)
|
// y_k(u_k) = u_k * dY_k + y_k(0)
|
||||||
|
@ -84,14 +81,14 @@ bool SegmentIntersectsSegment( const VECTOR2I& a_p1_l1, const VECTOR2I& a_p2_l1,
|
||||||
|
|
||||||
den = dY_a * dX_b - dY_b * dX_a ;
|
den = dY_a * dX_b - dY_b * dX_a ;
|
||||||
|
|
||||||
//Check if lines are parallel
|
// Check if lines are parallel.
|
||||||
if( den == 0 )
|
if( den == 0 )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
num_a = dY_ab * dX_b - dY_b * dX_ab;
|
num_a = dY_ab * dX_b - dY_b * dX_ab;
|
||||||
num_b = dY_ab * dX_a - dY_a * dX_ab;
|
num_b = dY_ab * dX_a - dY_a * dX_ab;
|
||||||
|
|
||||||
// Only compute the intersection point if requested
|
// Only compute the intersection point if requested.
|
||||||
if( aIntersectionPoint )
|
if( aIntersectionPoint )
|
||||||
{
|
{
|
||||||
*aIntersectionPoint = a_p1_l1;
|
*aIntersectionPoint = a_p1_l1;
|
||||||
|
@ -106,19 +103,19 @@ bool SegmentIntersectsSegment( const VECTOR2I& a_p1_l1, const VECTOR2I& a_p2_l1,
|
||||||
num_b = -num_b;
|
num_b = -num_b;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Test sign( u_a ) and return false if negative
|
// Test sign( u_a ) and return false if negative.
|
||||||
if( num_a < 0 )
|
if( num_a < 0 )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//Test sign( u_b ) and return false if negative
|
// Test sign( u_b ) and return false if negative.
|
||||||
if( num_b < 0 )
|
if( num_b < 0 )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//Test to ensure (u_a <= 1)
|
// Test to ensure (u_a <= 1).
|
||||||
if( num_a > den )
|
if( num_a > den )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//Test to ensure (u_b <= 1)
|
// Test to ensure (u_b <= 1).
|
||||||
if( num_b > den )
|
if( num_b > den )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -141,14 +138,14 @@ bool TestSegmentHit( const VECTOR2I& aRefPoint, const VECTOR2I& aStart, const VE
|
||||||
if( ymax < ymin )
|
if( ymax < ymin )
|
||||||
std::swap( ymax, ymin );
|
std::swap( ymax, ymin );
|
||||||
|
|
||||||
// First, check if we are outside of the bounding box
|
// Check if we are outside of the bounding box.
|
||||||
if( ( ymin - aRefPoint.y > aDist ) || ( aRefPoint.y - ymax > aDist ) )
|
if( ( ymin - aRefPoint.y > aDist ) || ( aRefPoint.y - ymax > aDist ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if( ( xmin - aRefPoint.x > aDist ) || ( aRefPoint.x - xmax > aDist ) )
|
if( ( xmin - aRefPoint.x > aDist ) || ( aRefPoint.x - xmax > aDist ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Next, eliminate easy cases
|
// Eliminate easy cases.
|
||||||
if( aStart.x == aEnd.x && aRefPoint.y > ymin && aRefPoint.y < ymax )
|
if( aStart.x == aEnd.x && aRefPoint.y > ymin && aRefPoint.y < ymax )
|
||||||
return std::abs( delta.x ) <= aDist;
|
return std::abs( delta.x ) <= aDist;
|
||||||
|
|
||||||
|
@ -356,8 +353,8 @@ const VECTOR2D CalcArcCenter( const VECTOR2D& aStart, const VECTOR2D& aMid, cons
|
||||||
{
|
{
|
||||||
if( aStart == aEnd )
|
if( aStart == aEnd )
|
||||||
{
|
{
|
||||||
// This is a special case for a 360 degrees arc. In this case, the center is halfway between
|
// This is a special case for a 360 degrees arc. In this case, the center is
|
||||||
// the midpoint and either end point
|
// halfway between the midpoint and either end point.
|
||||||
center.x = ( aStart.x + aMid.x ) / 2.0;
|
center.x = ( aStart.x + aMid.x ) / 2.0;
|
||||||
center.y = ( aStart.y + aMid.y ) / 2.0 ;
|
center.y = ( aStart.y + aMid.y ) / 2.0 ;
|
||||||
return center;
|
return center;
|
||||||
|
@ -383,22 +380,24 @@ const VECTOR2D CalcArcCenter( const VECTOR2D& aStart, const VECTOR2D& aMid, cons
|
||||||
// to the standard deviation.
|
// to the standard deviation.
|
||||||
// We ignore the possible covariance between variables. We also truncate our series expansion
|
// We ignore the possible covariance between variables. We also truncate our series expansion
|
||||||
// at the first term. These are reasonable assumptions as the worst-case scenario is that we
|
// at the first term. These are reasonable assumptions as the worst-case scenario is that we
|
||||||
// underestimate the potential uncertainty, which would potentially put us back at the status quo
|
// underestimate the potential uncertainty, which would potentially put us back at the status
|
||||||
|
// quo.
|
||||||
double abSlopeStartEndY = aSlope * bSlope * ( aStart.y - aEnd.y );
|
double abSlopeStartEndY = aSlope * bSlope * ( aStart.y - aEnd.y );
|
||||||
double dabSlopeStartEndY = abSlopeStartEndY * std::sqrt( ( daSlope / aSlope * daSlope / aSlope )
|
double dabSlopeStartEndY = abSlopeStartEndY *
|
||||||
+ ( dbSlope / bSlope * dbSlope / bSlope )
|
std::sqrt( ( daSlope / aSlope * daSlope / aSlope )
|
||||||
+ ( M_SQRT1_2 / ( aStart.y - aEnd.y )
|
+ ( dbSlope / bSlope * dbSlope / bSlope )
|
||||||
* M_SQRT1_2 / ( aStart.y - aEnd.y ) ) );
|
+ ( M_SQRT1_2 / ( aStart.y - aEnd.y )
|
||||||
|
* M_SQRT1_2 / ( aStart.y - aEnd.y ) ) );
|
||||||
|
|
||||||
double bSlopeStartMidX = bSlope * ( aStart.x + aMid.x );
|
double bSlopeStartMidX = bSlope * ( aStart.x + aMid.x );
|
||||||
double dbSlopeStartMidX = bSlopeStartMidX * std::sqrt( ( dbSlope / bSlope * dbSlope / bSlope )
|
double dbSlopeStartMidX = bSlopeStartMidX * std::sqrt( ( dbSlope / bSlope * dbSlope / bSlope )
|
||||||
+ ( M_SQRT1_2 / ( aStart.x + aMid.x )
|
+ ( M_SQRT1_2 / ( aStart.x + aMid.x )
|
||||||
* M_SQRT1_2 / ( aStart.x + aMid.x ) ) );
|
* M_SQRT1_2 / ( aStart.x + aMid.x ) ) );
|
||||||
|
|
||||||
double aSlopeMidEndX = aSlope * ( aMid.x + aEnd.x );
|
double aSlopeMidEndX = aSlope * ( aMid.x + aEnd.x );
|
||||||
double daSlopeMidEndX = aSlopeMidEndX * std::sqrt( ( daSlope / aSlope * daSlope / aSlope )
|
double daSlopeMidEndX = aSlopeMidEndX * std::sqrt( ( daSlope / aSlope * daSlope / aSlope )
|
||||||
+ ( M_SQRT1_2 / ( aMid.x + aEnd.x )
|
+ ( M_SQRT1_2 / ( aMid.x + aEnd.x )
|
||||||
* M_SQRT1_2 / ( aMid.x + aEnd.x ) ) );
|
* M_SQRT1_2 / ( aMid.x + aEnd.x ) ) );
|
||||||
|
|
||||||
double twiceBASlopeDiff = 2 * ( bSlope - aSlope );
|
double twiceBASlopeDiff = 2 * ( bSlope - aSlope );
|
||||||
double dtwiceBASlopeDiff = 2 * std::sqrt( dbSlope * dbSlope + daSlope * daSlope );
|
double dtwiceBASlopeDiff = 2 * std::sqrt( dbSlope * dbSlope + daSlope * daSlope );
|
||||||
|
@ -410,8 +409,10 @@ const VECTOR2D CalcArcCenter( const VECTOR2D& aStart, const VECTOR2D& aMid, cons
|
||||||
|
|
||||||
double centerX = ( abSlopeStartEndY + bSlopeStartMidX - aSlopeMidEndX ) / twiceBASlopeDiff;
|
double centerX = ( abSlopeStartEndY + bSlopeStartMidX - aSlopeMidEndX ) / twiceBASlopeDiff;
|
||||||
|
|
||||||
double dCenterX = centerX * std::sqrt( ( dCenterNumeratorX / centerNumeratorX * dCenterNumeratorX / centerNumeratorX )
|
double dCenterX = centerX * std::sqrt( ( dCenterNumeratorX / centerNumeratorX *
|
||||||
+ ( dtwiceBASlopeDiff / twiceBASlopeDiff * dtwiceBASlopeDiff / twiceBASlopeDiff ) );
|
dCenterNumeratorX / centerNumeratorX )
|
||||||
|
+ ( dtwiceBASlopeDiff / twiceBASlopeDiff *
|
||||||
|
dtwiceBASlopeDiff / twiceBASlopeDiff ) );
|
||||||
|
|
||||||
|
|
||||||
double centerNumeratorY = ( ( aStart.x + aMid.x ) / 2.0 - centerX );
|
double centerNumeratorY = ( ( aStart.x + aMid.x ) / 2.0 - centerX );
|
||||||
|
@ -419,7 +420,8 @@ const VECTOR2D CalcArcCenter( const VECTOR2D& aStart, const VECTOR2D& aMid, cons
|
||||||
|
|
||||||
double centerFirstTerm = centerNumeratorY / aSlope;
|
double centerFirstTerm = centerNumeratorY / aSlope;
|
||||||
double dcenterFirstTermY = centerFirstTerm * std::sqrt(
|
double dcenterFirstTermY = centerFirstTerm * std::sqrt(
|
||||||
( dCenterNumeratorY/ centerNumeratorY * dCenterNumeratorY / centerNumeratorY )
|
( dCenterNumeratorY/ centerNumeratorY *
|
||||||
|
dCenterNumeratorY / centerNumeratorY )
|
||||||
+ ( daSlope / aSlope * daSlope / aSlope ) );
|
+ ( daSlope / aSlope * daSlope / aSlope ) );
|
||||||
|
|
||||||
double centerY = centerFirstTerm + ( aStart.y + aMid.y ) / 2.0;
|
double centerY = centerFirstTerm + ( aStart.y + aMid.y ) / 2.0;
|
||||||
|
@ -430,16 +432,19 @@ const VECTOR2D CalcArcCenter( const VECTOR2D& aStart, const VECTOR2D& aMid, cons
|
||||||
double rounded10CenterX = std::floor( ( centerX + 5.0 ) / 10.0 ) * 10.0;
|
double rounded10CenterX = std::floor( ( centerX + 5.0 ) / 10.0 ) * 10.0;
|
||||||
double rounded10CenterY = std::floor( ( centerY + 5.0 ) / 10.0 ) * 10.0;
|
double rounded10CenterY = std::floor( ( centerY + 5.0 ) / 10.0 ) * 10.0;
|
||||||
|
|
||||||
// The last step is to find the nice, round numbers near our baseline estimate and see if they are within our uncertainty
|
// The last step is to find the nice, round numbers near our baseline estimate and see if
|
||||||
// range. If they are, then we use this round value as the true value. This is justified because ALL values within the
|
// they are within our uncertainty range. If they are, then we use this round value as the
|
||||||
// uncertainty range are equally true. Using a round number will make sure that we are on a multiple of 1mil or 100nm
|
// true value. This is justified because ALL values within the uncertainty range are equally
|
||||||
|
// true. Using a round number will make sure that we are on a multiple of 1mil or 100nm
|
||||||
// when calculating centers.
|
// when calculating centers.
|
||||||
if( std::abs( rounded100CenterX - centerX ) < dCenterX && std::abs( rounded100CenterY - centerY ) < dCenterY )
|
if( std::abs( rounded100CenterX - centerX ) < dCenterX &&
|
||||||
|
std::abs( rounded100CenterY - centerY ) < dCenterY )
|
||||||
{
|
{
|
||||||
center.x = rounded100CenterX;
|
center.x = rounded100CenterX;
|
||||||
center.y = rounded100CenterY;
|
center.y = rounded100CenterY;
|
||||||
}
|
}
|
||||||
else if( std::abs( rounded10CenterX - centerX ) < dCenterX && std::abs( rounded10CenterY - centerY ) < dCenterY )
|
else if( std::abs( rounded10CenterX - centerX ) < dCenterX &&
|
||||||
|
std::abs( rounded10CenterY - centerY ) < dCenterY )
|
||||||
{
|
{
|
||||||
center.x = rounded10CenterX;
|
center.x = rounded10CenterX;
|
||||||
center.y = rounded10CenterY;
|
center.y = rounded10CenterY;
|
||||||
|
|
Loading…
Reference in New Issue