mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-14 02:03:12 +02:00
Add additional handling for arc collisions
Provides nearest point calculation for circles, segments and rects Fixes https://gitlab.com/kicad/code/kicad/-/issues/18203
This commit is contained in:
parent
bcebc694b8
commit
bfb3875a68
@ -32,7 +32,9 @@
|
|||||||
#include <geometry/eda_angle.h>
|
#include <geometry/eda_angle.h>
|
||||||
|
|
||||||
class CIRCLE;
|
class CIRCLE;
|
||||||
|
class SHAPE_CIRCLE;
|
||||||
class SHAPE_LINE_CHAIN;
|
class SHAPE_LINE_CHAIN;
|
||||||
|
class SHAPE_RECT;
|
||||||
|
|
||||||
class SHAPE_ARC : public SHAPE
|
class SHAPE_ARC : public SHAPE
|
||||||
{
|
{
|
||||||
@ -120,7 +122,6 @@ public:
|
|||||||
|
|
||||||
VECTOR2I NearestPoint( const VECTOR2I& aP ) const;
|
VECTOR2I NearestPoint( const VECTOR2I& aP ) const;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute closest points between this arc and \a aArc.
|
* Compute closest points between this arc and \a aArc.
|
||||||
*
|
*
|
||||||
@ -131,6 +132,36 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool NearestPoints( const SHAPE_ARC& aArc, VECTOR2I& aPtA, VECTOR2I& aPtB, int64_t& aDistSq ) const;
|
bool NearestPoints( const SHAPE_ARC& aArc, VECTOR2I& aPtA, VECTOR2I& aPtB, int64_t& aDistSq ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute closest points between this arc and \a aCircle.
|
||||||
|
*
|
||||||
|
* @param aPtA point on this arc (output)
|
||||||
|
* @param aPtB point on the circle (output)
|
||||||
|
* @param aDistSq squared distance between points (output)
|
||||||
|
* @return true if the operation was successful
|
||||||
|
*/
|
||||||
|
bool NearestPoints( const SHAPE_CIRCLE& aCircle, VECTOR2I& aPtA, VECTOR2I& aPtB, int64_t& aDistSq ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute closest points between this arc and \a aSeg.
|
||||||
|
*
|
||||||
|
* @param aPtA point on this arc (output)
|
||||||
|
* @param aPtB point on the segment (output)
|
||||||
|
* @param aDistSq squared distance between points (output)
|
||||||
|
* @return true if the operation was successful
|
||||||
|
*/
|
||||||
|
bool NearestPoints( const SEG& aSeg, VECTOR2I& aPtA, VECTOR2I& aPtB, int64_t& aDistSq ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute closest points between this arc and \a aRect.
|
||||||
|
*
|
||||||
|
* @param aPtA point on this arc (output)
|
||||||
|
* @param aPtB point on the rectangle (output)
|
||||||
|
* @param aDistSq squared distance between points (output)
|
||||||
|
* @return true if the operation was successful
|
||||||
|
*/
|
||||||
|
bool NearestPoints( const SHAPE_RECT& aRect, VECTOR2I& aPtA, VECTOR2I& aPtB, int64_t& aDistSq ) const;
|
||||||
|
|
||||||
bool Collide( const SEG& aSeg, int aClearance = 0, int* aActual = nullptr,
|
bool Collide( const SEG& aSeg, int aClearance = 0, int* aActual = nullptr,
|
||||||
VECTOR2I* aLocation = nullptr ) const override;
|
VECTOR2I* aLocation = nullptr ) const override;
|
||||||
bool Collide( const VECTOR2I& aP, int aClearance = 0, int* aActual = nullptr,
|
bool Collide( const VECTOR2I& aP, int aClearance = 0, int* aActual = nullptr,
|
||||||
|
@ -506,7 +506,7 @@ public:
|
|||||||
if( !m_init )
|
if( !m_init )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Vec closest = ClosestPointTo( aCenter );
|
Vec closest = NearestPoint( aCenter );
|
||||||
|
|
||||||
double dx = static_cast<double>( aCenter.x ) - closest.x;
|
double dx = static_cast<double>( aCenter.x ) - closest.x;
|
||||||
double dy = static_cast<double>( aCenter.y ) - closest.y;
|
double dy = static_cast<double>( aCenter.y ) - closest.y;
|
||||||
@ -848,7 +848,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Return the point in this rect that is closest to the provided point
|
* Return the point in this rect that is closest to the provided point
|
||||||
*/
|
*/
|
||||||
constexpr Vec ClosestPointTo( const Vec& aPoint ) const
|
constexpr Vec NearestPoint( const Vec& aPoint ) const
|
||||||
{
|
{
|
||||||
BOX2<Vec> me( *this );
|
BOX2<Vec> me( *this );
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include <geometry/shape_arc.h>
|
#include <geometry/shape_arc.h>
|
||||||
#include <geometry/shape_circle.h>
|
#include <geometry/shape_circle.h>
|
||||||
#include <geometry/shape_line_chain.h>
|
#include <geometry/shape_line_chain.h>
|
||||||
|
#include <geometry/shape_rect.h>
|
||||||
#include <convert_basic_shapes_to_polygon.h>
|
#include <convert_basic_shapes_to_polygon.h>
|
||||||
#include <trigo.h>
|
#include <trigo.h>
|
||||||
|
|
||||||
@ -446,6 +447,185 @@ VECTOR2I SHAPE_ARC::NearestPoint( const VECTOR2I& aP ) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SHAPE_ARC::NearestPoints( const SHAPE_CIRCLE& aCircle, VECTOR2I& aPtA, VECTOR2I& aPtB,
|
||||||
|
int64_t& aDistSq ) const
|
||||||
|
{
|
||||||
|
if( GetCenter() == aCircle.GetCenter() && GetRadius() == aCircle.GetRadius() )
|
||||||
|
{
|
||||||
|
aPtA = aPtB = GetP0();
|
||||||
|
aDistSq = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
aDistSq = std::numeric_limits<int64_t>::max();
|
||||||
|
|
||||||
|
CIRCLE circle1( GetCenter(), GetRadius() );
|
||||||
|
CIRCLE circle2( aCircle.GetCircle() );
|
||||||
|
std::vector<VECTOR2I> intersections = circle1.Intersect( circle2 );
|
||||||
|
|
||||||
|
for( const VECTOR2I& pt : intersections )
|
||||||
|
{
|
||||||
|
if( sliceContainsPoint( pt ) )
|
||||||
|
{
|
||||||
|
aPtA = aPtB = pt;
|
||||||
|
aDistSq = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<VECTOR2I> pts = { m_start, m_end, circle1.NearestPoint( GetCenter() ) };
|
||||||
|
|
||||||
|
for( const VECTOR2I& pt : pts )
|
||||||
|
{
|
||||||
|
if( sliceContainsPoint( pt ) )
|
||||||
|
{
|
||||||
|
VECTOR2I nearestPt2 = circle2.NearestPoint( pt );
|
||||||
|
int64_t distSq = pt.SquaredDistance( nearestPt2 );
|
||||||
|
|
||||||
|
if( distSq < aDistSq )
|
||||||
|
{
|
||||||
|
aDistSq = distSq;
|
||||||
|
aPtA = pt;
|
||||||
|
aPtB = nearestPt2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SHAPE_ARC::NearestPoints( const SEG& aSeg, VECTOR2I& aPtA, VECTOR2I& aPtB,
|
||||||
|
int64_t& aDistSq ) const
|
||||||
|
{
|
||||||
|
aDistSq = std::numeric_limits<int64_t>::max();
|
||||||
|
CIRCLE circle( GetCenter(), GetRadius() );
|
||||||
|
|
||||||
|
// First check for intersections on the circle
|
||||||
|
std::vector<VECTOR2I> intersections = circle.Intersect( aSeg );
|
||||||
|
|
||||||
|
for( const VECTOR2I& pt : intersections )
|
||||||
|
{
|
||||||
|
if( sliceContainsPoint( pt ) )
|
||||||
|
{
|
||||||
|
aPtA = aPtB = pt;
|
||||||
|
aDistSq = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the endpoints of the segment against the nearest point on the arc
|
||||||
|
for( const VECTOR2I& pt : { aSeg.A, aSeg.B } )
|
||||||
|
{
|
||||||
|
if( sliceContainsPoint( pt ) )
|
||||||
|
{
|
||||||
|
VECTOR2I nearestPt = circle.NearestPoint( pt );
|
||||||
|
int64_t distSq = pt.SquaredDistance( nearestPt );
|
||||||
|
|
||||||
|
if( distSq < aDistSq )
|
||||||
|
{
|
||||||
|
aDistSq = distSq;
|
||||||
|
aPtA = nearestPt;
|
||||||
|
aPtB = pt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the endpoints of the arc against the nearest point on the segment
|
||||||
|
for( const VECTOR2I& pt : { m_start, m_end } )
|
||||||
|
{
|
||||||
|
VECTOR2I nearestPt = aSeg.NearestPoint( pt );
|
||||||
|
int64_t distSq = pt.SquaredDistance( nearestPt );
|
||||||
|
|
||||||
|
if( distSq < aDistSq )
|
||||||
|
{
|
||||||
|
aDistSq = distSq;
|
||||||
|
aPtA = pt;
|
||||||
|
aPtB = nearestPt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the closest points on the segment to the circle
|
||||||
|
VECTOR2I segNearestPt = aSeg.NearestPoint( GetCenter() );
|
||||||
|
|
||||||
|
if( sliceContainsPoint( segNearestPt ) )
|
||||||
|
{
|
||||||
|
VECTOR2I circleNearestPt = circle.NearestPoint( segNearestPt );
|
||||||
|
int64_t distSq = segNearestPt.SquaredDistance( circleNearestPt );
|
||||||
|
|
||||||
|
if( distSq < aDistSq )
|
||||||
|
{
|
||||||
|
aDistSq = distSq;
|
||||||
|
aPtA = segNearestPt;
|
||||||
|
aPtB = circleNearestPt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SHAPE_ARC::NearestPoints( const SHAPE_RECT& aRect, VECTOR2I& aPtA, VECTOR2I& aPtB,
|
||||||
|
int64_t& aDistSq ) const
|
||||||
|
{
|
||||||
|
BOX2I bbox = aRect.BBox();
|
||||||
|
CIRCLE circle( GetCenter(), GetRadius() );
|
||||||
|
aDistSq = std::numeric_limits<int64_t>::max();
|
||||||
|
|
||||||
|
// First check for intersections
|
||||||
|
SHAPE_LINE_CHAIN lineChain( aRect.Outline() );
|
||||||
|
|
||||||
|
for( int i = 0; i < 4; ++i )
|
||||||
|
{
|
||||||
|
SEG seg( lineChain.CPoint( i ), lineChain.CPoint( i + 1 ) );
|
||||||
|
|
||||||
|
std::vector<VECTOR2I> intersections = circle.Intersect( seg );
|
||||||
|
|
||||||
|
for( const VECTOR2I& pt : intersections )
|
||||||
|
{
|
||||||
|
if( sliceContainsPoint( pt ) )
|
||||||
|
{
|
||||||
|
aPtA = aPtB = pt;
|
||||||
|
aDistSq = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the endpoints of the arc against the nearest point on the rectangle
|
||||||
|
for( const VECTOR2I& pt : { m_start, m_end } )
|
||||||
|
{
|
||||||
|
VECTOR2I nearestPt = bbox.NearestPoint( pt );
|
||||||
|
int64_t distSq = pt.SquaredDistance( nearestPt );
|
||||||
|
|
||||||
|
if( distSq < aDistSq )
|
||||||
|
{
|
||||||
|
aDistSq = distSq;
|
||||||
|
aPtA = pt;
|
||||||
|
aPtB = nearestPt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the closest points on the rectangle to the circle
|
||||||
|
VECTOR2I rectNearestPt = bbox.NearestPoint( GetCenter() );
|
||||||
|
|
||||||
|
if( sliceContainsPoint( rectNearestPt ) )
|
||||||
|
{
|
||||||
|
VECTOR2I circleNearestPt = circle.NearestPoint( rectNearestPt );
|
||||||
|
int64_t distSq = rectNearestPt.SquaredDistance( circleNearestPt );
|
||||||
|
|
||||||
|
if( distSq < aDistSq )
|
||||||
|
{
|
||||||
|
aDistSq = distSq;
|
||||||
|
aPtA = rectNearestPt;
|
||||||
|
aPtB = circleNearestPt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SHAPE_ARC::NearestPoints( const SHAPE_ARC& aArc, VECTOR2I& aPtA, VECTOR2I& aPtB,
|
bool SHAPE_ARC::NearestPoints( const SHAPE_ARC& aArc, VECTOR2I& aPtA, VECTOR2I& aPtB,
|
||||||
int64_t& aDistSq ) const
|
int64_t& aDistSq ) const
|
||||||
{
|
{
|
||||||
|
@ -548,14 +548,30 @@ static inline bool Collide( const SHAPE_ARC& aA, const SHAPE_RECT& aB, int aClea
|
|||||||
static inline bool Collide( const SHAPE_ARC& aA, const SHAPE_CIRCLE& aB, int aClearance,
|
static inline bool Collide( const SHAPE_ARC& aA, const SHAPE_CIRCLE& aB, int aClearance,
|
||||||
int* aActual, VECTOR2I* aLocation, VECTOR2I* aMTV )
|
int* aActual, VECTOR2I* aLocation, VECTOR2I* aMTV )
|
||||||
{
|
{
|
||||||
const SHAPE_LINE_CHAIN lc( aA );
|
VECTOR2I ptA, ptB;
|
||||||
|
int64_t dist_sq = std::numeric_limits<int64_t>::max();
|
||||||
|
aA.NearestPoints( aB, ptA, ptB, dist_sq );
|
||||||
|
int half_width = ( aA.GetWidth() + 1 ) / 2;
|
||||||
|
int min_dist = aClearance + half_width;
|
||||||
|
|
||||||
bool rv = Collide( aB, lc, aClearance + aA.GetWidth() / 2, aActual, aLocation, aMTV );
|
if( dist_sq < SEG::Square( min_dist ) )
|
||||||
|
{
|
||||||
|
if( aLocation )
|
||||||
|
*aLocation = ( ptA + ptB ) / 2;
|
||||||
|
|
||||||
if( rv && aActual )
|
if( aActual )
|
||||||
*aActual = std::max( 0, *aActual - aA.GetWidth() / 2 );
|
*aActual = std::max( 0, KiROUND( std::sqrt( dist_sq ) - half_width ) );
|
||||||
|
|
||||||
return rv;
|
if( aMTV )
|
||||||
|
{
|
||||||
|
const VECTOR2I delta = ptB - ptA;
|
||||||
|
*aMTV = delta.Resize( min_dist - std::sqrt( dist_sq ) + 3 );
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -831,7 +831,7 @@ bool LINE_PLACER::rhMarkObstacles( const VECTOR2I& aP, LINE& aNewHead, LINE& aNe
|
|||||||
DIRECTION_45::CORNER_MODE cornerMode = Settings().GetCornerMode();
|
DIRECTION_45::CORNER_MODE cornerMode = Settings().GetCornerMode();
|
||||||
|
|
||||||
if( cornerMode == DIRECTION_45::MITERED_90 || cornerMode == DIRECTION_45::ROUNDED_90 )
|
if( cornerMode == DIRECTION_45::MITERED_90 || cornerMode == DIRECTION_45::ROUNDED_90 )
|
||||||
nearest = hull.BBox().ClosestPointTo( aP );
|
nearest = hull.BBox().NearestPoint( aP );
|
||||||
else
|
else
|
||||||
nearest = hull.NearestPoint( aP );
|
nearest = hull.NearestPoint( aP );
|
||||||
|
|
||||||
|
248
qa/data/pcbnew/issue18203.kicad_pcb
Normal file
248
qa/data/pcbnew/issue18203.kicad_pcb
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
(kicad_pcb
|
||||||
|
(version 20240108)
|
||||||
|
(generator "pcbnew")
|
||||||
|
(generator_version "8.0")
|
||||||
|
(general
|
||||||
|
(thickness 1.6)
|
||||||
|
(legacy_teardrops no)
|
||||||
|
)
|
||||||
|
(paper "A4")
|
||||||
|
(layers
|
||||||
|
(0 "F.Cu" signal)
|
||||||
|
(31 "B.Cu" signal)
|
||||||
|
(32 "B.Adhes" user "B.Adhesive")
|
||||||
|
(33 "F.Adhes" user "F.Adhesive")
|
||||||
|
(34 "B.Paste" user)
|
||||||
|
(35 "F.Paste" user)
|
||||||
|
(36 "B.SilkS" user "B.Silkscreen")
|
||||||
|
(37 "F.SilkS" user "F.Silkscreen")
|
||||||
|
(38 "B.Mask" user)
|
||||||
|
(39 "F.Mask" user)
|
||||||
|
(40 "Dwgs.User" user "User.Drawings")
|
||||||
|
(41 "Cmts.User" user "User.Comments")
|
||||||
|
(42 "Eco1.User" user "User.Eco1")
|
||||||
|
(43 "Eco2.User" user "User.Eco2")
|
||||||
|
(44 "Edge.Cuts" user)
|
||||||
|
(45 "Margin" user)
|
||||||
|
(46 "B.CrtYd" user "B.Courtyard")
|
||||||
|
(47 "F.CrtYd" user "F.Courtyard")
|
||||||
|
(48 "B.Fab" user)
|
||||||
|
(49 "F.Fab" user)
|
||||||
|
(50 "User.1" user)
|
||||||
|
(51 "User.2" user)
|
||||||
|
(52 "User.3" user)
|
||||||
|
(53 "User.4" user)
|
||||||
|
(54 "User.5" user)
|
||||||
|
(55 "User.6" user)
|
||||||
|
(56 "User.7" user)
|
||||||
|
(57 "User.8" user)
|
||||||
|
(58 "User.9" user)
|
||||||
|
)
|
||||||
|
(setup
|
||||||
|
(pad_to_mask_clearance 0)
|
||||||
|
(allow_soldermask_bridges_in_footprints no)
|
||||||
|
(pcbplotparams
|
||||||
|
(layerselection 0x00010fc_ffffffff)
|
||||||
|
(plot_on_all_layers_selection 0x0000000_00000000)
|
||||||
|
(disableapertmacros no)
|
||||||
|
(usegerberextensions no)
|
||||||
|
(usegerberattributes yes)
|
||||||
|
(usegerberadvancedattributes yes)
|
||||||
|
(creategerberjobfile yes)
|
||||||
|
(dashed_line_dash_ratio 12.000000)
|
||||||
|
(dashed_line_gap_ratio 3.000000)
|
||||||
|
(svgprecision 4)
|
||||||
|
(plotframeref no)
|
||||||
|
(viasonmask no)
|
||||||
|
(mode 1)
|
||||||
|
(useauxorigin no)
|
||||||
|
(hpglpennumber 1)
|
||||||
|
(hpglpenspeed 20)
|
||||||
|
(hpglpendiameter 15.000000)
|
||||||
|
(pdf_front_fp_property_popups yes)
|
||||||
|
(pdf_back_fp_property_popups yes)
|
||||||
|
(dxfpolygonmode yes)
|
||||||
|
(dxfimperialunits yes)
|
||||||
|
(dxfusepcbnewfont yes)
|
||||||
|
(psnegative no)
|
||||||
|
(psa4output no)
|
||||||
|
(plotreference yes)
|
||||||
|
(plotvalue yes)
|
||||||
|
(plotfptext yes)
|
||||||
|
(plotinvisibletext no)
|
||||||
|
(sketchpadsonfab no)
|
||||||
|
(subtractmaskfromsilk no)
|
||||||
|
(outputformat 1)
|
||||||
|
(mirror no)
|
||||||
|
(drillshape 1)
|
||||||
|
(scaleselection 1)
|
||||||
|
(outputdirectory "")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(net 0 "")
|
||||||
|
(footprint "MountingHole:MountingHole_3.2mm_M3_ISO14580_Pad"
|
||||||
|
(layer "F.Cu")
|
||||||
|
(uuid "7726c890-db15-4ad7-814e-dd8447b43ed2")
|
||||||
|
(at 70.3 153.4)
|
||||||
|
(descr "Mounting Hole 3.2mm, M3, ISO14580")
|
||||||
|
(tags "mounting hole 3.2mm m3 iso14580")
|
||||||
|
(property "Reference" "H205"
|
||||||
|
(at 0 -3.75 0)
|
||||||
|
(layer "F.SilkS")
|
||||||
|
(hide yes)
|
||||||
|
(uuid "69cccef0-a8a2-48a2-be02-3b276d7072c3")
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1 1)
|
||||||
|
(thickness 0.15)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Value" "M3"
|
||||||
|
(at 0 3.75 0)
|
||||||
|
(layer "F.Fab")
|
||||||
|
(hide yes)
|
||||||
|
(uuid "1b7e40fa-418f-45d5-b0d9-c3f086a93cf6")
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1 1)
|
||||||
|
(thickness 0.15)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Footprint" "MountingHole:MountingHole_3.2mm_M3_ISO14580_Pad"
|
||||||
|
(at 0 0 0)
|
||||||
|
(unlocked yes)
|
||||||
|
(layer "F.Fab")
|
||||||
|
(hide yes)
|
||||||
|
(uuid "cda40eb5-55d9-4984-922a-3cd45a7fcb03")
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
(thickness 0.15)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Datasheet" ""
|
||||||
|
(at 0 0 0)
|
||||||
|
(unlocked yes)
|
||||||
|
(layer "F.Fab")
|
||||||
|
(hide yes)
|
||||||
|
(uuid "9612decc-23e6-4abe-a20f-28237de64d36")
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
(thickness 0.15)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(property "Description" "Mounting Hole with connection"
|
||||||
|
(at 0 0 0)
|
||||||
|
(unlocked yes)
|
||||||
|
(layer "F.Fab")
|
||||||
|
(hide yes)
|
||||||
|
(uuid "33191b5e-4a3b-4d2f-bdd1-90692f6686a8")
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1.27 1.27)
|
||||||
|
(thickness 0.15)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(attr exclude_from_pos_files exclude_from_bom)
|
||||||
|
(fp_circle
|
||||||
|
(center 0 0)
|
||||||
|
(end 2.75 0)
|
||||||
|
(stroke
|
||||||
|
(width 0.15)
|
||||||
|
(type solid)
|
||||||
|
)
|
||||||
|
(fill none)
|
||||||
|
(layer "Cmts.User")
|
||||||
|
(uuid "49f8db1f-3f32-4c10-83f5-25b68933e968")
|
||||||
|
)
|
||||||
|
(fp_circle
|
||||||
|
(center 0 0)
|
||||||
|
(end 3 0)
|
||||||
|
(stroke
|
||||||
|
(width 0.05)
|
||||||
|
(type solid)
|
||||||
|
)
|
||||||
|
(fill none)
|
||||||
|
(layer "F.CrtYd")
|
||||||
|
(uuid "618b7e68-8d12-46da-9dff-96876e14c0ad")
|
||||||
|
)
|
||||||
|
(fp_text user "${REFERENCE}"
|
||||||
|
(at 0 0 0)
|
||||||
|
(layer "F.Fab")
|
||||||
|
(uuid "29fb7ad8-c6ed-480b-ade2-449708344f36")
|
||||||
|
(effects
|
||||||
|
(font
|
||||||
|
(size 1 1)
|
||||||
|
(thickness 0.15)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(pad "1" thru_hole circle
|
||||||
|
(at 0 0)
|
||||||
|
(size 5 5.5)
|
||||||
|
(drill 3.2)
|
||||||
|
(layers "*.Cu" "*.Mask")
|
||||||
|
(remove_unused_layers no)
|
||||||
|
(pinfunction "1")
|
||||||
|
(pintype "input+no_connect")
|
||||||
|
(uuid "d7f69fe4-85ef-4985-a12a-043b32cbe18d")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(gr_line
|
||||||
|
(start 67.3 153.4)
|
||||||
|
(end 67.3 140.7)
|
||||||
|
(stroke
|
||||||
|
(width 0.1)
|
||||||
|
(type default)
|
||||||
|
)
|
||||||
|
(layer "Edge.Cuts")
|
||||||
|
(uuid "97b5451b-be12-48cb-97bb-046b12351275")
|
||||||
|
)
|
||||||
|
(gr_line
|
||||||
|
(start 67.3 140.7)
|
||||||
|
(end 80.1 140.7)
|
||||||
|
(stroke
|
||||||
|
(width 0.1)
|
||||||
|
(type default)
|
||||||
|
)
|
||||||
|
(layer "Edge.Cuts")
|
||||||
|
(uuid "a45d033f-eded-4908-8b8b-a4856e094f4d")
|
||||||
|
)
|
||||||
|
(gr_arc
|
||||||
|
(start 70.3 156.4)
|
||||||
|
(mid 68.178686 155.521314)
|
||||||
|
(end 67.3 153.4)
|
||||||
|
(stroke
|
||||||
|
(width 0.1)
|
||||||
|
(type default)
|
||||||
|
)
|
||||||
|
(layer "Edge.Cuts")
|
||||||
|
(uuid "aa375595-1206-4739-8744-4e01967a5e45")
|
||||||
|
)
|
||||||
|
(gr_line
|
||||||
|
(start 80.1 156.4)
|
||||||
|
(end 70.3 156.4)
|
||||||
|
(stroke
|
||||||
|
(width 0.1)
|
||||||
|
(type default)
|
||||||
|
)
|
||||||
|
(layer "Edge.Cuts")
|
||||||
|
(uuid "d1e9169a-9d96-4c1d-9c99-bceeb7cce997")
|
||||||
|
)
|
||||||
|
(gr_line
|
||||||
|
(start 80.1 140.7)
|
||||||
|
(end 80.1 156.4)
|
||||||
|
(stroke
|
||||||
|
(width 0.1)
|
||||||
|
(type default)
|
||||||
|
)
|
||||||
|
(layer "Edge.Cuts")
|
||||||
|
(uuid "f6a2d3af-1670-4475-9393-9f14f5ab578f")
|
||||||
|
)
|
||||||
|
)
|
@ -119,31 +119,31 @@ BOOST_AUTO_TEST_CASE( test_closest_point_to, *boost::unit_test::tolerance( 0.000
|
|||||||
// check all quadrants
|
// check all quadrants
|
||||||
|
|
||||||
// top left
|
// top left
|
||||||
BOOST_TEST( box.ClosestPointTo( VECTOR2D( 0, 0 ) ) == VECTOR2D( 1, 2 ) );
|
BOOST_TEST( box.NearestPoint( VECTOR2D( 0, 0 ) ) == VECTOR2D( 1, 2 ) );
|
||||||
|
|
||||||
// top
|
// top
|
||||||
BOOST_TEST( box.ClosestPointTo( VECTOR2D( 2, 0 ) ) == VECTOR2D( 2, 2 ) );
|
BOOST_TEST( box.NearestPoint( VECTOR2D( 2, 0 ) ) == VECTOR2D( 2, 2 ) );
|
||||||
|
|
||||||
// top right
|
// top right
|
||||||
BOOST_TEST( box.ClosestPointTo( VECTOR2D( 6, 0 ) ) == VECTOR2D( 4, 2 ) );
|
BOOST_TEST( box.NearestPoint( VECTOR2D( 6, 0 ) ) == VECTOR2D( 4, 2 ) );
|
||||||
|
|
||||||
// right
|
// right
|
||||||
BOOST_TEST( box.ClosestPointTo( VECTOR2D( 6, 5 ) ) == VECTOR2D( 4, 5 ) );
|
BOOST_TEST( box.NearestPoint( VECTOR2D( 6, 5 ) ) == VECTOR2D( 4, 5 ) );
|
||||||
|
|
||||||
// bottom right
|
// bottom right
|
||||||
BOOST_TEST( box.ClosestPointTo( VECTOR2D( 6, 7 ) ) == VECTOR2D( 4, 6 ) );
|
BOOST_TEST( box.NearestPoint( VECTOR2D( 6, 7 ) ) == VECTOR2D( 4, 6 ) );
|
||||||
|
|
||||||
// bottom
|
// bottom
|
||||||
BOOST_TEST( box.ClosestPointTo( VECTOR2D( 3, 7 ) ) == VECTOR2D( 3, 6 ) );
|
BOOST_TEST( box.NearestPoint( VECTOR2D( 3, 7 ) ) == VECTOR2D( 3, 6 ) );
|
||||||
|
|
||||||
// bottom left
|
// bottom left
|
||||||
BOOST_TEST( box.ClosestPointTo( VECTOR2D( 0, 7 ) ) == VECTOR2D( 1, 6 ) );
|
BOOST_TEST( box.NearestPoint( VECTOR2D( 0, 7 ) ) == VECTOR2D( 1, 6 ) );
|
||||||
|
|
||||||
// left
|
// left
|
||||||
BOOST_TEST( box.ClosestPointTo( VECTOR2D( 0, 3 ) ) == VECTOR2D( 1, 3 ) );
|
BOOST_TEST( box.NearestPoint( VECTOR2D( 0, 3 ) ) == VECTOR2D( 1, 3 ) );
|
||||||
|
|
||||||
// inside
|
// inside
|
||||||
BOOST_TEST( box.ClosestPointTo( VECTOR2D( 2, 4 ) ) == VECTOR2D( 2, 4 ) );
|
BOOST_TEST( box.NearestPoint( VECTOR2D( 2, 4 ) ) == VECTOR2D( 2, 4 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( test_farthest_point_to, *boost::unit_test::tolerance( 0.000001 ) )
|
BOOST_AUTO_TEST_CASE( test_farthest_point_to, *boost::unit_test::tolerance( 0.000001 ) )
|
||||||
|
@ -66,6 +66,7 @@ BOOST_FIXTURE_TEST_CASE( DRCFalsePositiveRegressions, DRC_REGRESSION_TEST_FIXTUR
|
|||||||
"issue15280", // Very wide spokes mis-counted as being single spoke
|
"issue15280", // Very wide spokes mis-counted as being single spoke
|
||||||
"issue14008", // Net-tie clearance error
|
"issue14008", // Net-tie clearance error
|
||||||
"issue17967/issue17967", // Arc dp coupling
|
"issue17967/issue17967", // Arc dp coupling
|
||||||
|
"issue18203", // DRC error due to colliding arc and circle
|
||||||
"unconnected-netnames/unconnected-netnames", // Raised false schematic partity error
|
"unconnected-netnames/unconnected-netnames", // Raised false schematic partity error
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user