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 <wxPcbStruct.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 90 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().

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

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

Referenced by BuildCornersList_S_Shape().

53 {
54  const int SEGM_COUNT_PER_360DEG = 16;
55  auto first_point = aStartPoint - aCenter;
56  int seg_count = ( ( abs( a_ArcAngle ) ) * SEGM_COUNT_PER_360DEG ) / 3600;
57 
58  if( seg_count == 0 )
59  seg_count = 1;
60 
61  double increment_angle = (double) a_ArcAngle * M_PI / 1800 / seg_count;
62 
63  // Creates nb_seg point to approximate arc by segments:
64  for( int ii = 1; ii <= seg_count; ii++ )
65  {
66  double rot_angle = increment_angle * ii;
67  double fcos = cos( rot_angle );
68  double fsin = sin( rot_angle );
69  wxPoint currpt;
70 
71  // Rotate current point:
72  currpt.x = KiROUND( ( first_point.x * fcos + first_point.y * fsin ) );
73  currpt.y = KiROUND( ( first_point.y * fcos - first_point.x * fsin ) );
74 
75  auto corner = aCenter + currpt;
76  aBuffer.push_back( corner );
77  }
78 }
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