|
|
|
|
#usage "<qt><b>Draw a Microstrip Radial Stub</b><p>"
|
|
|
|
|
"RUN microstrip-radial-stub"
|
|
|
|
|
"<p>"
|
|
|
|
|
"<author>Author: support@cadsoft.de </author></qt>"
|
|
|
|
|
|
|
|
|
|
// THIS PROGRAM IS PROVIDED AS IS AND WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED
|
|
|
|
|
|
|
|
|
|
int grid = 1;
|
|
|
|
|
string GridUnit[] = { "MIC", "MM", "MIL", "INCH" };
|
|
|
|
|
real GridWidth[] = { 10.2, 0.0102, 0.4, 0.0004 }; // default by grid
|
|
|
|
|
if (board) { board(B) grid = B.grid.unit; }
|
|
|
|
|
if (library) { library(L) grid = L.grid.unit; }
|
|
|
|
|
|
|
|
|
|
real width = GridWidth[grid];
|
|
|
|
|
string layer = "1";
|
|
|
|
|
string gridstr = "";
|
|
|
|
|
real D = 0.01;
|
|
|
|
|
real L = 0.99;
|
|
|
|
|
|
|
|
|
|
real angle = 30.0; // angle of Stub
|
|
|
|
|
int arcres = angle / 3; // resolution of angle in steps
|
|
|
|
|
real angle_offset = 0.0; // rotate the complete stub
|
|
|
|
|
int polygon = 1; // draw as polygon
|
|
|
|
|
real arcsinXa;
|
|
|
|
|
real arcsinYa;
|
|
|
|
|
real arcsinXe;
|
|
|
|
|
real arcsinYe;
|
|
|
|
|
real ox, oy; // offset X Y
|
|
|
|
|
string signame = "";
|
|
|
|
|
|
|
|
|
|
string cmd_draw_info = "<img src=microstrip-radial-stub.bmp>";
|
|
|
|
|
string s;
|
|
|
|
|
string h;
|
|
|
|
|
string err = " ";
|
|
|
|
|
|
|
|
|
|
int rank = 0;
|
|
|
|
|
if (board) rank = 1;
|
|
|
|
|
string polyinit;
|
|
|
|
|
sprintf (polyinit, "CHANGE ORPHANS ON;\nCHANGE POUR SOLID;\nCHANGE RANK %d;\n", rank);
|
|
|
|
|
|
|
|
|
|
real wwidth2;
|
|
|
|
|
real RadiusL;
|
|
|
|
|
real angleL;
|
|
|
|
|
|
|
|
|
|
int test = 0;
|
|
|
|
|
|
|
|
|
|
// ******************** Functions ****************************
|
|
|
|
|
string esigname(string sig) {
|
|
|
|
|
if (sig) sig = "'" + sig + "'";
|
|
|
|
|
return sig;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ************************************************************************
|
|
|
|
|
string xy_arc( real ang, real radius, real offx, real offy) {
|
|
|
|
|
string xy;
|
|
|
|
|
real rad = PI / 180 * ang;
|
|
|
|
|
sprintf(xy, "(%.4f %.4f)\n",
|
|
|
|
|
offx + (cos(rad) * radius),
|
|
|
|
|
offy + (sin(rad) * radius) );
|
|
|
|
|
return xy;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
real bogenY2( real ang, real radius) {
|
|
|
|
|
real rad = PI / 180 * (ang/2);
|
|
|
|
|
return sin(rad) * radius;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
real bogenX( real ang, real radius) {
|
|
|
|
|
real rad = PI / 180 * (ang/2);
|
|
|
|
|
return cos(rad) * radius;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ***
|
|
|
|
|
real Xneu(real Xalt, real Yalt, real Xorigin, real Yorigin, real UserWinkel) {
|
|
|
|
|
real RADIUS = sqrt(((Xalt - Xorigin) * (Xalt - Xorigin)) + ((Yalt - Yorigin) * (Yalt - Yorigin)));
|
|
|
|
|
real WinkelNeu; /* alter Cosinus Winkel = (Xalt - Xorigin) / RADIUS; */
|
|
|
|
|
|
|
|
|
|
if ((Xalt > Xorigin) && (Yalt >= Yorigin)) { /* Quadrant 1 */
|
|
|
|
|
WinkelNeu = acos((Xalt - Xorigin) / RADIUS) * 57.29578 + UserWinkel;
|
|
|
|
|
real rad = PI / 180 * WinkelNeu;
|
|
|
|
|
return (RADIUS * cos(rad)); }
|
|
|
|
|
if ((Xalt < Xorigin) && (Yalt >= Yorigin)) { /* Quadrant 2 */
|
|
|
|
|
WinkelNeu = acos((Xalt - Xorigin) / RADIUS) * 57.29578 + UserWinkel;
|
|
|
|
|
real rad = PI / 180 * WinkelNeu;
|
|
|
|
|
return (RADIUS * cos(rad)); }
|
|
|
|
|
if ((Xalt < Xorigin) && (Yalt < Yorigin)) { /* Quadrant 3 */
|
|
|
|
|
WinkelNeu = 360 - acos((Xalt - Xorigin) / RADIUS) * 57.29578 + UserWinkel;
|
|
|
|
|
real rad = PI / 180 * WinkelNeu;
|
|
|
|
|
return (RADIUS * cos(rad)); }
|
|
|
|
|
if ((Xalt > Xorigin) && (Yalt < Yorigin)) { /* Quadrant 4 */
|
|
|
|
|
WinkelNeu = 360 - acos((Xalt - Xorigin) / RADIUS) * 57.29578 + UserWinkel;
|
|
|
|
|
real rad = PI / 180 * WinkelNeu;
|
|
|
|
|
return (RADIUS * cos(rad)); }
|
|
|
|
|
if ((Xalt == Xorigin) && (Yalt == Yorigin)) { /* Ursprung */
|
|
|
|
|
WinkelNeu = (Xalt - Xorigin) + UserWinkel;
|
|
|
|
|
real rad = PI / 180 * WinkelNeu;
|
|
|
|
|
return (RADIUS * cos(rad)); }
|
|
|
|
|
if ((Xalt == Xorigin) && (Yalt > Yorigin)) { /* 90<39> */
|
|
|
|
|
WinkelNeu = (Xalt - Xorigin + 90) + UserWinkel;
|
|
|
|
|
real rad = PI / 180 * WinkelNeu;
|
|
|
|
|
return (RADIUS * cos(rad)); }
|
|
|
|
|
if ((Xalt == Xorigin) && (Yalt < Yorigin)) { /* 270<37> */
|
|
|
|
|
WinkelNeu = (Xalt - Xorigin + 270)+ UserWinkel;
|
|
|
|
|
real rad = PI / 180 * WinkelNeu;
|
|
|
|
|
return (RADIUS * cos(rad)); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
real Yneu(real Xalt, real Yalt, real Xorigin, real Yorigin, real UserWinkel) {
|
|
|
|
|
real RADIUS = sqrt(((Xalt - Xorigin) * (Xalt - Xorigin)) + ((Yalt - Yorigin) * (Yalt - Yorigin)));
|
|
|
|
|
real WinkelNeu; /* alter Cosinus Winkel = (Xalt - Xorigin) / RADIUS; */
|
|
|
|
|
|
|
|
|
|
if ((Xalt > Xorigin) && (Yalt >= Yorigin)) { /* Quadrant 1 */
|
|
|
|
|
WinkelNeu = acos((Xalt - Xorigin) / RADIUS) * 57.29578 + UserWinkel;
|
|
|
|
|
real rad = PI / 180 * WinkelNeu;
|
|
|
|
|
return (RADIUS * sin(rad)); }
|
|
|
|
|
if ((Xalt < Xorigin) && (Yalt >= Yorigin)) { /* Quadrant 2 */
|
|
|
|
|
WinkelNeu = acos((Xalt - Xorigin) / RADIUS) * 57.29578 + UserWinkel;
|
|
|
|
|
real rad = PI / 180 * WinkelNeu;
|
|
|
|
|
return (RADIUS * sin(rad)); }
|
|
|
|
|
if ((Xalt < Xorigin) && (Yalt < Yorigin)) { /* Quadrant 3 */
|
|
|
|
|
WinkelNeu = 360 - acos((Xalt - Xorigin) / RADIUS) * 57.29578 + UserWinkel;
|
|
|
|
|
real rad = PI / 180 * WinkelNeu;
|
|
|
|
|
return (RADIUS * sin(rad)); }
|
|
|
|
|
if ((Xalt > Xorigin) && (Yalt < Yorigin)) { /* Quadrant 4 */
|
|
|
|
|
WinkelNeu = 360 - acos((Xalt - Xorigin) / RADIUS) * 57.29578 + UserWinkel;
|
|
|
|
|
real rad = PI / 180 * WinkelNeu;
|
|
|
|
|
return (RADIUS * sin(rad)); }
|
|
|
|
|
if ((Xalt == Xorigin) && (Yalt == Yorigin)) { /* Ursprung */
|
|
|
|
|
WinkelNeu = (Xalt - Xorigin) + UserWinkel;
|
|
|
|
|
real rad = PI / 180 * WinkelNeu;
|
|
|
|
|
return (RADIUS * sin(rad)); }
|
|
|
|
|
if ((Xalt == Xorigin) && (Yalt > Yorigin)) { /* 90<39> */
|
|
|
|
|
WinkelNeu = (Xalt - Xorigin + 90) + UserWinkel;
|
|
|
|
|
real rad = PI / 180 * WinkelNeu;
|
|
|
|
|
return (RADIUS * sin(rad)); }
|
|
|
|
|
if ((Xalt == Xorigin) && (Yalt < Yorigin)) { /* 270<37> */
|
|
|
|
|
WinkelNeu = (Xalt - Xorigin + 270)+ UserWinkel;
|
|
|
|
|
real rad = PI / 180 * WinkelNeu;
|
|
|
|
|
return (RADIUS * sin(rad)); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
real radiusY(real ang, real rry) {
|
|
|
|
|
real r = (rry*2) / sin(PI / 180 * ang) / 2;
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string check_values(void) {
|
|
|
|
|
string error = "";
|
|
|
|
|
wwidth2 = width/2;
|
|
|
|
|
RadiusL = D + L - wwidth2;
|
|
|
|
|
angleL = angle - (width / ((RadiusL * 2 * PI) / 360));
|
|
|
|
|
arcsinXa = bogenX( angle, D) + wwidth2;
|
|
|
|
|
arcsinYa = bogenY2( angle, D + wwidth2) - wwidth2;
|
|
|
|
|
arcsinXe = arcsinXa;
|
|
|
|
|
arcsinYe = -arcsinYa;
|
|
|
|
|
if (arcsinYa < 0) {
|
|
|
|
|
sprintf(error, "<nobr><img src=warning.bmp>Set D to %.4f while W %.4f < wire width %.4f",
|
|
|
|
|
radiusY(angle/2, wwidth2), bogenX( angle, D), width );
|
|
|
|
|
}
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// *** draw arc ***
|
|
|
|
|
string draw_arc(int draw_resol, real draw_radius, real draw_arc_degree, real draw_ang_off, real offx, real offy) {
|
|
|
|
|
real start_arc_degree = draw_ang_off - draw_arc_degree/2;
|
|
|
|
|
if (start_arc_degree < 0) start_arc_degree += 360;
|
|
|
|
|
real end_arc_degree = start_arc_degree + draw_arc_degree;
|
|
|
|
|
real arcstep = (end_arc_degree - start_arc_degree) / draw_resol;
|
|
|
|
|
string e;
|
|
|
|
|
for (real winkel = start_arc_degree; winkel < end_arc_degree + 0.0001; winkel += arcstep) {
|
|
|
|
|
e += xy_arc(winkel, draw_radius, offx, offy) ;
|
|
|
|
|
}
|
|
|
|
|
return e;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// *************************************************************
|
|
|
|
|
void menue(void) {
|
|
|
|
|
dlgDialog("Radial Stub") {
|
|
|
|
|
dlgHBoxLayout {
|
|
|
|
|
dlgSpacing(150);
|
|
|
|
|
dlgLabel("<nobr>Measures in <b>" + GridUnit[grid] + "</b> (Grid)");
|
|
|
|
|
dlgStretch(1);
|
|
|
|
|
dlgGroup(" Draw as") {
|
|
|
|
|
dlgVBoxLayout {
|
|
|
|
|
dlgRadioButton("W&ire", polygon);
|
|
|
|
|
dlgRadioButton("&Polygon", polygon);
|
|
|
|
|
dlgHBoxLayout {
|
|
|
|
|
dlgLabel("&Width");
|
|
|
|
|
dlgSpacing(15);
|
|
|
|
|
dlgRealEdit(width);
|
|
|
|
|
dlgStretch(1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
dlgHBoxLayout {
|
|
|
|
|
dlgLabel(cmd_draw_info, 1);
|
|
|
|
|
dlgGridLayout {
|
|
|
|
|
dlgCell( 1, 1) dlgLabel(" ");
|
|
|
|
|
dlgCell( 2, 1) dlgLabel("Lay&er");
|
|
|
|
|
dlgCell( 2, 2) dlgStringEdit(layer);
|
|
|
|
|
dlgCell( 2, 3) dlgSpacing(8);
|
|
|
|
|
if (board) {
|
|
|
|
|
dlgCell( 2, 4) dlgLabel("&Signal name");
|
|
|
|
|
dlgCell( 2, 5) dlgStringEdit(signame);
|
|
|
|
|
}
|
|
|
|
|
dlgCell( 6, 1) dlgLabel("&L");
|
|
|
|
|
dlgCell( 6, 2) dlgRealEdit(L, 0, +1600);
|
|
|
|
|
dlgCell( 7, 1) dlgLabel("&D");
|
|
|
|
|
dlgCell( 7, 2) dlgRealEdit(D, 0, +1600);
|
|
|
|
|
dlgCell( 9, 1) dlgLabel("&Angle");
|
|
|
|
|
dlgCell( 9, 2) dlgRealEdit(angle, 0.0, 180.0);
|
|
|
|
|
dlgCell( 9, 4) dlgLabel("Angle &offset <20>");
|
|
|
|
|
dlgCell( 9, 5) dlgRealEdit(angle_offset, 0.0, 360.0);
|
|
|
|
|
dlgCell( 10, 1) dlgLabel("A&rc res.");
|
|
|
|
|
dlgCell( 10, 2) dlgIntEdit(arcres, 6, 180);
|
|
|
|
|
dlgCell( 11, 2) dlgLabel(" (steps)");
|
|
|
|
|
|
|
|
|
|
dlgCell( 14, 4) dlgLabel("&X offset");
|
|
|
|
|
dlgCell( 14, 5) dlgRealEdit(ox, -800.0, +800.0);
|
|
|
|
|
dlgCell( 15, 4) dlgLabel("&Y offset");
|
|
|
|
|
dlgCell( 15, 5) dlgRealEdit(oy, -800.0, +800.0);
|
|
|
|
|
}
|
|
|
|
|
dlgStretch(1);
|
|
|
|
|
}
|
|
|
|
|
dlgHBoxLayout {
|
|
|
|
|
dlgVBoxLayout {
|
|
|
|
|
dlgSpacing(50);
|
|
|
|
|
}
|
|
|
|
|
dlgLabel(err, 1);
|
|
|
|
|
dlgStretch(1);
|
|
|
|
|
}
|
|
|
|
|
dlgHBoxLayout {
|
|
|
|
|
dlgPushButton("+OK") {
|
|
|
|
|
err = check_values();
|
|
|
|
|
if (err) {
|
|
|
|
|
if (dlgMessageBox(err, "Accept", "No") == 0) {
|
|
|
|
|
D = radiusY(angle/2, wwidth2);
|
|
|
|
|
err = "";
|
|
|
|
|
}
|
|
|
|
|
else if (dlgMessageBox("Confirm (the values) ?", "Yes", "No") == 0) dlgAccept();
|
|
|
|
|
}
|
|
|
|
|
else dlgAccept();
|
|
|
|
|
}
|
|
|
|
|
dlgPushButton("-Cancel") { dlgReject(); exit(0); }
|
|
|
|
|
dlgStretch(1);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ***** Main ******
|
|
|
|
|
void main(void) {
|
|
|
|
|
if (library) signame = "";
|
|
|
|
|
menue();
|
|
|
|
|
if (angle_offset) {
|
|
|
|
|
real nX = Xneu(arcsinXa, arcsinYa, 0, 0, angle_offset);
|
|
|
|
|
real nY = Yneu(arcsinXa, arcsinYa, 0, 0, angle_offset);
|
|
|
|
|
arcsinXa = nX;
|
|
|
|
|
arcsinYa = nY;
|
|
|
|
|
nX = Xneu(arcsinXe, arcsinYe, 0, 0, angle_offset);
|
|
|
|
|
nY = Yneu(arcsinXe, arcsinYe, 0, 0, angle_offset);
|
|
|
|
|
arcsinXe = nX;
|
|
|
|
|
arcsinYe = nY;
|
|
|
|
|
}
|
|
|
|
|
esigname(signame);
|
|
|
|
|
gridstr = GridUnit[grid];
|
|
|
|
|
|
|
|
|
|
sprintf(s, "SET WIRE_BEND 2;\n");
|
|
|
|
|
if (gridstr) s += "GRID " + gridstr + ";\n";
|
|
|
|
|
if (layer) s += "CHANGE LAYER " + layer + ";\n";
|
|
|
|
|
sprintf(h, "CHANGE WIDTH %.4f;\n", width);
|
|
|
|
|
s += h;
|
|
|
|
|
if (polygon) {
|
|
|
|
|
s += polyinit;
|
|
|
|
|
sprintf(h, "POLY %s ", signame );
|
|
|
|
|
}
|
|
|
|
|
else sprintf(h, "WIRE %s ", signame );
|
|
|
|
|
s += h;
|
|
|
|
|
sprintf(h, " (%.4f %.4f)", arcsinXa + ox, arcsinYa + oy); // *** draw sinw ***
|
|
|
|
|
s += h;
|
|
|
|
|
sprintf(h, " (%.4f %.4f)", arcsinXe + ox, arcsinYe + oy);
|
|
|
|
|
s += h;
|
|
|
|
|
s += draw_arc(arcres, RadiusL, angleL, angle_offset, ox, oy); // *** draw arc ***
|
|
|
|
|
sprintf(h, " (%.4f %.4f)", arcsinXa + ox, arcsinYa +oy);
|
|
|
|
|
s += h;
|
|
|
|
|
if (gridstr) {
|
|
|
|
|
sprintf(h, ";\nGRID LAST;\n");
|
|
|
|
|
s += h;
|
|
|
|
|
}
|
|
|
|
|
if (test) if (dlgMessageBox(s, "OK", "ESC") != 0) exit (-1);
|
|
|
|
|
exit (s);
|
|
|
|
|
}
|