4 * \brief Functions used to insert points into objects.
8 * <h1><b>Copyright.</b></h1>\n
10 * PCB, interactive printed circuit board design
11 * Copyright (C) 1994,1995,1996 Thomas Nau
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 * Contact addresses for paper mail and Email:
28 * Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
29 * Thomas.Nau@rz.uni-ulm.de
41 #include "crosshair.h"
55 #ifdef HAVE_LIBDMALLOC
59 /* ---------------------------------------------------------------------------
60 * some local prototypes
62 static void *InsertPointIntoLine (LayerType
*, LineType
*);
63 static void *InsertPointIntoPolygon (LayerType
*, PolygonType
*);
64 static void *InsertPointIntoRat (RatType
*);
66 /* ---------------------------------------------------------------------------
67 * some local identifiers
69 static Coord InsertX
, InsertY
; /* used by local routines as offset */
70 static Angle InsertIncludedAngle
; /* Only used by polygon point insert */
71 static Cardinal InsertAt
;
72 static bool InsertLast
;
74 static ObjectFunctionType InsertFunctions
= {
77 InsertPointIntoPolygon
,
90 * \brief Inserts a point into a rat-line.
93 InsertPointIntoRat (RatType
*Rat
)
97 newone
= CreateDrawnLineOnLayer (CURRENT
, Rat
->Point1
.X
, Rat
->Point1
.Y
,
98 InsertX
, InsertY
, Settings
.LineThickness
,
99 2 * Settings
.Keepaway
, Rat
->Flags
);
102 AddObjectToCreateUndoList (LINE_TYPE
, CURRENT
, newone
, newone
);
104 DrawLine (CURRENT
, newone
);
105 newone
= CreateDrawnLineOnLayer (CURRENT
, Rat
->Point2
.X
, Rat
->Point2
.Y
,
106 InsertX
, InsertY
, Settings
.LineThickness
,
107 2 * Settings
.Keepaway
, Rat
->Flags
);
110 AddObjectToCreateUndoList (LINE_TYPE
, CURRENT
, newone
, newone
);
111 DrawLine (CURRENT
, newone
);
113 MoveObjectToRemoveUndoList (RATLINE_TYPE
, Rat
, Rat
, Rat
);
119 * \brief Inserts a point into a line.
122 InsertPointIntoLine (LayerType
*Layer
, LineType
*Line
)
127 if (((Line
->Point1
.X
== InsertX
) && (Line
->Point1
.Y
== InsertY
)) ||
128 ((Line
->Point2
.X
== InsertX
) && (Line
->Point2
.Y
== InsertY
)))
132 AddObjectToMoveUndoList (LINEPOINT_TYPE
, Layer
, Line
, &Line
->Point2
,
133 InsertX
- X
, InsertY
- Y
);
135 r_delete_entry (Layer
->line_tree
, (BoxType
*) Line
);
136 RestoreToPolygon (PCB
->Data
, LINE_TYPE
, Layer
, Line
);
137 Line
->Point2
.X
= InsertX
;
138 Line
->Point2
.Y
= InsertY
;
139 SetLineBoundingBox (Line
);
140 r_insert_entry (Layer
->line_tree
, (BoxType
*) Line
, 0);
141 ClearFromPolygon (PCB
->Data
, LINE_TYPE
, Layer
, Line
);
142 DrawLine (Layer
, Line
);
143 /* we must create after playing with Line since creation may
144 * invalidate the line pointer
146 if ((line
= CreateDrawnLineOnLayer (Layer
, InsertX
, InsertY
,
148 Line
->Thickness
, Line
->Clearance
,
151 AddObjectToCreateUndoList (LINE_TYPE
, Layer
, line
, line
);
152 DrawLine (Layer
, line
);
153 ClearFromPolygon (PCB
->Data
, LINE_TYPE
, Layer
, line
);
154 /* creation call adds it to the rtree */
161 * \brief Inserts a point into a polygon.
164 InsertPointIntoPolygon (LayerType
*Layer
, PolygonType
*Polygon
)
173 * first make sure adding the point is sensible
176 line
.Point1
= Polygon
->Points
[prev_contour_point (Polygon
, InsertAt
)];
177 line
.Point2
= Polygon
->Points
[InsertAt
];
178 if (IsPointOnLine ((float) InsertX
, (float) InsertY
, 0.0, &line
))
182 * second, shift the points up to make room for the new point
184 ErasePolygon (Polygon
);
185 r_delete_entry (Layer
->polygon_tree
, (BoxType
*) Polygon
);
186 save
= *CreateNewPointInPolygon (Polygon
, InsertX
, InsertY
, InsertIncludedAngle
);
187 for (n
= Polygon
->PointN
- 1; n
> InsertAt
; n
--)
188 Polygon
->Points
[n
] = Polygon
->Points
[n
- 1];
190 /* Shift up indices of any holes */
191 for (n
= 0; n
< Polygon
->HoleIndexN
; n
++)
192 if (Polygon
->HoleIndex
[n
] > InsertAt
||
193 (InsertLast
&& Polygon
->HoleIndex
[n
] == InsertAt
))
194 Polygon
->HoleIndex
[n
]++;
196 Polygon
->Points
[InsertAt
] = save
;
197 SetChangedFlag (true);
198 AddObjectToInsertPointUndoList (POLYGONPOINT_TYPE
, Layer
, Polygon
,
199 &Polygon
->Points
[InsertAt
]);
201 SetPolygonBoundingBox (Polygon
);
202 r_insert_entry (Layer
->polygon_tree
, (BoxType
*) Polygon
, 0);
203 InitClip (PCB
->Data
, Layer
, Polygon
);
204 if (Forcible
|| !RemoveExcessPolygonPoints (Layer
, Polygon
))
206 DrawPolygon (Layer
, Polygon
);
209 return (&Polygon
->Points
[InsertAt
]);
213 * \brief Inserts point into objects.
216 InsertPointIntoObject (int Type
, void *Ptr1
, void *Ptr2
, Cardinal
* Ptr3
,
217 Coord DX
, Coord DY
, Angle included_angle
, bool Force
,
225 InsertIncludedAngle
= included_angle
;
227 InsertLast
= insert_last
;
230 /* the operation insert the points to the undo-list */
231 ptr
= ObjectOperation (&InsertFunctions
, Type
, Ptr1
, Ptr2
, Ptr3
);
233 IncrementUndoSerialNumber ();
238 * \brief Adjusts the insert point to make 45 degree lines as necessary.
241 AdjustInsertPoint (void)
243 static PointType InsertedPoint
;
246 LineType
*line
= (LineType
*) Crosshair
.AttachedObject
.Ptr2
;
248 if (Crosshair
.AttachedObject
.State
== STATE_FIRST
)
250 Crosshair
.AttachedObject
.Ptr3
= &InsertedPoint
;
251 if (gui
->shift_is_pressed ())
253 AttachedLineType myline
;
254 /* only force 45 degree for nearest point */
255 if (Distance (Crosshair
.X
, Crosshair
.Y
, line
->Point1
.X
, line
->Point1
.Y
) <
256 Distance (Crosshair
.X
, Crosshair
.Y
, line
->Point2
.X
, line
->Point2
.Y
))
257 myline
.Point1
= myline
.Point2
= line
->Point1
;
259 myline
.Point1
= myline
.Point2
= line
->Point2
;
260 FortyFiveLine (&myline
);
261 InsertedPoint
.X
= myline
.Point2
.X
;
262 InsertedPoint
.Y
= myline
.Point2
.Y
;
263 return &InsertedPoint
;
265 if (TEST_FLAG (ALLDIRECTIONFLAG
, PCB
))
267 InsertedPoint
.X
= Crosshair
.X
;
268 InsertedPoint
.Y
= Crosshair
.Y
;
269 return &InsertedPoint
;
271 if (Crosshair
.X
== line
->Point1
.X
)
272 m1
= 2; /* 2 signals infinite slope */
275 m
= (double) (Crosshair
.Y
- line
->Point1
.Y
) / (Crosshair
.X
- line
->Point1
.X
);
277 if (m
> TAN_30_DEGREE
)
278 m1
= (m
> TAN_60_DEGREE
) ? 2 : 1;
279 else if (m
< -TAN_30_DEGREE
)
280 m1
= (m
< -TAN_60_DEGREE
) ? 2 : -1;
282 if (Crosshair
.X
== line
->Point2
.X
)
283 m2
= 2; /* 2 signals infinite slope */
286 m
= (double) (Crosshair
.Y
- line
->Point2
.Y
) / (Crosshair
.X
- line
->Point2
.X
);
288 if (m
> TAN_30_DEGREE
)
289 m2
= (m
> TAN_60_DEGREE
) ? 2 : 1;
290 else if (m
< -TAN_30_DEGREE
)
291 m2
= (m
< -TAN_60_DEGREE
) ? 2 : -1;
295 InsertedPoint
.X
= line
->Point1
.X
;
296 InsertedPoint
.Y
= line
->Point1
.Y
;
297 return &InsertedPoint
;
302 y
= line
->Point2
.Y
+ m2
* (line
->Point1
.X
- line
->Point2
.X
);
307 y
= line
->Point1
.Y
+ m1
* (line
->Point2
.X
- line
->Point1
.X
);
311 x
= (line
->Point2
.Y
- line
->Point1
.Y
+ m1
* line
->Point1
.X
312 - m2
* line
->Point2
.X
) / (m1
- m2
);
313 y
= (m1
* line
->Point2
.Y
- m1
* m2
* line
->Point2
.X
314 - m2
* line
->Point1
.Y
+ m1
* m2
* line
->Point1
.X
) / (m1
- m2
);
318 return &InsertedPoint
;