KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sch_line.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <base_units.h>
26#include <bitmaps.h>
27#include <string_utils.h>
28#include <core/mirror.h>
29#include <sch_painter.h>
30#include <sch_plotter.h>
32#include <sch_line.h>
33#include <sch_edit_frame.h>
35#include <schematic.h>
36#include <connection_graph.h>
39#include <trigo.h>
40#include <board_item.h>
41
42
43SCH_LINE::SCH_LINE( const VECTOR2I& pos, int layer ) :
44 SCH_ITEM( nullptr, SCH_LINE_T )
45{
46 m_start = pos;
47 m_end = pos;
48 m_stroke.SetWidth( 0 );
49 m_stroke.SetLineStyle( LINE_STYLE::DEFAULT );
50 m_stroke.SetColor( COLOR4D::UNSPECIFIED );
51
52 switch( layer )
53 {
54 default: m_layer = LAYER_NOTES; break;
55 case LAYER_WIRE: m_layer = LAYER_WIRE; break;
56 case LAYER_BUS: m_layer = LAYER_BUS; break;
57 }
58
59 if( layer == LAYER_NOTES )
61 else
63
64 if( layer == LAYER_WIRE )
66 else if( layer == LAYER_BUS )
68 else
70
71 m_lastResolvedLineStyle = LINE_STYLE::SOLID;
72 m_lastResolvedColor = COLOR4D::UNSPECIFIED;
73}
74
75
77 SCH_ITEM( aLine )
78{
79 m_start = aLine.m_start;
80 m_end = aLine.m_end;
81 m_stroke = aLine.m_stroke;
84
88
90}
91
92
94{
95 switch( GetLayer() )
96 {
97 case LAYER_WIRE: return _( "Wire" );
98 case LAYER_BUS: return _( "Bus" );
99 default: return _( "Graphic Line" );
100 }
101}
102
103
104wxString SCH_LINE::GetNetname( const SCH_SHEET_PATH& aSheet )
105{
106 std::list<const SCH_LINE *> checkedLines;
107 checkedLines.push_back(this);
108 return FindWireSegmentNetNameRecursive( this, checkedLines, aSheet );
109}
110
111
113 std::list<const SCH_LINE *> &checkedLines,
114 const SCH_SHEET_PATH& aSheet ) const
115{
116 for ( auto connected : line->ConnectedItems( aSheet ) )
117 {
118 if( connected->Type() == SCH_LINE_T )
119 {
120 if( std::find(checkedLines.begin(), checkedLines.end(), connected ) == checkedLines.end() )
121 {
122 SCH_LINE* connectedLine = static_cast<SCH_LINE*>( connected );
123 checkedLines.push_back( connectedLine );
124
125 wxString netName = FindWireSegmentNetNameRecursive( connectedLine, checkedLines,
126 aSheet );
127
128 if( !netName.IsEmpty() )
129 return netName;
130 }
131 }
132 else if( connected->Type() == SCH_LABEL_T
133 || connected->Type() == SCH_GLOBAL_LABEL_T
134 || connected->Type() == SCH_DIRECTIVE_LABEL_T)
135 {
136 return static_cast<SCH_TEXT*>( connected )->GetText();
137 }
138
139 }
140 return "";
141}
142
143
145{
146 return new SCH_LINE( *this );
147}
148
149
150void SCH_LINE::Move( const VECTOR2I& aOffset )
151{
152 m_start += aOffset;
153 m_end += aOffset;
154}
155
156
157void SCH_LINE::MoveStart( const VECTOR2I& aOffset )
158{
159 m_start += aOffset;
160}
161
162
163void SCH_LINE::MoveEnd( const VECTOR2I& aOffset )
164{
165 m_end += aOffset;
166}
167
168
169#if defined(DEBUG)
170
171void SCH_LINE::Show( int nestLevel, std::ostream& os ) const
172{
173 NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str()
174 << " layer=\"" << m_layer << '"'
175 << " startIsDangling=\"" << m_startIsDangling
176 << '"' << " endIsDangling=\""
177 << m_endIsDangling << '"' << ">"
178 << " <start" << m_start << "/>"
179 << " <end" << m_end << "/>" << "</"
180 << GetClass().Lower().mb_str() << ">\n";
181}
182
183#endif
184
185
186void SCH_LINE::ViewGetLayers( int aLayers[], int& aCount ) const
187{
188 aCount = 4;
189 aLayers[0] = LAYER_DANGLING;
190 aLayers[1] = m_layer;
191 aLayers[2] = LAYER_SELECTION_SHADOWS;
192 aLayers[3] = LAYER_OP_VOLTAGES;
193}
194
195
196double SCH_LINE::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
197{
198 constexpr double HIDE = std::numeric_limits<double>::max();
199 constexpr double SHOW = 0.0;
200
201 if( aLayer == LAYER_OP_VOLTAGES )
202 {
203 if( m_start == m_end )
204 return HIDE;
205
206 int height = std::abs( m_end.y - m_start.y );
207 int width = std::abs( m_end.x - m_start.x );
208
209 // Operating points will be shown only if zoom is appropriate
210 if( height == 0 )
211 return (double) schIUScale.mmToIU( 15 ) / width;
212 else
213 return (double) schIUScale.mmToIU( 5 ) / height;
214 }
215
216 // Other layers are always drawn.
217 return SHOW;
218}
219
220
222{
223 int width = GetPenWidth() / 2;
224
225 int xmin = std::min( m_start.x, m_end.x ) - width;
226 int ymin = std::min( m_start.y, m_end.y ) - width;
227
228 int xmax = std::max( m_start.x, m_end.x ) + width + 1;
229 int ymax = std::max( m_start.y, m_end.y ) + width + 1;
230
231 BOX2I ret( VECTOR2I( xmin, ymin ), VECTOR2I( xmax - xmin, ymax - ymin ) );
232
233 return ret;
234}
235
236
238{
239 return GetLineLength( m_start, m_end );
240}
241
242
243void SCH_LINE::SetLineColor( const COLOR4D& aColor )
244{
245 m_stroke.SetColor( aColor );
247}
248
249
250void SCH_LINE::SetLineColor( const double r, const double g, const double b, const double a )
251{
252 COLOR4D newColor(r, g, b, a);
253
254 if( newColor == COLOR4D::UNSPECIFIED )
255 {
256 m_stroke.SetColor( COLOR4D::UNSPECIFIED );
257 }
258 else
259 {
260 // Eeschema does not allow alpha channel in colors
261 newColor.a = 1.0;
262 m_stroke.SetColor( newColor );
263 }
264}
265
266
268{
269 if( m_stroke.GetColor() != COLOR4D::UNSPECIFIED )
271 else if( !IsConnectable() )
272 m_lastResolvedColor = COLOR4D::UNSPECIFIED;
273 else if( !IsConnectivityDirty() )
274 m_lastResolvedColor = GetEffectiveNetClass()->GetSchematicColor();
275
276 return m_lastResolvedColor;
277}
278
279
280void SCH_LINE::SetLineStyle( const int aStyleId )
281{
282 SetLineStyle( static_cast<LINE_STYLE>( aStyleId ) );
283}
284
285
287{
288 m_stroke.SetLineStyle( aStyle );
290}
291
292
294{
295 if( m_stroke.GetLineStyle() != LINE_STYLE::DEFAULT )
296 return m_stroke.GetLineStyle();
297
298 return LINE_STYLE::SOLID;
299}
300
301
303{
304 if( m_stroke.GetLineStyle() != LINE_STYLE::DEFAULT )
306 else if( !IsConnectable() )
307 m_lastResolvedLineStyle = LINE_STYLE::SOLID;
308 else if( !IsConnectivityDirty() )
310
312}
313
314
315void SCH_LINE::SetLineWidth( const int aSize )
316{
317 m_stroke.SetWidth( aSize );
319}
320
321
323{
324 SCHEMATIC* schematic = Schematic();
325
326 switch ( m_layer )
327 {
328 default:
329 if( m_stroke.GetWidth() > 0 )
330 return m_stroke.GetWidth();
331
332 if( schematic )
333 return schematic->Settings().m_DefaultLineWidth;
334
336
337 case LAYER_WIRE:
338 if( m_stroke.GetWidth() > 0 )
340 else if( !IsConnectivityDirty() )
341 m_lastResolvedWidth = GetEffectiveNetClass()->GetWireWidth();
342
343 return m_lastResolvedWidth;
344
345 case LAYER_BUS:
346 if( m_stroke.GetWidth() > 0 )
348 else if( !IsConnectivityDirty() )
349 m_lastResolvedWidth = GetEffectiveNetClass()->GetBusWidth();
350
351 return m_lastResolvedWidth;
352 }
353}
354
355
356void SCH_LINE::Print( const RENDER_SETTINGS* aSettings, const VECTOR2I& offset )
357{
358 wxDC* DC = aSettings->GetPrintDC();
360
361 if( color == COLOR4D::UNSPECIFIED )
362 color = aSettings->GetLayerColor( GetLayer() );
363
364 VECTOR2I start = m_start;
365 VECTOR2I end = m_end;
366 LINE_STYLE lineStyle = GetEffectiveLineStyle();
367 int penWidth = std::max( GetPenWidth(), aSettings->GetDefaultPenWidth() );
368
369 if( lineStyle <= LINE_STYLE::FIRST_TYPE )
370 {
371 GRLine( DC, start.x, start.y, end.x, end.y, penWidth, color );
372 }
373 else
374 {
375 SHAPE_SEGMENT segment( start, end );
376
377 STROKE_PARAMS::Stroke( &segment, lineStyle, penWidth, aSettings,
378 [&]( const VECTOR2I& a, const VECTOR2I& b )
379 {
380 GRLine( DC, a.x, a.y, b.x, b.y, penWidth, color );
381 } );
382 }
383}
384
385
386void SCH_LINE::MirrorVertically( int aCenter )
387{
388 if( m_flags & STARTPOINT )
389 MIRROR( m_start.y, aCenter );
390
391 if( m_flags & ENDPOINT )
392 MIRROR( m_end.y, aCenter );
393}
394
395
397{
398 if( m_flags & STARTPOINT )
399 MIRROR( m_start.x, aCenter );
400
401 if( m_flags & ENDPOINT )
402 MIRROR( m_end.x, aCenter );
403}
404
405
406void SCH_LINE::Rotate( const VECTOR2I& aCenter )
407{
408 // When we allow off grid items, the
409 // else if should become a plain if to allow
410 // rotation around the center of the line
411 if( m_flags & STARTPOINT )
412 RotatePoint( m_start, aCenter, ANGLE_90 );
413
414 else if( m_flags & ENDPOINT )
415 RotatePoint( m_end, aCenter, ANGLE_90 );
416}
417
418
419void SCH_LINE::RotateStart( const VECTOR2I& aCenter )
420{
421 RotatePoint( m_start, aCenter, ANGLE_90 );
422}
423
424
425void SCH_LINE::RotateEnd( const VECTOR2I& aCenter )
426{
427 RotatePoint( m_end, aCenter, ANGLE_90 );
428}
429
430
431int SCH_LINE::GetAngleFrom( const VECTOR2I& aPoint ) const
432{
433 VECTOR2I vec;
434
435 if( aPoint == m_start )
436 vec = m_end - aPoint;
437 else
438 vec = m_start - aPoint;
439
440 return KiROUND( EDA_ANGLE( vec ).AsDegrees() );
441}
442
443
444int SCH_LINE::GetReverseAngleFrom( const VECTOR2I& aPoint ) const
445{
446 VECTOR2I vec;
447
448 if( aPoint == m_end )
449 vec = m_start - aPoint;
450 else
451 vec = m_end - aPoint;
452
453 return KiROUND( EDA_ANGLE( vec ).AsDegrees() );
454}
455
456
457bool SCH_LINE::IsParallel( const SCH_LINE* aLine ) const
458{
459 wxCHECK_MSG( aLine != nullptr && aLine->Type() == SCH_LINE_T, false,
460 wxT( "Cannot test line segment for overlap." ) );
461
462 VECTOR2I firstSeg = m_end - m_start;
463 VECTOR2I secondSeg = aLine->m_end - aLine->m_start;
464
465 // Use long long here to avoid overflow in calculations
466 return !( (long long) firstSeg.x * secondSeg.y - (long long) firstSeg.y * secondSeg.x );
467}
468
469
470SCH_LINE* SCH_LINE::MergeOverlap( SCH_SCREEN* aScreen, SCH_LINE* aLine, bool aCheckJunctions )
471{
472 auto less =
473 []( const VECTOR2I& lhs, const VECTOR2I& rhs ) -> bool
474 {
475 if( lhs.x == rhs.x )
476 return lhs.y < rhs.y;
477
478 return lhs.x < rhs.x;
479 };
480
481 wxCHECK_MSG( aLine != nullptr && aLine->Type() == SCH_LINE_T, nullptr,
482 wxT( "Cannot test line segment for overlap." ) );
483
484 if( this == aLine || GetLayer() != aLine->GetLayer() )
485 return nullptr;
486
487 VECTOR2I leftmost_start = aLine->m_start;
488 VECTOR2I leftmost_end = aLine->m_end;
489
490 VECTOR2I rightmost_start = m_start;
491 VECTOR2I rightmost_end = m_end;
492
493 // We place the start to the left and below the end of both lines
494 if( leftmost_start != std::min( { leftmost_start, leftmost_end }, less ) )
495 std::swap( leftmost_start, leftmost_end );
496 if( rightmost_start != std::min( { rightmost_start, rightmost_end }, less ) )
497 std::swap( rightmost_start, rightmost_end );
498
499 // - leftmost is the line that starts farthest to the left
500 // - other is the line that is _not_ leftmost
501 // - rightmost is the line that ends farthest to the right. This may or may not be 'other'
502 // as the second line may be completely covered by the first.
503 if( less( rightmost_start, leftmost_start ) )
504 {
505 std::swap( leftmost_start, rightmost_start );
506 std::swap( leftmost_end, rightmost_end );
507 }
508
509 VECTOR2I other_start = rightmost_start;
510 VECTOR2I other_end = rightmost_end;
511
512 if( less( rightmost_end, leftmost_end ) )
513 {
514 rightmost_start = leftmost_start;
515 rightmost_end = leftmost_end;
516 }
517
518 // If we end one before the beginning of the other, no overlap is possible
519 if( less( leftmost_end, other_start ) )
520 {
521 return nullptr;
522 }
523
524 // Search for a common end:
525 if( ( leftmost_start == other_start ) && ( leftmost_end == other_end ) ) // Trivial case
526 {
527 SCH_LINE* ret = new SCH_LINE( *aLine );
528 ret->SetStartPoint( leftmost_start );
529 ret->SetEndPoint( leftmost_end );
530 ret->SetConnectivityDirty( true );
531
532 if( IsSelected() || aLine->IsSelected() )
533 ret->SetSelected();
534
535 return ret;
536 }
537
538 bool colinear = false;
539
540 /* Test alignment: */
541 if( ( leftmost_start.y == leftmost_end.y ) &&
542 ( other_start.y == other_end.y ) ) // Horizontal segment
543 {
544 colinear = ( leftmost_start.y == other_start.y );
545 }
546 else if( ( leftmost_start.x == leftmost_end.x ) &&
547 ( other_start.x == other_end.x ) ) // Vertical segment
548 {
549 colinear = ( leftmost_start.x == other_start.x );
550 }
551 else
552 {
553 // We use long long here to avoid overflow -- it enforces promotion
554 // The slope of the left-most line is dy/dx. Then we check that the slope from the
555 // left most start to the right most start is the same as well as the slope from the
556 // left most start to right most end.
557 long long dx = leftmost_end.x - leftmost_start.x;
558 long long dy = leftmost_end.y - leftmost_start.y;
559 colinear = ( ( ( other_start.y - leftmost_start.y ) * dx ==
560 ( other_start.x - leftmost_start.x ) * dy ) &&
561 ( ( other_end.y - leftmost_start.y ) * dx ==
562 ( other_end.x - leftmost_start.x ) * dy ) );
563 }
564
565 if( !colinear )
566 return nullptr;
567
568 // We either have a true overlap or colinear touching segments. We always want to merge
569 // the former, but the later only get merged if there no junction at the touch point.
570
571 bool touching = leftmost_end == rightmost_start;
572
573 if( touching && aCheckJunctions && aScreen->IsJunction( leftmost_end ) )
574 return nullptr;
575
576 // Make a new segment that merges the 2 segments
577 leftmost_end = rightmost_end;
578
579 SCH_LINE* ret = new SCH_LINE( *aLine );
580 ret->SetStartPoint( leftmost_start );
581 ret->SetEndPoint( leftmost_end );
582 ret->SetConnectivityDirty( true );
583
584 if( IsSelected() || aLine->IsSelected() )
585 ret->SetSelected();
586
587 return ret;
588}
589
590
592{
593 SCH_LINE* newSegment = static_cast<SCH_LINE*>( Duplicate() );
594
595 newSegment->SetStartPoint( aPoint );
596 newSegment->SetConnectivityDirty( true );
597 SetEndPoint( aPoint );
598
599 return newSegment;
600}
601
602
603void SCH_LINE::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
604{
605 if( IsConnectable() )
606 {
607 aItemList.emplace_back( IsBus() ? BUS_END : WIRE_END, this, m_start );
608 aItemList.emplace_back( IsBus() ? BUS_END : WIRE_END, this, m_end );
609 }
610}
611
612
613bool SCH_LINE::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList,
614 const SCH_SHEET_PATH* aPath )
615{
616 if( IsConnectable() )
617 {
618 bool previousStartState = m_startIsDangling;
619 bool previousEndState = m_endIsDangling;
620
622
623 for( DANGLING_END_ITEM item : aItemList )
624 {
625 if( item.GetItem() == this )
626 continue;
627
628 if( ( IsWire() && item.GetType() != BUS_END && item.GetType() != BUS_ENTRY_END )
629 || ( IsBus() && item.GetType() != WIRE_END && item.GetType() != PIN_END ) )
630 {
631 if( m_start == item.GetPosition() )
632 m_startIsDangling = false;
633
634 if( m_end == item.GetPosition() )
635 m_endIsDangling = false;
636
638 break;
639 }
640 }
641
642 // We only use the bus dangling state for automatic line starting, so we don't care if it
643 // has changed or not (and returning true will result in extra work)
644 if( IsBus() )
645 return false;
646
647 return previousStartState != m_startIsDangling || previousEndState != m_endIsDangling;
648 }
649
650 return false;
651}
652
653
655{
656 if( m_layer == LAYER_WIRE || m_layer == LAYER_BUS )
657 return true;
658
659 return false;
660}
661
662
663bool SCH_LINE::CanConnect( const SCH_ITEM* aItem ) const
664{
665 if( m_layer == LAYER_WIRE )
666 {
667 switch( aItem->Type() )
668 {
669 case SCH_JUNCTION_T:
670 case SCH_NO_CONNECT_T:
671 case SCH_LABEL_T:
673 case SCH_HIER_LABEL_T:
676 case SCH_SYMBOL_T:
677 case SCH_SHEET_T:
678 case SCH_SHEET_PIN_T:
679 return true;
680 default:
681 break;
682 }
683 }
684 else if( m_layer == LAYER_BUS )
685 {
686 switch( aItem->Type() )
687 {
688 case SCH_JUNCTION_T:
689 case SCH_LABEL_T:
691 case SCH_HIER_LABEL_T:
694 case SCH_SHEET_T:
695 case SCH_SHEET_PIN_T:
696 return true;
697 default:
698 break;
699 }
700 }
701
702 return aItem->GetLayer() == m_layer;
703}
704
705
706std::vector<VECTOR2I> SCH_LINE::GetConnectionPoints() const
707{
708 return { m_start, m_end };
709}
710
711
713{
714 switch( aItem->Type() )
715 {
716 case SCH_LINE_T:
717 return IsBus() == static_cast<const SCH_LINE*>( aItem )->IsBus();
718
719 default:
720 return true;
721 }
722}
723
724
725void SCH_LINE::GetSelectedPoints( std::vector<VECTOR2I>& aPoints ) const
726{
727 if( m_flags & STARTPOINT )
728 aPoints.push_back( m_start );
729
730 if( m_flags & ENDPOINT )
731 aPoints.push_back( m_end );
732}
733
734
735wxString SCH_LINE::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
736{
737 wxString txtfmt;
738
739 if( m_start.x == m_end.x )
740 {
741 switch( m_layer )
742 {
743 case LAYER_WIRE: txtfmt = _( "Vertical Wire, length %s" ); break;
744 case LAYER_BUS: txtfmt = _( "Vertical Bus, length %s" ); break;
745 default: txtfmt = _( "Vertical Graphic Line, length %s" ); break;
746 }
747 }
748 else if( m_start.y == m_end.y )
749 {
750 switch( m_layer )
751 {
752 case LAYER_WIRE: txtfmt = _( "Horizontal Wire, length %s" ); break;
753 case LAYER_BUS: txtfmt = _( "Horizontal Bus, length %s" ); break;
754 default: txtfmt = _( "Horizontal Graphic Line, length %s" ); break;
755 }
756 }
757 else
758 {
759 switch( m_layer )
760 {
761 case LAYER_WIRE: txtfmt = _( "Wire, length %s" ); break;
762 case LAYER_BUS: txtfmt = _( "Bus, length %s" ); break;
763 default: txtfmt = _( "Graphic Line, length %s" ); break;
764 }
765 }
766
767 return wxString::Format( txtfmt,
768 aUnitsProvider->MessageTextFromValue( EuclideanNorm( m_start - m_end ) ) );
769}
770
771
773{
774 if( m_layer == LAYER_NOTES )
775 return BITMAPS::add_dashed_line;
776 else if( m_layer == LAYER_WIRE )
777 return BITMAPS::add_line;
778
779 return BITMAPS::add_bus;
780}
781
782
783bool SCH_LINE::operator <( const SCH_ITEM& aItem ) const
784{
785 if( Type() != aItem.Type() )
786 return Type() < aItem.Type();
787
788 const SCH_LINE* line = static_cast<const SCH_LINE*>( &aItem );
789
790 if( GetLayer() != line->GetLayer() )
791 return GetLayer() < line->GetLayer();
792
793 if( GetStartPoint().x != line->GetStartPoint().x )
794 return GetStartPoint().x < line->GetStartPoint().x;
795
796 if( GetStartPoint().y != line->GetStartPoint().y )
797 return GetStartPoint().y < line->GetStartPoint().y;
798
799 if( GetEndPoint().x != line->GetEndPoint().x )
800 return GetEndPoint().x < line->GetEndPoint().x;
801
802 return GetEndPoint().y < line->GetEndPoint().y;
803}
804
805
806bool SCH_LINE::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
807{
808 // Performance enhancement for connection-building
809 if( aPosition == m_start || aPosition == m_end )
810 return true;
811
812 if( aAccuracy >= 0 )
813 aAccuracy += GetPenWidth() / 2;
814 else
815 aAccuracy = abs( aAccuracy );
816
817 return TestSegmentHit( aPosition, m_start, m_end, aAccuracy );
818}
819
820
821bool SCH_LINE::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
822{
824 return false;
825
826 BOX2I rect = aRect;
827
828 if ( aAccuracy )
829 rect.Inflate( aAccuracy );
830
831 if( aContained )
832 return rect.Contains( m_start ) && rect.Contains( m_end );
833
834 return rect.Intersects( m_start, m_end );
835}
836
837
839{
840 SCH_ITEM::SwapFlags( aItem );
841
842 SCH_LINE* item = (SCH_LINE*) aItem;
843
844 std::swap( m_layer, item->m_layer );
845
846 std::swap( m_start, item->m_start );
847 std::swap( m_end, item->m_end );
848 std::swap( m_startIsDangling, item->m_startIsDangling );
849 std::swap( m_endIsDangling, item->m_endIsDangling );
850 std::swap( m_stroke, item->m_stroke );
851}
852
853
854bool SCH_LINE::doIsConnected( const VECTOR2I& aPosition ) const
855{
856 if( m_layer != LAYER_WIRE && m_layer != LAYER_BUS )
857 return false;
858
859 return IsEndPoint( aPosition );
860}
861
862
863void SCH_LINE::Plot( PLOTTER* aPlotter, bool aBackground,
864 const SCH_PLOT_SETTINGS& aPlotSettings ) const
865{
866 if( aBackground )
867 return;
868
869 auto* settings = static_cast<KIGFX::SCH_RENDER_SETTINGS*>( aPlotter->RenderSettings() );
870 int penWidth = std::max( GetPenWidth(), settings->GetMinPenWidth() );
872
873 if( color == COLOR4D::UNSPECIFIED )
874 color = settings->GetLayerColor( GetLayer() );
875
876 aPlotter->SetColor( color );
877
878 aPlotter->SetCurrentLineWidth( penWidth );
879 aPlotter->SetDash( penWidth, GetEffectiveLineStyle() );
880
881 aPlotter->MoveTo( m_start );
882 aPlotter->FinishTo( m_end );
883
884 aPlotter->SetDash( penWidth, LINE_STYLE::SOLID );
885
886 // Plot attributes to a hypertext menu
887 std::vector<wxString> properties;
888 BOX2I bbox = GetBoundingBox();
889 bbox.Inflate( GetPenWidth() * 3 );
890
891 if( aPlotSettings.m_PDFPropertyPopups )
892 {
893 if( GetLayer() == LAYER_WIRE )
894 {
895 if( SCH_CONNECTION* connection = Connection() )
896 {
897 properties.emplace_back( wxString::Format( wxT( "!%s = %s" ),
898 _( "Net" ),
899 connection->Name() ) );
900
901 properties.emplace_back( wxString::Format( wxT( "!%s = %s" ),
902 _( "Resolved netclass" ),
903 GetEffectiveNetClass()->GetName() ) );
904 }
905 }
906 else if( GetLayer() == LAYER_BUS )
907 {
908 if( SCH_CONNECTION* connection = Connection() )
909 {
910 for( const std::shared_ptr<SCH_CONNECTION>& member : connection->Members() )
911 properties.emplace_back( wxT( "!" ) + member->Name() );
912 }
913
914 }
915
916 if( !properties.empty() )
917 aPlotter->HyperlinkMenu( bbox, properties );
918 }
919}
920
921
922void SCH_LINE::SetPosition( const VECTOR2I& aPosition )
923{
924 m_end = m_end - ( m_start - aPosition );
925 m_start = aPosition;
926}
927
928
929void SCH_LINE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
930{
931 wxString msg;
932
933 switch( GetLayer() )
934 {
935 case LAYER_WIRE: msg = _( "Wire" ); break;
936 case LAYER_BUS: msg = _( "Bus" ); break;
937 default: msg = _( "Graphical" ); break;
938 }
939
940 aList.emplace_back( _( "Line Type" ), msg );
941
942 LINE_STYLE lineStyle = GetLineStyle();
943
944 if( GetEffectiveLineStyle() != lineStyle )
945 aList.emplace_back( _( "Line Style" ), _( "from netclass" ) );
946 else
947 m_stroke.GetMsgPanelInfo( aFrame, aList, true, false );
948
949 SCH_CONNECTION* conn = nullptr;
950
951 if( !IsConnectivityDirty() && dynamic_cast<SCH_EDIT_FRAME*>( aFrame ) )
952 conn = Connection();
953
954 if( conn )
955 {
956 conn->AppendInfoToMsgPanel( aList );
957
958 if( !conn->IsBus() )
959 {
960 aList.emplace_back( _( "Resolved Netclass" ),
961 UnescapeString( GetEffectiveNetClass()->GetName() ) );
962 }
963 }
964}
965
966
968{
969 return ( GetLayer() == LAYER_NOTES );
970}
971
972
974{
975 return ( GetLayer() == LAYER_WIRE );
976}
977
978
979bool SCH_LINE::IsBus() const
980{
981 return ( GetLayer() == LAYER_BUS );
982}
983
984
985bool SCH_LINE::operator==( const SCH_ITEM& aOther ) const
986{
987 if( Type() != aOther.Type() )
988 return false;
989
990 const SCH_LINE& other = static_cast<const SCH_LINE&>( aOther );
991
992 if( GetLayer() != other.GetLayer() )
993 return false;
994
995 if( m_start != other.m_start )
996 return false;
997
998 if( m_end != other.m_end )
999 return false;
1000
1001 if( m_stroke.GetWidth() != other.m_stroke.GetWidth() )
1002 return false;
1003
1004 if( m_stroke.GetColor() != other.m_stroke.GetColor() )
1005 return false;
1006
1007 if( m_stroke.GetLineStyle() != other.m_stroke.GetLineStyle() )
1008 return false;
1009
1010 return true;
1011}
1012
1013
1014double SCH_LINE::Similarity( const SCH_ITEM& aOther ) const
1015{
1016 if( m_Uuid == aOther.m_Uuid )
1017 return 1.0;
1018
1019 if( Type() != aOther.Type() )
1020 return 0.0;
1021
1022 const SCH_LINE& other = static_cast<const SCH_LINE&>( aOther );
1023
1024 if( GetLayer() != other.GetLayer() )
1025 return 0.0;
1026
1027 double similarity = 1.0;
1028
1029 if( m_start != other.m_start )
1030 similarity *= 0.9;
1031
1032 if( m_end != other.m_end )
1033 similarity *= 0.9;
1034
1035 if( m_stroke.GetWidth() != other.m_stroke.GetWidth() )
1036 similarity *= 0.9;
1037
1038 if( m_stroke.GetColor() != other.m_stroke.GetColor() )
1039 similarity *= 0.9;
1040
1041 if( m_stroke.GetLineStyle() != other.m_stroke.GetLineStyle() )
1042 similarity *= 0.9;
1043
1044 return similarity;
1045}
1046
1047
1048static struct SCH_LINE_DESC
1049{
1051 {
1053
1054 if( plotDashTypeEnum.Choices().GetCount() == 0 )
1055 {
1056 plotDashTypeEnum.Map( LINE_STYLE::DEFAULT, _HKI( "Default" ) )
1057 .Map( LINE_STYLE::SOLID, _HKI( "Solid" ) )
1058 .Map( LINE_STYLE::DASH, _HKI( "Dashed" ) )
1059 .Map( LINE_STYLE::DOT, _HKI( "Dotted" ) )
1060 .Map( LINE_STYLE::DASHDOT, _HKI( "Dash-Dot" ) )
1061 .Map( LINE_STYLE::DASHDOTDOT, _HKI( "Dash-Dot-Dot" ) );
1062 }
1063
1067
1068 void ( SCH_LINE::*lineStyleSetter )( LINE_STYLE ) = &SCH_LINE::SetLineStyle;
1069
1070 propMgr.AddProperty( new PROPERTY_ENUM<SCH_LINE, LINE_STYLE>( _HKI( "Line Style" ),
1071 lineStyleSetter, &SCH_LINE::GetLineStyle ) );
1072
1073 propMgr.AddProperty( new PROPERTY<SCH_LINE, int>( _HKI( "Line Width" ),
1074 &SCH_LINE::SetLineWidth, &SCH_LINE::GetLineWidth, PROPERTY_DISPLAY::PT_SIZE ) );
1075
1076 propMgr.AddProperty( new PROPERTY<SCH_LINE, COLOR4D>( _HKI( "Color" ),
1078 }
int color
Definition: DXF_plotter.cpp:58
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:111
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:33
bool Intersects(const BOX2< Vec > &aRect) const
Definition: box2.h:270
bool Contains(const Vec &aPoint) const
Definition: box2.h:142
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:507
Helper class used to store the state of schematic items that can be connected to other schematic item...
Definition: sch_item.h:86
The base class for create windows for drawing purpose.
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:85
const KIID m_Uuid
Definition: eda_item.h:482
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
EDA_ITEM_FLAGS m_flags
Definition: eda_item.h:487
bool IsSelected() const
Definition: eda_item.h:106
void SetSelected()
Definition: eda_item.h:115
ENUM_MAP & Map(T aValue, const wxString &aName)
Definition: property.h:646
static ENUM_MAP< T > & Instance()
Definition: property.h:640
wxPGChoices & Choices()
Definition: property.h:689
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
double a
Alpha component.
Definition: color4d.h:379
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
int GetDefaultPenWidth() const
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
wxDC * GetPrintDC() const
Store schematic specific render settings.
Definition: sch_painter.h:71
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:68
Base plotter engine class.
Definition: plotter.h:104
void MoveTo(const VECTOR2I &pos)
Definition: plotter.h:242
virtual void SetDash(int aLineWidth, LINE_STYLE aLineStyle)=0
void FinishTo(const VECTOR2I &pos)
Definition: plotter.h:252
RENDER_SETTINGS * RenderSettings()
Definition: plotter.h:135
virtual void SetCurrentLineWidth(int width, void *aData=nullptr)=0
Set the line width for the next drawing.
virtual void HyperlinkMenu(const BOX2I &aBox, const std::vector< wxString > &aDestURLs)
Create a clickable hyperlink menu with a rectangular click area.
Definition: plotter.h:463
virtual void SetColor(const COLOR4D &color)=0
Provide class metadata.Helper macro to map type hashes to names.
Definition: property_mgr.h:74
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:76
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
Holds all the data relating to one schematic.
Definition: schematic.h:75
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:216
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
bool IsBus() const
void AppendInfoToMsgPanel(std::vector< MSG_PANEL_ITEM > &aList) const
Adds information about the connection object to aList.
Schematic editor (Eeschema) main window.
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:151
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:113
SCH_ITEM_SET & ConnectedItems(const SCH_SHEET_PATH &aPath)
Retrieve the set of items connected to this item on the given sheet.
Definition: sch_item.cpp:197
std::shared_ptr< NETCLASS > GetEffectiveNetClass(const SCH_SHEET_PATH *aSheet=nullptr) const
Definition: sch_item.cpp:176
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
Definition: sch_item.h:258
void SetConnectivityDirty(bool aDirty=true)
Definition: sch_item.h:438
bool IsConnectivityDirty() const
Definition: sch_item.h:436
void SwapFlags(SCH_ITEM *aItem)
Swap the non-temp and non-edit flags.
Definition: sch_item.cpp:267
SCH_CONNECTION * Connection(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieve the connection associated with this object in the given sheet.
Definition: sch_item.cpp:147
SCH_LAYER_ID m_layer
Definition: sch_item.h:521
SCH_ITEM * Duplicate(bool doClone=false) const
Routine to create a new copy of given item.
Definition: sch_item.cpp:94
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:40
int GetPenWidth() const override
Definition: sch_line.cpp:322
void Rotate(const VECTOR2I &aCenter) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition: sch_line.cpp:406
bool doIsConnected(const VECTOR2I &aPosition) const override
Provide the object specific test to see if it is connected to aPosition.
Definition: sch_line.cpp:854
void GetEndPoints(std::vector< DANGLING_END_ITEM > &aItemList) override
Add the schematic item end points to aItemList if the item has end points.
Definition: sch_line.cpp:603
void SetStartPoint(const VECTOR2I &aPosition)
Definition: sch_line.h:141
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: sch_line.cpp:144
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: sch_line.cpp:772
bool m_startIsDangling
True if start point is not connected.
Definition: sch_line.h:349
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
Definition: sch_line.cpp:806
void SetPosition(const VECTOR2I &aPosition) override
Definition: sch_line.cpp:922
std::vector< VECTOR2I > GetConnectionPoints() const override
Add all the connection points for this item to aPoints.
Definition: sch_line.cpp:706
int GetReverseAngleFrom(const VECTOR2I &aPoint) const
Definition: sch_line.cpp:444
double ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
Return the level of detail (LOD) of the item.
Definition: sch_line.cpp:196
SCH_LINE(const VECTOR2I &pos=VECTOR2I(0, 0), int layer=LAYER_NOTES)
Definition: sch_line.cpp:43
bool IsWire() const
Return true if the line is a wire.
Definition: sch_line.cpp:973
void RotateEnd(const VECTOR2I &aCenter)
Definition: sch_line.cpp:425
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: sch_line.cpp:221
void ViewGetLayers(int aLayers[], int &aCount) const override
Return the layers the item is drawn on (which may be more than its "home" layer)
Definition: sch_line.cpp:186
void SetLineColor(const COLOR4D &aColor)
Definition: sch_line.cpp:243
bool CanConnect(const SCH_ITEM *aItem) const override
Definition: sch_line.cpp:663
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider) const override
Return a user-visible description string of this item.
Definition: sch_line.cpp:735
bool IsParallel(const SCH_LINE *aLine) const
Definition: sch_line.cpp:457
void SetLineWidth(const int aSize)
Definition: sch_line.cpp:315
void RotateStart(const VECTOR2I &aCenter)
Definition: sch_line.cpp:419
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
Definition: sch_line.cpp:396
int GetAngleFrom(const VECTOR2I &aPoint) const
Definition: sch_line.cpp:431
void GetSelectedPoints(std::vector< VECTOR2I > &aPoints) const
Definition: sch_line.cpp:725
COLOR4D m_lastResolvedColor
Definition: sch_line.h:361
LINE_STYLE GetEffectiveLineStyle() const
Definition: sch_line.cpp:302
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Populate aList of MSG_PANEL_ITEM objects with it's internal state for display purposes.
Definition: sch_line.cpp:929
wxString m_operatingPoint
Definition: sch_line.h:363
wxString GetClass() const override
Return the class name.
Definition: sch_line.h:59
VECTOR2I GetEndPoint() const
Definition: sch_line.h:145
VECTOR2I GetStartPoint() const
Definition: sch_line.h:140
bool ConnectionPropagatesTo(const EDA_ITEM *aItem) const override
Return true if this item should propagate connection info to aItem.
Definition: sch_line.cpp:712
LINE_STYLE m_lastResolvedLineStyle
Definition: sch_line.h:359
SCH_LINE * MergeOverlap(SCH_SCREEN *aScreen, SCH_LINE *aLine, bool aCheckJunctions)
Check line against aLine to see if it overlaps and merge if it does.
Definition: sch_line.cpp:470
VECTOR2I m_start
Line start point.
Definition: sch_line.h:351
bool IsBus() const
Return true if the line is a bus.
Definition: sch_line.cpp:979
int m_lastResolvedWidth
Definition: sch_line.h:360
void SetLineStyle(const LINE_STYLE aStyle)
Definition: sch_line.cpp:286
VECTOR2I m_end
Line end point.
Definition: sch_line.h:352
void Move(const VECTOR2I &aMoveVector) override
Move the item by aMoveVector to a new position.
Definition: sch_line.cpp:150
bool UpdateDanglingState(std::vector< DANGLING_END_ITEM > &aItemList, const SCH_SHEET_PATH *aPath=nullptr) override
Test the schematic item to aItemList to check if it's dangling state has changed.
Definition: sch_line.cpp:613
LINE_STYLE GetLineStyle() const
Definition: sch_line.cpp:293
void MoveEnd(const VECTOR2I &aMoveVector)
Definition: sch_line.cpp:163
STROKE_PARAMS m_stroke
Line stroke properties.
Definition: sch_line.h:354
bool m_endIsDangling
True if end point is not connected.
Definition: sch_line.h:350
void SwapData(SCH_ITEM *aItem) override
Swap the internal data structures aItem with the schematic item.
Definition: sch_line.cpp:838
bool IsConnectable() const override
Definition: sch_line.cpp:654
wxString GetFriendlyName() const override
Definition: sch_line.cpp:93
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
Definition: sch_line.cpp:386
bool operator==(const SCH_ITEM &aOther) const override
Definition: sch_line.cpp:985
bool operator<(const SCH_ITEM &aItem) const override
Definition: sch_line.cpp:783
void Print(const RENDER_SETTINGS *aSettings, const VECTOR2I &aOffset) override
Print a schematic item.
Definition: sch_line.cpp:356
wxString GetNetname(const SCH_SHEET_PATH &aSheet)
This function travel though all the connected wire segments to look for connected labels.
Definition: sch_line.cpp:104
bool IsEndPoint(const VECTOR2I &aPoint) const
Definition: sch_line.h:94
bool IsGraphicLine() const
Return if the line is a graphic (non electrical line)
Definition: sch_line.cpp:967
void Plot(PLOTTER *aPlotter, bool aBackground, const SCH_PLOT_SETTINGS &aPlotSettings) const override
Plot the schematic item to aPlotter.
Definition: sch_line.cpp:863
int GetLineWidth() const
Definition: sch_line.h:177
COLOR4D GetLineColor() const
Returns COLOR4D::UNSPECIFIED if a custom color hasn't been set for this line.
Definition: sch_line.cpp:267
void MoveStart(const VECTOR2I &aMoveVector)
Definition: sch_line.cpp:157
double GetLength() const
Definition: sch_line.cpp:237
SCH_LINE * BreakAt(const VECTOR2I &aPoint)
Break this segment into two at the specified point.
Definition: sch_line.cpp:591
wxString FindWireSegmentNetNameRecursive(SCH_LINE *line, std::list< const SCH_LINE * > &checkedLines, const SCH_SHEET_PATH &aSheet) const
Recursively called function to travel through the connected wires and find a connected net name label...
Definition: sch_line.cpp:112
void SetEndPoint(const VECTOR2I &aPosition)
Definition: sch_line.h:146
double Similarity(const SCH_ITEM &aOther) const override
Return a measure of how likely the other object is to represent the same object.
Definition: sch_line.cpp:1014
bool IsJunction(const VECTOR2I &aPosition) const
Test if a junction is required for the items at aPosition on the screen.
Definition: sch_screen.cpp:475
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
int GetWidth() const
Definition: stroke_params.h:91
static void Stroke(const SHAPE *aShape, LINE_STYLE aLineStyle, int aWidth, const KIGFX::RENDER_SETTINGS *aRenderSettings, std::function< void(const VECTOR2I &a, const VECTOR2I &b)> aStroker)
void SetLineStyle(LINE_STYLE aLineStyle)
Definition: stroke_params.h:95
void SetWidth(int aWidth)
Definition: stroke_params.h:92
void SetColor(const KIGFX::COLOR4D &aColor)
Definition: stroke_params.h:98
void GetMsgPanelInfo(UNITS_PROVIDER *aUnitsProvider, std::vector< MSG_PANEL_ITEM > &aList, bool aIncludeStyle=true, bool aIncludeWidth=true)
LINE_STYLE GetLineStyle() const
Definition: stroke_params.h:94
KIGFX::COLOR4D GetColor() const
Definition: stroke_params.h:97
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
A lower-precision version of StringFromValue().
#define DEFAULT_BUS_WIDTH_MILS
The default noconnect size in mils.
#define DEFAULT_WIRE_WIDTH_MILS
The default bus width in mils. (can be changed in preference menu)
#define DEFAULT_LINE_WIDTH_MILS
The default wire width in mils. (can be changed in preference menu)
#define _HKI(x)
#define _(s)
static constexpr EDA_ANGLE & ANGLE_90
Definition: eda_angle.h:439
#define STRUCT_DELETED
flag indication structures to be erased
#define ENDPOINT
ends. (Used to support dragging.)
#define SKIP_STRUCT
flag indicating that the structure should be ignored
#define STARTPOINT
When a line is selected, these flags indicate which.
void GRLine(wxDC *DC, int x1, int y1, int x2, int y2, int width, const COLOR4D &Color, wxPenStyle aStyle)
Definition: gr_basic.cpp:171
@ LAYER_DANGLING
Definition: layer_ids.h:373
@ LAYER_WIRE
Definition: layer_ids.h:349
@ LAYER_NOTES
Definition: layer_ids.h:363
@ LAYER_BUS
Definition: layer_ids.h:350
@ LAYER_SELECTION_SHADOWS
Definition: layer_ids.h:387
@ LAYER_OP_VOLTAGES
Definition: layer_ids.h:393
void MIRROR(T &aPoint, const T &aMirrorRef)
Updates aPoint with the mirror of aPoint relative to the aMirrorRef.
Definition: mirror.h:40
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:426
#define TYPE_HASH(x)
Definition: property.h:64
#define REGISTER_TYPE(x)
Definition: property_mgr.h:331
@ BUS_END
Definition: sch_item.h:70
@ PIN_END
Definition: sch_item.h:72
@ BUS_ENTRY_END
Definition: sch_item.h:74
@ WIRE_END
Definition: sch_item.h:69
static struct SCH_LINE_DESC _SCH_LINE_DESC
wxString UnescapeString(const wxString &aSource)
LINE_STYLE
Dashed line types.
Definition: stroke_params.h:48
constexpr int MilsToIU(int mils) const
Definition: base_units.h:94
constexpr int mmToIU(double mm) const
Definition: base_units.h:89
bool m_PDFPropertyPopups
Definition: sch_plotter.h:90
bool TestSegmentHit(const VECTOR2I &aRefPoint, const VECTOR2I &aStart, const VECTOR2I &aEnd, int aDist)
Test if aRefPoint is with aDistance on the line defined by aStart and aEnd.
Definition: trigo.cpp:174
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
Definition: trigo.cpp:228
double GetLineLength(const VECTOR2I &aPointA, const VECTOR2I &aPointB)
Return the length of a line segment defined by aPointA and aPointB.
Definition: trigo.h:194
double EuclideanNorm(const VECTOR2I &vector)
Definition: trigo.h:128
@ SCH_LINE_T
Definition: typeinfo.h:146
@ SCH_NO_CONNECT_T
Definition: typeinfo.h:143
@ SCH_SYMBOL_T
Definition: typeinfo.h:156
@ SCH_DIRECTIVE_LABEL_T
Definition: typeinfo.h:154
@ SCH_LABEL_T
Definition: typeinfo.h:151
@ SCH_SHEET_T
Definition: typeinfo.h:158
@ SCH_HIER_LABEL_T
Definition: typeinfo.h:153
@ SCH_SHEET_PIN_T
Definition: typeinfo.h:157
@ SCH_BUS_WIRE_ENTRY_T
Definition: typeinfo.h:144
@ SCH_GLOBAL_LABEL_T
Definition: typeinfo.h:152
@ SCH_JUNCTION_T
Definition: typeinfo.h:142
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:85
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588