KiCad PCB EDA Suite
microwave_inductor.cpp File Reference
#include "microwave_inductor.h"
#include <wx/wx.h>
#include <base_units.h>
#include <validators.h>
#include <dialog_text_entry.h>
#include <pcb_edit_frame.h>
#include <class_pad.h>
#include <class_edge_mod.h>
#include <class_module.h>

Go to the source code of this file.

Macros

#define ADJUST_SIZE   0.988
 

Functions

static void gen_arc (std::vector< wxPoint > &aBuffer, const wxPoint &aStartPoint, const wxPoint &aCenter, int a_ArcAngle)
 Function gen_arc generates an arc using arc approximation by lines: Center aCenter Angle "angle" (in 0.1 deg) More...
 
static int BuildCornersList_S_Shape (std::vector< wxPoint > &aBuffer, const wxPoint &aStartPoint, const wxPoint &aEndPoint, int aLength, int aWidth)
 Function BuildCornersList_S_Shape Create a path like a S-shaped coil. More...
 

Macro Definition Documentation

#define ADJUST_SIZE   0.988

Function Documentation

static int BuildCornersList_S_Shape ( std::vector< wxPoint > &  aBuffer,
const wxPoint aStartPoint,
const wxPoint aEndPoint,
int  aLength,
int  aWidth 
)
static

Function BuildCornersList_S_Shape Create a path like a S-shaped coil.

Parameters
aBuffer= a buffer where to store points (ends of segments)
aStartPoint= starting point of the path
aEndPoint= ending point of the path
aLength= full length of the path
aWidth= segment width

Definition at line 91 of file microwave_inductor.cpp.

References ADJUST_SIZE, PNS::angle(), ArcTangente(), EuclideanNorm(), gen_arc(), KiROUND(), min, RotatePoint(), sign(), wxPoint::x, and wxPoint::y.

Referenced by MWAVE::CreateMicrowaveInductor().

95 {
96 /* We must determine:
97  * segm_count = number of segments perpendicular to the direction
98  * segm_len = length of a strand
99  * radius = radius of rounded parts of the coil
100  * stubs_len = length of the 2 stubs( segments parallel to the direction)
101  * connecting the start point to the start point of the S shape
102  * and the ending point to the end point of the S shape
103  * The equations are (assuming the area size of the entire shape is Size:
104  * Size.x = 2 * radius + segm_len
105  * Size.y = (segm_count + 2 ) * 2 * radius + 2 * stubs_len
106  * inductorPattern.m_length = 2 * delta // connections to the coil
107  * + (segm_count-2) * segm_len // length of the strands except 1st and last
108  * + (segm_count) * (PI * radius) // length of rounded
109  * segm_len + / 2 - radius * 2) // length of 1st and last bit
110  *
111  * The constraints are:
112  * segm_count >= 2
113  * radius < m_Size.x
114  * Size.y = (radius * 4) + (2 * stubs_len)
115  * segm_len > radius * 2
116  *
117  * The calculation is conducted in the following way:
118  * first:
119  * segm_count = 2
120  * radius = 4 * Size.x (arbitrarily fixed value)
121  * Then:
122  * Increasing the number of segments to the desired length
123  * (radius decreases if necessary)
124  */
125  wxPoint size;
126 
127  // This scale factor adjusts the arc length to handle
128  // the arc to segment approximation.
129  // because we use SEGM_COUNT_PER_360DEG segment to approximate a circle,
130  // the trace len must be corrected when calculated using arcs
131  // this factor adjust calculations and must be changed if SEGM_COUNT_PER_360DEG is modified
132  // because trace using segment is shorter the corresponding arc
133  // ADJUST_SIZE is the ratio between tline len and the arc len for an arc
134  // of 360/ADJUST_SIZE angle
135  #define ADJUST_SIZE 0.988
136 
137  auto pt = aEndPoint - aStartPoint;
138  double angle = -ArcTangente( pt.y, pt.x );
139  int min_len = KiROUND( EuclideanNorm( pt ) );
140  int segm_len = 0; // length of segments
141  int full_len; // full len of shape (sum of length of all segments + arcs)
142 
143 
144  /* Note: calculations are made for a vertical coil (more easy calculations)
145  * and after points are rotated to their actual position
146  * So the main direction is the Y axis.
147  * the 2 stubs are on the Y axis
148  * the others segments are parallel to the X axis.
149  */
150 
151  // Calculate the size of area (for a vertical shape)
152  size.x = min_len / 2;
153  size.y = min_len;
154 
155  // Choose a reasonable starting value for the radius of the arcs.
156  int radius = std::min( aWidth * 5, size.x / 4 );
157 
158  int segm_count; // number of full len segments
159  // the half size segments (first and last segment) are not counted here
160  int stubs_len = 0; // length of first or last segment (half size of others segments)
161 
162  for( segm_count = 0; ; segm_count++ )
163  {
164  stubs_len = ( size.y - ( radius * 2 * (segm_count + 2 ) ) ) / 2;
165 
166  if( stubs_len < size.y / 10 ) // Reduce radius.
167  {
168  stubs_len = size.y / 10;
169  radius = ( size.y - (2 * stubs_len) ) / ( 2 * (segm_count + 2) );
170 
171  if( radius < aWidth ) // Radius too small.
172  {
173  // Unable to create line: Requested length value is too large for room
174  return 0;
175  }
176  }
177 
178  segm_len = size.x - ( radius * 2 );
179  full_len = 2 * stubs_len; // Length of coil connections.
180  full_len += segm_len * segm_count; // Length of full length segments.
181  full_len += KiROUND( ( segm_count + 2 ) * M_PI * ADJUST_SIZE * radius ); // Ard arcs len
182  full_len += segm_len - (2 * radius); // Length of first and last segments
183  // (half size segments len = segm_len/2 - radius).
184 
185  if( full_len >= aLength )
186  break;
187  }
188 
189  // Adjust len by adjusting segm_len:
190  int delta_size = full_len - aLength;
191 
192  // reduce len of the segm_count segments + 2 half size segments (= 1 full size segment)
193  segm_len -= delta_size / (segm_count + 1);
194 
195  // Generate first line (the first stub) and first arc (90 deg arc)
196  pt = aStartPoint;
197  aBuffer.push_back( pt );
198  pt.y += stubs_len;
199  aBuffer.push_back( pt );
200 
201  auto centre = pt;
202  centre.x -= radius;
203  gen_arc( aBuffer, pt, centre, -900 );
204  pt = aBuffer.back();
205 
206  int half_size_seg_len = segm_len / 2 - radius;
207 
208  if( half_size_seg_len )
209  {
210  pt.x -= half_size_seg_len;
211  aBuffer.push_back( pt );
212  }
213 
214  // Create shape.
215  int ii;
216  int sign = 1;
217  segm_count += 1; // increase segm_count to create the last half_size segment
218 
219  for( ii = 0; ii < segm_count; ii++ )
220  {
221  int arc_angle;
222 
223  if( ii & 1 ) // odd order arcs are greater than 0
224  sign = -1;
225  else
226  sign = 1;
227 
228  arc_angle = 1800 * sign;
229  centre = pt;
230  centre.y += radius;
231  gen_arc( aBuffer, pt, centre, arc_angle );
232  pt = aBuffer.back();
233  pt.x += segm_len * sign;
234  aBuffer.push_back( pt );
235  }
236 
237  // The last point is false:
238  // it is the end of a full size segment, but must be
239  // the end of the second half_size segment. Change it.
240  sign *= -1;
241  aBuffer.back().x = aStartPoint.x + radius * sign;
242 
243  // create last arc
244  pt = aBuffer.back();
245  centre = pt;
246  centre.y += radius;
247  gen_arc( aBuffer, pt, centre, 900 * sign );
248 
249  // Rotate point
250  angle += 900;
251 
252  for( unsigned jj = 0; jj < aBuffer.size(); jj++ )
253  {
254  RotatePoint( &aBuffer[jj], aStartPoint, angle );
255  }
256 
257  // push last point (end point)
258  aBuffer.push_back( aEndPoint );
259 
260  return 1;
261 }
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
Definition: trigo.h:112
static int KiROUND(double v)
KiROUND rounds a floating point number to an int using "round halfway cases away from zero"...
Definition: common.h:107
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:216
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:170
static void gen_arc(std::vector< wxPoint > &aBuffer, const wxPoint &aStartPoint, const wxPoint &aCenter, int a_ArcAngle)
Function gen_arc generates an arc using arc approximation by lines: Center aCenter Angle "angle" (in ...
#define ADJUST_SIZE
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
#define min(a, b)
Definition: auxiliary.h:85
int sign(T val)
Definition: math_util.h:44
static void gen_arc ( std::vector< wxPoint > &  aBuffer,
const wxPoint aStartPoint,
const wxPoint aCenter,
int  a_ArcAngle 
)
static

Function gen_arc generates an arc using arc approximation by lines: Center aCenter Angle "angle" (in 0.1 deg)

Parameters
aBuffer= a buffer to store points.
aStartPoint= starting point of arc.
aCenter= arc centre.
a_ArcAngle= arc length in 0.1 degrees.

Definition at line 50 of file microwave_inductor.cpp.

References abs, KiROUND(), wxPoint::x, and wxPoint::y.

Referenced by BuildCornersList_S_Shape().

54 {
55  const int SEGM_COUNT_PER_360DEG = 16;
56  auto first_point = aStartPoint - aCenter;
57  int seg_count = ( ( abs( a_ArcAngle ) ) * SEGM_COUNT_PER_360DEG ) / 3600;
58 
59  if( seg_count == 0 )
60  seg_count = 1;
61 
62  double increment_angle = (double) a_ArcAngle * M_PI / 1800 / seg_count;
63 
64  // Creates nb_seg point to approximate arc by segments:
65  for( int ii = 1; ii <= seg_count; ii++ )
66  {
67  double rot_angle = increment_angle * ii;
68  double fcos = cos( rot_angle );
69  double fsin = sin( rot_angle );
70  wxPoint currpt;
71 
72  // Rotate current point:
73  currpt.x = KiROUND( ( first_point.x * fcos + first_point.y * fsin ) );
74  currpt.y = KiROUND( ( first_point.y * fcos - first_point.x * fsin ) );
75 
76  auto corner = aCenter + currpt;
77  aBuffer.push_back( corner );
78  }
79 }
static int KiROUND(double v)
KiROUND rounds a floating point number to an int using "round halfway cases away from zero"...
Definition: common.h:107
#define abs(a)
Definition: auxiliary.h:84