KiCad PCB EDA Suite
Loading...
Searching...
No Matches
point_editor_behavior.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 The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
25
26#include <advanced_config.h>
27#include <commit.h>
29
30
32 const SHAPE_POLY_SET& aOutline )
33{
34 const int cornersCount = aOutline.TotalVertices();
35
36 if( cornersCount == 0 )
37 return;
38
39 for( auto iterator = aOutline.CIterateWithHoles(); iterator; iterator++ )
40 {
41 aPoints.AddPoint( *iterator );
42
43 if( iterator.IsEndContour() )
44 aPoints.AddBreak();
45 }
46
47 // Lines have to be added after creating edit points, as they use EDIT_POINT references
48 for( int i = 0; i < cornersCount - 1; ++i )
49 {
50 if( aPoints.IsContourEnd( i ) )
51 aPoints.AddLine( aPoints.Point( i ), aPoints.Point( aPoints.GetContourStartIdx( i ) ) );
52 else
53 aPoints.AddLine( aPoints.Point( i ), aPoints.Point( i + 1 ) );
54
55 aPoints.Line( i ).SetConstraint( new EC_CONVERGING( aPoints.Line( i ), aPoints ) );
56 }
57
58 // The last missing line, connecting the last and the first polygon point
59 aPoints.AddLine( aPoints.Point( cornersCount - 1 ),
60 aPoints.Point( aPoints.GetContourStartIdx( cornersCount - 1 ) ) );
61
62 aPoints.Line( aPoints.LinesSize() - 1 )
63 .SetConstraint( new EC_CONVERGING( aPoints.Line( aPoints.LinesSize() - 1 ), aPoints ) );
64}
65
66
68 EDIT_POINTS& aPoints )
69{
70 // No size check here, as we can and will rebuild if that fails
71 if( aPoints.PointsSize() != (unsigned) aOutline.TotalVertices() )
72 {
73 // Rebuild the points list
74 aPoints.Clear();
75 BuildForPolyOutline( aPoints, aOutline );
76 }
77 else
78 {
79 for( int i = 0; i < aOutline.TotalVertices(); ++i )
80 aPoints.Point( i ).SetPosition( aOutline.CVertex( i ) );
81 }
82}
83
84
86 const EDIT_POINT& aEditedPoint,
87 EDIT_POINTS& aPoints )
88{
89 CHECK_POINT_COUNT_GE( aPoints, (unsigned) aOutline.TotalVertices() );
90
91 for( int i = 0; i < aOutline.TotalVertices(); ++i )
92 aOutline.SetVertex( i, aPoints.Point( i ).GetPosition() );
93
94 for( unsigned i = 0; i < aPoints.LinesSize(); ++i )
95 {
96 if( !isModified( aEditedPoint, aPoints.Line( i ) ) )
97 aPoints.Line( i ).SetConstraint( new EC_CONVERGING( aPoints.Line( i ), aPoints ) );
98 }
99}
100
101
103{
104 m_polygon.RemoveNullSegments();
105}
106
107
109{
110 aPoints.AddPoint( m_segment.GetStart() );
111 aPoints.AddPoint( m_segment.GetEnd() );
112}
113
114
116{
117 wxCHECK( aPoints.PointsSize() == SEGMENT_MAX_POINTS, false );
118
119 aPoints.Point( SEGMENT_START ) = m_segment.GetStart();
120 aPoints.Point( SEGMENT_END ) = m_segment.GetEnd();
121 return true;
122}
123
124
126 EDIT_POINTS& aPoints, COMMIT& aCommit,
127 std::vector<EDA_ITEM*>& aUpdatedItems )
128{
130
131 if( isModified( aEditedPoint, aPoints.Point( SEGMENT_START ) ) )
132 m_segment.SetStart( aPoints.Point( SEGMENT_START ).GetPosition() );
133
134 else if( isModified( aEditedPoint, aPoints.Point( SEGMENT_END ) ) )
135 m_segment.SetEnd( aPoints.Point( SEGMENT_END ).GetPosition() );
136}
137
138
140 EDIT_POINTS& aPoints ) const
141{
142 // Select the other end of line
143 return aPoints.Next( aEditedPoint )->GetPosition();
144}
145
146
148{
149 aPoints.AddPoint( m_circle.getCenter() );
150 aPoints.AddPoint( m_circle.GetEnd() );
151}
152
153
155{
156 wxCHECK( aPoints.PointsSize() == CIRC_MAX_POINTS, false );
157
158 aPoints.Point( CIRC_CENTER ).SetPosition( m_circle.getCenter() );
159 aPoints.Point( CIRC_END ).SetPosition( m_circle.GetEnd() );
160 return true;
161}
162
163
165 EDIT_POINTS& aPoints, COMMIT& aCommit,
166 std::vector<EDA_ITEM*>& aUpdatedItems )
167{
169
170 const VECTOR2I& center = aPoints.Point( CIRC_CENTER ).GetPosition();
171 const VECTOR2I& end = aPoints.Point( CIRC_END ).GetPosition();
172
173 if( isModified( aEditedPoint, aPoints.Point( CIRC_CENTER ) ) )
174 m_circle.SetCenter( center );
175 else
176 m_circle.SetEnd( VECTOR2I( end.x, end.y ) );
177}
178
179
181 EDIT_POINTS& aPoints ) const
182{
183 return aPoints.Point( CIRC_CENTER ).GetPosition();
184}
185
186
188{
189 aPoints.AddPoint( m_bezier.GetStart() );
190 aPoints.AddPoint( m_bezier.GetBezierC1() );
191 aPoints.AddPoint( m_bezier.GetBezierC2() );
192 aPoints.AddPoint( m_bezier.GetEnd() );
193
194 aPoints.AddIndicatorLine( aPoints.Point( BEZIER_START ), aPoints.Point( BEZIER_CTRL_PT1 ) );
195 aPoints.AddIndicatorLine( aPoints.Point( BEZIER_CTRL_PT2 ), aPoints.Point( BEZIER_END ) );
196}
197
198
200{
201 wxCHECK( aPoints.PointsSize() == BEZIER_MAX_POINTS, false );
202
203 aPoints.Point( BEZIER_START ).SetPosition( m_bezier.GetStart() );
204 aPoints.Point( BEZIER_CTRL_PT1 ).SetPosition( m_bezier.GetBezierC1() );
205 aPoints.Point( BEZIER_CTRL_PT2 ).SetPosition( m_bezier.GetBezierC2() );
206 aPoints.Point( BEZIER_END ).SetPosition( m_bezier.GetEnd() );
207 return true;
208}
209
210
212 COMMIT& aCommit, std::vector<EDA_ITEM*>& aUpdatedItems )
213{
215
216 if( isModified( aEditedPoint, aPoints.Point( BEZIER_START ) ) )
217 {
218 m_bezier.SetStart( aPoints.Point( BEZIER_START ).GetPosition() );
219 }
220 else if( isModified( aEditedPoint, aPoints.Point( BEZIER_CTRL_PT1 ) ) )
221 {
222 m_bezier.SetBezierC1( aPoints.Point( BEZIER_CTRL_PT1 ).GetPosition() );
223 }
224 else if( isModified( aEditedPoint, aPoints.Point( BEZIER_CTRL_PT2 ) ) )
225 {
226 m_bezier.SetBezierC2( aPoints.Point( BEZIER_CTRL_PT2 ).GetPosition() );
227 }
228 else if( isModified( aEditedPoint, aPoints.Point( BEZIER_END ) ) )
229 {
230 m_bezier.SetEnd( aPoints.Point( BEZIER_END ).GetPosition() );
231 }
232
233 m_bezier.RebuildBezierToSegmentsPointsList( m_maxError );
234}
235
236
237// Note: these static arc functions don't have to be in here - we could ship them out
238// to a utils area for use by other code (e.g. polygon fillet editing).
239
243static void editArcEndpointKeepTangent( EDA_SHAPE& aArc, const VECTOR2I& aCenter, const VECTOR2I& aStart,
244 const VECTOR2I& aMid, const VECTOR2I& aEnd, const VECTOR2I& aCursor )
245{
246 VECTOR2I center = aCenter;
247 bool movingStart;
248 bool arcValid = true;
249
250 VECTOR2I p1, p2, p3;
251 // p1 does not move, p2 does.
252
253 if( aStart != aArc.GetStart() )
254 {
255 p1 = aEnd;
256 p2 = aStart;
257 p3 = aMid;
258 movingStart = true;
259 }
260 else if( aEnd != aArc.GetEnd() )
261 {
262 p1 = aStart;
263 p2 = aEnd;
264 p3 = aMid;
265 movingStart = false;
266 }
267 else
268 {
269 return;
270 }
271
272 VECTOR2D v1, v2, v3, v4;
273
274 // Move the coordinate system
275 v1 = p1 - aCenter;
276 v2 = p2 - aCenter;
277 v3 = p3 - aCenter;
278
279 VECTOR2D u1, u2;
280
281 // A point cannot be both the center and on the arc.
282 if( ( v1.EuclideanNorm() == 0 ) || ( v2.EuclideanNorm() == 0 ) )
283 return;
284
285 u1 = v1 / v1.EuclideanNorm();
286 u2 = v3 - ( u1.x * v3.x + u1.y * v3.y ) * u1;
287 u2 = u2 / u2.EuclideanNorm();
288
289 // [ u1, u3 ] is a base centered on the circle with:
290 // u1 : unit vector toward the point that does not move
291 // u2 : unit vector toward the mid point.
292
293 // Get vectors v1, and v2 in that coordinate system.
294
295 double det = u1.x * u2.y - u2.x * u1.y;
296
297 // u1 and u2 are unit vectors, and perpendicular.
298 // det should not be 0. In case it is, do not change the arc.
299 if( det == 0 )
300 return;
301
302 double tmpx = v1.x * u2.y - v1.y * u2.x;
303 double tmpy = -v1.x * u1.y + v1.y * u1.x;
304 v1.x = tmpx;
305 v1.y = tmpy;
306 v1 = v1 / det;
307
308 tmpx = v2.x * u2.y - v2.y * u2.x;
309 tmpy = -v2.x * u1.y + v2.y * u1.x;
310 v2.x = tmpx;
311 v2.y = tmpy;
312 v2 = v2 / det;
313
314 double R = v1.EuclideanNorm();
315 bool transformCircle = false;
316
317 /* p2
318 * X***
319 * ** <---- This is the arc
320 * y ^ **
321 * | R *
322 * | <-----------> *
323 * x------x------>--------x p1
324 * C' <----> C x
325 * delta
326 *
327 * p1 does not move, and the tangent at p1 remains the same.
328 * => The new center, C', will be on the C-p1 axis.
329 * p2 moves
330 *
331 * The radius of the new circle is delta + R
332 *
333 * || C' p2 || = || C' P1 ||
334 * is the same as :
335 * ( delta + p2.x ) ^ 2 + p2.y ^ 2 = ( R + delta ) ^ 2
336 *
337 * delta = ( R^2 - p2.x ^ 2 - p2.y ^2 ) / ( 2 * p2.x - 2 * R )
338 *
339 * We can use this equation for any point p2 with p2.x < R
340 */
341
342 if( v2.x == R )
343 {
344 // Straight line, do nothing
345 }
346 else
347 {
348 if( v2.x > R )
349 {
350 // If we need to invert the curvature.
351 // We modify the input so we can use the same equation
352 transformCircle = true;
353 v2.x = 2 * R - v2.x;
354 }
355
356 // We can keep the tangent constraint.
357 double delta = ( R * R - v2.x * v2.x - v2.y * v2.y ) / ( 2 * v2.x - 2 * R );
358
359 // This is just to limit the radius, so nothing overflows later when drawing.
360 if( abs( v2.y / ( R - v2.x ) ) > ADVANCED_CFG::GetCfg().m_DrawArcCenterMaxAngle )
361 arcValid = false;
362
363 // Never recorded a problem, but still checking.
364 if( !std::isfinite( delta ) )
365 arcValid = false;
366
367 // v4 is the new center
368 v4 = ( !transformCircle ) ? VECTOR2D( -delta, 0 ) : VECTOR2D( 2 * R + delta, 0 );
369
370 tmpx = v4.x * u1.x + v4.y * u2.x;
371 tmpy = v4.x * u1.y + v4.y * u2.y;
372 v4.x = tmpx;
373 v4.y = tmpy;
374
375 center = v4 + aCenter;
376
377 if( arcValid )
378 {
379 aArc.SetCenter( center );
380
381 if( movingStart )
382 aArc.SetStart( aStart );
383 else
384 aArc.SetEnd( aEnd );
385 }
386 }
387}
388
389
393static void editArcCenterKeepEndpoints( EDA_SHAPE& aArc, const VECTOR2I& aCenter, const VECTOR2I& aStart,
394 const VECTOR2I& aMid, const VECTOR2I& aEnd )
395{
396 const int c_snapEpsilon_sq = 4;
397
398 VECTOR2I m = ( aStart / 2 + aEnd / 2 );
399 VECTOR2I perp = ( aEnd - aStart ).Perpendicular().Resize( INT_MAX / 2 );
400
401 SEG legal( m - perp, m + perp );
402
403 const SEG testSegments[] = {
404 SEG( aCenter, aCenter + VECTOR2( 1, 0 ) ),
405 SEG( aCenter, aCenter + VECTOR2( 0, 1 ) ),
406 };
407
408 std::vector<VECTOR2I> points = { legal.A, legal.B };
409
410 for( const SEG& seg : testSegments )
411 {
412 OPT_VECTOR2I vec = legal.IntersectLines( seg );
413
414 if( vec && legal.SquaredDistance( *vec ) <= c_snapEpsilon_sq )
415 points.push_back( *vec );
416 }
417
418 OPT_VECTOR2I nearest;
420
421 // Snap by distance between cursor and intersections
422 for( const VECTOR2I& pt : points )
423 {
424 SEG::ecoord d_sq = ( pt - aCenter ).SquaredEuclideanNorm();
425
426 if( d_sq < min_d_sq - c_snapEpsilon_sq )
427 {
428 min_d_sq = d_sq;
429 nearest = pt;
430 }
431 }
432
433 if( nearest )
434 aArc.SetCenter( *nearest );
435}
436
437
441static void editArcEndpointKeepCenter( EDA_SHAPE& aArc, const VECTOR2I& aCenter, const VECTOR2I& aStart,
442 const VECTOR2I& aMid, const VECTOR2I& aEnd, const VECTOR2I& aCursor )
443{
444 int minRadius = EDA_UNIT_UTILS::Mils2IU( pcbIUScale, 1 );
445 bool movingStart;
446
447 VECTOR2I p1, p2, prev_p1;
448
449 // user is moving p1, we want to move p2 to the new radius.
450
451 if( aStart != aArc.GetStart() )
452 {
453 prev_p1 = aArc.GetStart();
454 p1 = aStart;
455 p2 = aEnd;
456 movingStart = true;
457 }
458 else
459 {
460 prev_p1 = aArc.GetEnd();
461 p1 = aEnd;
462 p2 = aStart;
463 movingStart = false;
464 }
465
466 p1 = p1 - aCenter;
467 p2 = p2 - aCenter;
468
469 if( p1.x == 0 && p1.y == 0 )
470 p1 = prev_p1 - aCenter;
471
472 if( p2.x == 0 && p2.y == 0 )
473 p2 = { 1, 0 };
474
475 double radius = p1.EuclideanNorm();
476
477 if( radius < minRadius )
478 radius = minRadius;
479
480 p1 = aCenter + p1.Resize( radius );
481 p2 = aCenter + p2.Resize( radius );
482
483 aArc.SetCenter( aCenter );
484
485 if( movingStart )
486 {
487 aArc.SetStart( p1 );
488 aArc.SetEnd( p2 );
489 }
490 else
491 {
492 aArc.SetStart( p2 );
493 aArc.SetEnd( p1 );
494 }
495}
496
497
498static void editArcEndpointKeepCenterAndRadius( EDA_SHAPE& aArc, const VECTOR2I& aCenter, const VECTOR2I& aStart,
499 const VECTOR2I& aMid, const VECTOR2I& aEnd )
500{
501 VECTOR2I p1;
502 bool movingStart = false;
503
504 // User is moving p1, we need to update whichever end that is
505 // The other end won't move.
506
507 if( aStart != aArc.GetStart() )
508 {
509 p1 = aStart;
510 movingStart = true;
511 }
512 else
513 {
514 p1 = aEnd;
515 movingStart = false;
516 }
517
518 // Do not change the radius
519 p1 = p1 - aCenter;
520 p1 = aCenter + p1.Resize( aArc.GetRadius() );
521
522 if( movingStart )
523 {
524 aArc.SetStart( p1 );
525 }
526 else
527 {
528 aArc.SetEnd( p1 );
529 }
530}
531
532
536static void editArcMidKeepCenter( EDA_SHAPE& aArc, const VECTOR2I& aCenter, const VECTOR2I& aStart,
537 const VECTOR2I& aMid, const VECTOR2I& aEnd, const VECTOR2I& aCursor )
538{
539 int minRadius = EDA_UNIT_UTILS::Mils2IU( pcbIUScale, 1 );
540
541 SEG chord( aStart, aEnd );
542
543 // Now, update the edit point position
544 // Express the point in a circle-centered coordinate system.
545 VECTOR2I start = aStart - aCenter;
546 VECTOR2I end = aEnd - aCenter;
547
548 double radius = ( aCursor - aCenter ).EuclideanNorm();
549
550 if( radius < minRadius )
551 radius = minRadius;
552
553 start = start.Resize( radius );
554 end = end.Resize( radius );
555
556 start = start + aCenter;
557 end = end + aCenter;
558
559 aArc.SetStart( start );
560 aArc.SetEnd( end );
561}
562
563
567static void editArcMidKeepEndpoints( EDA_SHAPE& aArc, const VECTOR2I& aStart, const VECTOR2I& aEnd,
568 const VECTOR2I& aCursor )
569{
570 // Let 'm' be the middle point of the chord between the start and end points
571 VECTOR2I m = ( aStart + aEnd ) / 2;
572
573 // Legal midpoints lie on a vector starting just off the chord midpoint and extending out
574 // past the existing midpoint. We do not allow arc inflection while point editing.
575 const int JUST_OFF = ( aStart - aEnd ).EuclideanNorm() / 100;
576 VECTOR2I v = (VECTOR2I) aArc.GetArcMid() - m;
577 SEG legal( m + v.Resize( JUST_OFF ), m + v.Resize( INT_MAX / 2 ) );
578 VECTOR2I mid = legal.NearestPoint( aCursor );
579
580 aArc.SetArcGeometry( aStart, mid, aEnd );
581}
582
583
585 KIGFX::VIEW_CONTROLS& aViewContols ) :
586 m_arc( aArc ),
587 m_arcEditMode( aArcEditMode ),
588 m_viewControls( aViewContols )
589{
590 wxASSERT( m_arc.GetShape() == SHAPE_T::ARC );
591}
592
593
595{
596 aPoints.AddPoint( m_arc.GetStart() );
597 aPoints.AddPoint( m_arc.GetArcMid() );
598 aPoints.AddPoint( m_arc.GetEnd() );
599 aPoints.AddPoint( m_arc.getCenter() );
600
601 aPoints.AddIndicatorLine( aPoints.Point( ARC_CENTER ), aPoints.Point( ARC_START ) );
602 aPoints.AddIndicatorLine( aPoints.Point( ARC_CENTER ), aPoints.Point( ARC_END ) );
603}
604
605
607{
608 wxCHECK( aPoints.PointsSize() == 4, false );
609
610 aPoints.Point( ARC_START ).SetPosition( m_arc.GetStart() );
611 aPoints.Point( ARC_MID ).SetPosition( m_arc.GetArcMid() );
612 aPoints.Point( ARC_END ).SetPosition( m_arc.GetEnd() );
613 aPoints.Point( ARC_CENTER ).SetPosition( m_arc.getCenter() );
614 return true;
615}
616
617
618void EDA_ARC_POINT_EDIT_BEHAVIOR::UpdateItem( const EDIT_POINT& aEditedPoint, EDIT_POINTS& aPoints, COMMIT& aCommit,
619 std::vector<EDA_ITEM*>& aUpdatedItems )
620{
621 CHECK_POINT_COUNT( aPoints, 4 );
622
624 VECTOR2I mid = aPoints.Point( ARC_MID ).GetPosition();
625 VECTOR2I start = aPoints.Point( ARC_START ).GetPosition();
626 VECTOR2I end = aPoints.Point( ARC_END ).GetPosition();
627
628 if( isModified( aEditedPoint, aPoints.Point( ARC_CENTER ) ) )
629 {
630 switch( m_arcEditMode )
631 {
634 break;
637 {
638 // Both these modes just move the arc
639 VECTOR2I moveVector = VECTOR2I( center.x, center.y ) - m_arc.getCenter();
640
641 m_arc.SetArcGeometry( m_arc.GetStart() + moveVector, m_arc.GetArcMid() + moveVector,
642 m_arc.GetEnd() + moveVector );
643 break;
644 }
645 }
646 }
647 else if( isModified( aEditedPoint, aPoints.Point( ARC_MID ) ) )
648 {
649 const VECTOR2I& cursorPos = m_viewControls.GetCursorPosition( false );
650
651 switch( m_arcEditMode )
652 {
654 editArcMidKeepEndpoints( m_arc, start, end, cursorPos );
655 break;
658 editArcMidKeepCenter( m_arc, center, start, mid, end, cursorPos );
659 break;
660 }
661 }
662 else if( isModified( aEditedPoint, aPoints.Point( ARC_START ) )
663 || isModified( aEditedPoint, aPoints.Point( ARC_END ) ) )
664 {
665 const VECTOR2I& cursorPos = m_viewControls.GetCursorPosition();
666
667 switch( m_arcEditMode )
668 {
670 editArcEndpointKeepCenter( m_arc, center, start, mid, end, cursorPos );
671 break;
674 break;
676 editArcEndpointKeepTangent( m_arc, center, start, mid, end, cursorPos );
677 break;
678 }
679 }
680}
681
682
684 EDIT_POINTS& aPoints ) const
685{
686 return aPoints.Point( ARC_CENTER ).GetPosition();
687}
688
689
691{
692 aPoints.AddPoint( m_cell.GetEnd() - VECTOR2I( 0, m_cell.GetRectangleHeight() / 2 ) );
693 aPoints.AddPoint( m_cell.GetEnd() - VECTOR2I( m_cell.GetRectangleWidth() / 2, 0 ) );
694}
695
696
698{
699 aPoints.Point( COL_WIDTH ).SetPosition( m_cell.GetEnd() - VECTOR2I( 0, m_cell.GetRectangleHeight() / 2 ) );
700 aPoints.Point( ROW_HEIGHT ).SetPosition( m_cell.GetEnd() - VECTOR2I( m_cell.GetRectangleWidth() / 2, 0 ) );
701 return true;
702}
703
704
ARC_EDIT_MODE
Settings for arc editing.
@ KEEP_ENDPOINTS_OR_START_DIRECTION
Whe editing endpoints, the other end remains in place.
@ KEEP_CENTER_ENDS_ADJUST_ANGLE
When editing endpoints, only the angle is adjusted.
@ KEEP_CENTER_ADJUST_ANGLE_RADIUS
When editing endpoints, the angle and radius are adjusted.
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:112
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
Represent a set of changes (additions, deletions or modifications) of a data model (e....
Definition commit.h:72
EDIT_CONSTRAINT for 3 segments: dragged and two adjacent ones, enforcing to keep their slopes and all...
const ARC_EDIT_MODE & m_arcEditMode
void UpdateItem(const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints, COMMIT &aCommit, std::vector< EDA_ITEM * > &aUpdatedItems) override
Update the item with the new positions of the edit points.
void MakePoints(EDIT_POINTS &aPoints) override
Construct the initial set of edit points for the item and append to the given list.
OPT_VECTOR2I Get45DegreeConstrainer(const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints) const override
Get the 45-degree constrainer for the item, when the given point is moved.
KIGFX::VIEW_CONTROLS & m_viewControls
EDA_ARC_POINT_EDIT_BEHAVIOR(EDA_SHAPE &aArc, const ARC_EDIT_MODE &aArcEditMode, KIGFX::VIEW_CONTROLS &aViewContols)
bool UpdatePoints(EDIT_POINTS &aPoints) override
Update the list of the edit points for the item.
void UpdateItem(const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints, COMMIT &aCommit, std::vector< EDA_ITEM * > &aUpdatedItems) override
Update the item with the new positions of the edit points.
bool UpdatePoints(EDIT_POINTS &aPoints) override
Update the list of the edit points for the item.
void MakePoints(EDIT_POINTS &aPoints) override
Construct the initial set of edit points for the item and append to the given list.
OPT_VECTOR2I Get45DegreeConstrainer(const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints) const override
Get the 45-degree constrainer for the item, when the given point is moved.
void UpdateItem(const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints, COMMIT &aCommit, std::vector< EDA_ITEM * > &aUpdatedItems) override
Update the item with the new positions of the edit points.
bool UpdatePoints(EDIT_POINTS &aPoints) override
Update the list of the edit points for the item.
void MakePoints(EDIT_POINTS &aPoints) override
Construct the initial set of edit points for the item and append to the given list.
OPT_VECTOR2I Get45DegreeConstrainer(const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints) const override
Get the 45-degree constrainer for the item, when the given point is moved.
void MakePoints(EDIT_POINTS &aPoints) override
Construct the initial set of edit points for the item and append to the given list.
bool UpdatePoints(EDIT_POINTS &aPoints) override
Update the list of the edit points for the item.
void UpdateItem(const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints, COMMIT &aCommit, std::vector< EDA_ITEM * > &aUpdatedItems) override
Update the item with the new positions of the edit points.
void SetCenter(const VECTOR2I &aCenter)
int GetRadius() const
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition eda_shape.h:215
void SetStart(const VECTOR2I &aStart)
Definition eda_shape.h:177
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition eda_shape.h:173
void SetEnd(const VECTOR2I &aEnd)
Definition eda_shape.h:219
void SetArcGeometry(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Set the three controlling points for an arc.
VECTOR2I GetArcMid() const
void MakePoints(EDIT_POINTS &aPoints) override
Construct the initial set of edit points for the item and append to the given list.
bool UpdatePoints(EDIT_POINTS &aPoints) override
Update the list of the edit points for the item.
void SetConstraint(EDIT_CONSTRAINT< EDIT_LINE > *aConstraint)
Set a constraint for and EDIT_POINT.
EDIT_POINTS is a VIEW_ITEM that manages EDIT_POINTs and EDIT_LINEs and draws them.
unsigned int PointsSize() const
Return number of stored EDIT_POINTs.
void AddPoint(const EDIT_POINT &aPoint)
Add an EDIT_POINT.
void Clear()
Clear all stored EDIT_POINTs and EDIT_LINEs.
EDIT_POINT * Next(const EDIT_POINT &aPoint, bool aTraverseContours=true)
Return the point that is before the given point in the list.
EDIT_LINE & Line(unsigned int aIndex)
bool IsContourEnd(int aPointIdx) const
Check is a point with given index is a contour finish.
void AddIndicatorLine(EDIT_POINT &aOrigin, EDIT_POINT &aEnd)
Adds an EDIT_LINE that is shown as an indicator, rather than an editable line (no center point drag,...
void AddBreak()
Adds a break, indicating the end of a contour.
int GetContourStartIdx(int aPointIdx) const
Return index of the contour origin for a point with given index.
unsigned int LinesSize() const
Return number of stored EDIT_LINEs.
EDIT_POINT & Point(unsigned int aIndex)
void AddLine(const EDIT_LINE &aLine)
Adds an EDIT_LINE.
Represent a single point that can be used for modifying items.
Definition edit_points.h:48
virtual void SetPosition(const VECTOR2I &aPosition)
Set new coordinates for an EDIT_POINT.
virtual VECTOR2I GetPosition() const
Return coordinates of an EDIT_POINT.
Definition edit_points.h:72
An interface for classes handling user events controlling the view behavior such as zooming,...
static bool isModified(const EDIT_POINT &aEditedPoint, const EDIT_POINT &aPoint)
Checks if two points are the same instance - which means the point is being edited.
static void UpdateOutlineFromPoints(SHAPE_POLY_SET &aOutline, const EDIT_POINT &aEditedPoint, EDIT_POINTS &aPoints)
Update the polygon outline with the new positions of the edit points.
static void UpdatePointsFromOutline(const SHAPE_POLY_SET &aOutline, EDIT_POINTS &aPoints)
Update the edit points with the current polygon outline.
void FinalizeItem(EDIT_POINTS &aPoints, COMMIT &aCommit) override
Finalize the edit operation.
static void BuildForPolyOutline(EDIT_POINTS &aPoints, const SHAPE_POLY_SET &aOutline)
Build the edit points for the given polygon outline.
Definition seg.h:42
VECTOR2I A
Definition seg.h:49
ecoord SquaredDistance(const SEG &aSeg) const
Definition seg.cpp:80
VECTOR2I::extended_type ecoord
Definition seg.h:44
VECTOR2I B
Definition seg.h:50
const VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute a point on the segment (this) that is closest to point aP.
Definition seg.cpp:604
OPT_VECTOR2I IntersectLines(const SEG &aSeg) const
Compute the intersection point of lines passing through ends of (this) and aSeg.
Definition seg.h:220
Represent a set of closed polygons.
void SetVertex(const VERTEX_INDEX &aIndex, const VECTOR2I &aPos)
Accessor function to set the position of a specific point.
int TotalVertices() const
Return total number of vertices stored in the set.
const VECTOR2I & CVertex(int aIndex, int aOutline, int aHole) const
Return the index-th vertex in a given hole outline within a given outline.
CONST_ITERATOR CIterateWithHoles(int aOutline) const
Define a general 2D-vector/point.
Definition vector2d.h:71
static constexpr extended_type ECOORD_MAX
Definition vector2d.h:76
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition vector2d.h:283
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
Definition vector2d.h:385
constexpr int Mils2IU(const EDA_IU_SCALE &aIuScale, int mils)
Definition eda_units.h:166
static void editArcEndpointKeepCenterAndRadius(EDA_SHAPE &aArc, const VECTOR2I &aCenter, const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
static void editArcEndpointKeepCenter(EDA_SHAPE &aArc, const VECTOR2I &aCenter, const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd, const VECTOR2I &aCursor)
Move an end point of the arc around the circumference.
ARC_EDIT_MODE IncrementArcEditMode(ARC_EDIT_MODE aMode)
static void editArcCenterKeepEndpoints(EDA_SHAPE &aArc, const VECTOR2I &aCenter, const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Move the arc center but keep endpoint locations.
static void editArcMidKeepEndpoints(EDA_SHAPE &aArc, const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aCursor)
Move the mid point of the arc, while keeping the angle.
static void editArcMidKeepCenter(EDA_SHAPE &aArc, const VECTOR2I &aCenter, const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd, const VECTOR2I &aCursor)
Move the mid point of the arc, while keeping the two endpoints.
static void editArcEndpointKeepTangent(EDA_SHAPE &aArc, const VECTOR2I &aCenter, const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd, const VECTOR2I &aCursor)
Move an end point of the arc, while keeping the tangent at the other endpoint.
#define CHECK_POINT_COUNT(aPoints, aExpected)
#define CHECK_POINT_COUNT_GE(aPoints, aExpected)
std::optional< VECTOR2I > OPT_VECTOR2I
Definition seg.h:39
VECTOR3I v1(5, 5, 5)
VECTOR2I center
int radius
VECTOR2I end
VECTOR2I v2(1, 0)
VECTOR2I v4(1, 1)
VECTOR2I v3(-2, 1)
int delta
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:695
VECTOR2< double > VECTOR2D
Definition vector2d.h:694