kopia lustrzana https://github.com/miguelvaca/vk3cpu
Added support for octagon, hexagon and square shaped loops.
rodzic
76c3a14615
commit
e84b2e96ae
BIN
L_hex.png
BIN
L_hex.png
Plik binarny nie jest wyświetlany.
Przed Szerokość: | Wysokość: | Rozmiar: 6.2 KiB Po Szerokość: | Wysokość: | Rozmiar: 6.3 KiB |
BIN
L_oct.png
BIN
L_oct.png
Plik binarny nie jest wyświetlany.
Przed Szerokość: | Wysokość: | Rozmiar: 6.3 KiB Po Szerokość: | Wysokość: | Rozmiar: 6.3 KiB |
BIN
L_sqr.png
BIN
L_sqr.png
Plik binarny nie jest wyświetlany.
Przed Szerokość: | Wysokość: | Rozmiar: 6.1 KiB Po Szerokość: | Wysokość: | Rozmiar: 6.3 KiB |
650
magloop.html
650
magloop.html
|
@ -7,7 +7,7 @@
|
||||||
<link rel="stylesheet" href="magloop.css">
|
<link rel="stylesheet" href="magloop.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>Miguel <a href="mailto:vk3cpu@gmail.com">VK3CPU</a> - Magloop Antenna Calculator V4</header>
|
<header>Miguel <a href="mailto:vk3cpu@gmail.com">VK3CPU</a> - Magloop Antenna Calculator V5</header>
|
||||||
<section class="gridLayoutClass">
|
<section class="gridLayoutClass">
|
||||||
<div class="chart-container" style="position: relative;">
|
<div class="chart-container" style="position: relative;">
|
||||||
<canvas id="chartCanvas" class="chartCanvasClass">
|
<canvas id="chartCanvas" class="chartCanvasClass">
|
||||||
|
@ -36,24 +36,22 @@
|
||||||
<input type="range" id="transmit_power_slider" min="5" max="1500" value="100" step="5">
|
<input type="range" id="transmit_power_slider" min="5" max="1500" value="100" step="5">
|
||||||
</div>
|
</div>
|
||||||
<div class="radios">
|
<div class="radios">
|
||||||
<label>Metr</label>
|
<label>Met</label>
|
||||||
<input type="radio" name="unit_radio" id="metric_radio" value="metric" checked/>
|
<input type="radio" name="unit_radio" id="metric_radio" value="metric" checked/>
|
||||||
<label>Impr</label>
|
<label>Imp</label>
|
||||||
<input type="radio" name="unit_radio" id="imperial_radio" value="imperial"/>
|
<input type="radio" name="unit_radio" id="imperial_radio" value="imperial"/>
|
||||||
<label>Cu</label>
|
<label>Cu</label>
|
||||||
<input type="radio" name="metal_radio" id="copper_radio" value="copper" checked/>
|
<input type="radio" name="metal_radio" id="copper_radio" value="copper" checked/>
|
||||||
<label>Al</label>
|
<label>Al</label>
|
||||||
<input type="radio" name="metal_radio" id="aluminium_radio" value="aluminium"/>
|
<input type="radio" name="metal_radio" id="aluminium_radio" value="aluminium"/>
|
||||||
<!--
|
|
||||||
<label>Circ</label>
|
<label>Circ</label>
|
||||||
<input type="radio" name="shape_radio" id="circle_radio" value="circle" checked/>
|
<input type="radio" name="shape_radio" id="circle_radio" value="circle" checked/>
|
||||||
<label>Oct</label>
|
<label>Oct</label>
|
||||||
<input type="radio" name="shape_radio" id="oct_radio" value="oct"/>
|
<input type="radio" name="shape_radio" id="oct_radio" value="octagon"/>
|
||||||
<label>Hex</label>
|
<label>Hex</label>
|
||||||
<input type="radio" name="shape_radio" id="hex_radio" value="hex"/>
|
<input type="radio" name="shape_radio" id="hex_radio" value="hexagon"/>
|
||||||
<label>Sqr</label>
|
<label>Sqr</label>
|
||||||
<input type="radio" name="shape_radio" id="square_radio" value="square"/>
|
<input type="radio" name="shape_radio" id="square_radio" value="square"/>
|
||||||
-->
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="antenna-front-container" class="antennaFront-container" style="position: relative;">
|
<div id="antenna-front-container" class="antennaFront-container" style="position: relative;">
|
||||||
|
@ -65,8 +63,10 @@
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
<div class="notes">
|
<div class="notes">
|
||||||
<b><u>Notes:</u></b><br> The Magloop Antenna Calculator was developed to predict the characteristics of a small-loop (aka "magnetic loop" or "magloop")
|
<p style="text-align:center"><b><u><a href="./magloop_equations.html"> EQUATIONS USED </a></u></b></p>
|
||||||
antenna, given physical dimensions entered via slider widgets. It assumes the main loop is made from a round
|
<b><u>Notes:</u></b><br>
|
||||||
|
The Magloop Antenna Calculator was developed to predict the characteristics of a small-loop (aka "magnetic loop" or "magloop")
|
||||||
|
antenna, given physical dimensions entered via slider widgets. It assumes the main loop is made from a hollow round
|
||||||
anodised copper or aluminium conductor. I developed this multi-turn capable magloop calculator to take advantage of the
|
anodised copper or aluminium conductor. I developed this multi-turn capable magloop calculator to take advantage of the
|
||||||
touch-screens and high-speed of modern mobile phones, to allow users to get realtime feedback of the predicted
|
touch-screens and high-speed of modern mobile phones, to allow users to get realtime feedback of the predicted
|
||||||
behaviour of a magloop antenna. This would help a radio amateur to decide on the characteristics for the build. <br>-- 73 de VK3CPU<br><br>
|
behaviour of a magloop antenna. This would help a radio amateur to decide on the characteristics for the build. <br>-- 73 de VK3CPU<br><br>
|
||||||
|
@ -86,9 +86,9 @@
|
||||||
<li>L : Inductance in microhenries.</li>
|
<li>L : Inductance in microhenries.</li>
|
||||||
<li>A : Loop area in square meters or square feet.</li>
|
<li>A : Loop area in square meters or square feet.</li>
|
||||||
<li>C : Effective capacitance for multi-turn loops in picofarads.</li>
|
<li>C : Effective capacitance for multi-turn loops in picofarads.</li>
|
||||||
<li>circ : Circumference of the main loop in meters or feet.</li>
|
<li>peri : Perimeter of the main loop in meters or feet.</li>
|
||||||
<li>c : Distance between windings, measured from the conductor centers in mm or inches.</li>
|
<li>c : Distance between windings, measured from the conductor centers in mm or inches.</li>
|
||||||
<li>cond : Total conductor length in meters or feet.</li>
|
<li>cond : Total required conductor length in meters or feet.</li>
|
||||||
<li>Tuning Cap (pF): The capacitance required to bring the loop into resonance at the given frequency. Value in picofarads.</li>
|
<li>Tuning Cap (pF): The capacitance required to bring the loop into resonance at the given frequency. Value in picofarads.</li>
|
||||||
<li>Vcap (kV): The predicted voltage across the capacitance given the desired transmit power.</li>
|
<li>Vcap (kV): The predicted voltage across the capacitance given the desired transmit power.</li>
|
||||||
<li>BW (kHz): The predicted 3dB bandwidth of the magloop antenna. This is calculated from the predicted Q and the center frequency.</li>
|
<li>BW (kHz): The predicted 3dB bandwidth of the magloop antenna. This is calculated from the predicted Q and the center frequency.</li>
|
||||||
|
@ -99,41 +99,38 @@
|
||||||
<li>Q : The quality factor, which is the reactance divided by the resistance of the loop at that frequency.</li>
|
<li>Q : The quality factor, which is the reactance divided by the resistance of the loop at that frequency.</li>
|
||||||
<li>Ia (A): The RMS loop current in amps.</li>
|
<li>Ia (A): The RMS loop current in amps.</li>
|
||||||
</ul>
|
</ul>
|
||||||
<b><u>Formula used for calculations:</u></b><br>
|
|
||||||
<img src="MagloopSingleTurnInductance.png" alt="magloop single-turn antenna inductance"><br>
|
|
||||||
<img src="MagloopMultiTurnInductance.png" alt="magloop multi-turn antenna inductance"><br>
|
|
||||||
<img src="MagloopLossResistance.png" alt="magloop multi-turn loss resistance"><br>
|
|
||||||
<img src="MagloopSurfaceResistance.png" alt="magloop surface resistance of conductor"><br>
|
|
||||||
<img src="MagloopRadiationResistance.png" alt="multi-turn magloop radiation resistance"><br>
|
|
||||||
<img src="MagloopEfficiency.png" alt="magloop antenna efficiency"><br>
|
|
||||||
<img src="MagloopQ.png" alt="magloop antenna Q factor"><br>
|
|
||||||
<img src="Vcap.png" alt="magloop antenna capacitor voltage"><br>
|
|
||||||
<img src="I_loop.png" alt="magloop antenna loop current"><br>
|
|
||||||
<img src="BW.png" alt="magloop antenna bandwidth"><br>
|
|
||||||
<!-- img src="MultiloopCapacitance.png" alt="magloop antenna multi-turn loop capacitance"><br-->
|
|
||||||
<br>
|
<br>
|
||||||
<b><u>Change history:</u></b><br>
|
<b><u>Change history:</u></b><br>
|
||||||
[16-Sep-21] : Update to release V4: Updated equation used for Q to match the one use in the ARRL Antenna Book. This will affect predictions for V_cap, I_loop and BW. (Based on confirmation of correct Q equation used in
|
<b>[18-Sep-21]</b> <br>
|
||||||
"Impedance, Bandwidth, and Q of Antennas" by A D Yaghjian, IEEE Transactions on Antennas and Propagation, April 2005.)<br>
|
* Updated to V5; Added support for octagon, hexagon and square shaped loops. Moved and hyperlinked equations-used to a separate page for clarity.<br>
|
||||||
[16-Sep-21] : Added equation graphics for V_cap, I_loop and BW formulas.<br>
|
<b>[16-Sep-21]</b> <br>
|
||||||
[16-Sep-21] : Flipped the main-loop graphic to have the capacitor above the coupling loop.<br>
|
* Updated to V4; Updated equation used for Q to match the one use in the ARRL Antenna Book. This will affect predictions for V_cap, I_loop and BW. (Based on confirmation of correct Q equation used in
|
||||||
[12-Sep-21] : Set maximum values to Q, Vcap and I axes to stop autoscaling. Max Q set to 2000, Vcap to 20 kV and I to 100 A.<br>
|
<i>"Impedance, Bandwidth, and Q of Antennas"</i> by A D Yaghjian, IEEE Transactions on Antennas and Propagation, April 2005.)<br>
|
||||||
[12-Sep-21] : Added formula/equation graphics in Notes section. A few more complex ones, such as effective capacitance and SRF, are still needed.<br>
|
* Added equation graphics for V_cap, I_loop and BW formulas.<br>
|
||||||
[12-Sep-21] : Fixed minor error in calculation of resistive loss due to proximity effect.<br>
|
* Flipped the main-loop graphic to have the capacitor above the coupling loop.<br>
|
||||||
[11-Sep-21] : Added visual cues for all slider-controlled parameters to highlight which parameter is being modified in the graphic representation.<br>
|
<b>[12-Sep-21]</b> <br>
|
||||||
[10-Sep-21] : Added c/a display to graphic representation. Moved N from center to left.<br>
|
* Set maximum values to Q, Vcap and I axes to stop autoscaling. Max Q set to 2000, Vcap to 20 kV and I to 100 A.<br>
|
||||||
[30-Aug-21] : Added SRF calculation and display for multi-loop antennas.<br>
|
* Added formula/equation graphics in Notes section. A few more complex ones, such as effective capacitance and SRF, are still needed.<br>
|
||||||
[28-Aug-21] : Added support for imperial units and for aluminum metal.<br>
|
* Fixed minor error in calculation of resistive loss due to proximity effect.<br>
|
||||||
[27-Jul-21] : Added total conductor length display.<br>
|
<b>[11-Sep-21]</b> <br>
|
||||||
[24-Jul-21] : Added loop circumference display.<br>
|
* Added visual cues for all slider-controlled parameters to highlight which parameter is being modified in the graphic representation.<br>
|
||||||
|
<b>[10-Sep-21]</b> <br>
|
||||||
|
* Added c/a display to graphic representation. Moved N from center to left.<br>
|
||||||
|
<b>[30-Aug-21]</b> <br>
|
||||||
|
* Added SRF calculation and display for multi-loop antennas.<br>
|
||||||
|
<b>[28-Aug-21]</b> <br>
|
||||||
|
* Added support for imperial units and for aluminum metal.<br>
|
||||||
|
<b>[27-Jul-21]</b> <br>
|
||||||
|
* Added total conductor length display.<br>
|
||||||
|
<b>[24-Jul-21]</b> <br>
|
||||||
|
* Added loop circumference display.<br>
|
||||||
<br>
|
<br>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-crosshair@1.1.2"></script>
|
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-crosshair@1.1.2"></script>
|
||||||
<script>
|
<script>
|
||||||
var frequencies = [];
|
// GUI control widgets:
|
||||||
|
|
||||||
var loop_diameter_slider = document.getElementById("loop_diameter_slider");
|
var loop_diameter_slider = document.getElementById("loop_diameter_slider");
|
||||||
var conductor_diameter_slider = document.getElementById("conductor_diameter_slider");
|
var conductor_diameter_slider = document.getElementById("conductor_diameter_slider");
|
||||||
var loop_turns_slider = document.getElementById("loop_turns_slider");
|
var loop_turns_slider = document.getElementById("loop_turns_slider");
|
||||||
|
@ -141,9 +138,20 @@
|
||||||
var transmit_power_slider = document.getElementById("transmit_power_slider");
|
var transmit_power_slider = document.getElementById("transmit_power_slider");
|
||||||
var metric_radio = document.getElementById("metric_radio");
|
var metric_radio = document.getElementById("metric_radio");
|
||||||
var imperial_radio = document.getElementById("imperial_radio");
|
var imperial_radio = document.getElementById("imperial_radio");
|
||||||
|
var shape_radio = document.getElementById("shape_radio");
|
||||||
|
|
||||||
|
// Global variables:
|
||||||
var units = "metric";
|
var units = "metric";
|
||||||
var conductivity = 58e6; // Default is annealed copper
|
var conductivity = 58e6; // Default is annealed copper
|
||||||
|
var shape = "circle"; // Shape of the main loop
|
||||||
|
|
||||||
|
var inductance = 0.0;
|
||||||
|
var area = 0.0; // Loop area in square meters.
|
||||||
|
var perimeter = 0.0; // Perimeter of a single turn of the main loop
|
||||||
|
var multiloop_capacitance = 0.0; // Effective capacitance of a multi-turn loop
|
||||||
|
var conductor_length = 0.0; // Total conductor length
|
||||||
|
|
||||||
|
var frequencies = [];
|
||||||
|
|
||||||
function updateFrequencies() {
|
function updateFrequencies() {
|
||||||
const hamFrequencies = [
|
const hamFrequencies = [
|
||||||
|
@ -162,9 +170,57 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the frequencies, now that we have the sliders available:
|
function setGlobals() {
|
||||||
updateFrequencies();
|
inductance = getInductance();
|
||||||
|
area = getArea();
|
||||||
|
perimeter = getPerimeter();
|
||||||
|
multiloop_capacitance = (loop_turns_slider.value > 1) ? multiloopCapacitance() : 0.0;
|
||||||
|
conductor_length = ((((perimeter* loop_turns_slider.value) ** 2.0) + ((loop_spacing_slider.value * conductor_diameter_slider.value * 1e-3 * loop_turns_slider.value) ** 2.0)) ** 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the loop area in square meters:
|
||||||
|
function getArea() {
|
||||||
|
var l_area = 0.0;
|
||||||
|
const width = loop_diameter_slider.value;
|
||||||
|
if(shape == "circle") {
|
||||||
|
l_area = 3.141592 * (0.5 * width)**2;
|
||||||
|
} else
|
||||||
|
if(shape == "octagon") {
|
||||||
|
const r = 0.4142135 * width;
|
||||||
|
l_area = 4.8284 * r**2.0;
|
||||||
|
} else
|
||||||
|
if(shape == "hexagon") {
|
||||||
|
const r = 0.5 * width;
|
||||||
|
l_area = 3.4641 * r**2.0;
|
||||||
|
} else
|
||||||
|
if(shape == "square") {
|
||||||
|
l_area = width **2.0;
|
||||||
|
}
|
||||||
|
return l_area;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the loop area in square meters:
|
||||||
|
function getPerimeter() {
|
||||||
|
var l_perimeter = 0.0;
|
||||||
|
const width = loop_diameter_slider.value;
|
||||||
|
if(shape == "circle") {
|
||||||
|
l_perimeter = 3.141592 * width;
|
||||||
|
} else
|
||||||
|
if(shape == "octagon") {
|
||||||
|
const r = 0.4142135 * width;
|
||||||
|
l_perimeter = 8 * r;
|
||||||
|
} else
|
||||||
|
if(shape == "hexagon") {
|
||||||
|
const r = 0.5 * width;
|
||||||
|
const t = 2.0 * r * 0.57735;
|
||||||
|
l_perimeter = 6 * t;
|
||||||
|
} else
|
||||||
|
if(shape == "square") {
|
||||||
|
l_perimeter = 4 * width;
|
||||||
|
}
|
||||||
|
return l_perimeter;
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate the inductance of the coil. For single turn loops, use standard inductance equation. For multi-turn, use Nagaoka correction.
|
// Calculate the inductance of the coil. For single turn loops, use standard inductance equation. For multi-turn, use Nagaoka correction.
|
||||||
function getInductance() {
|
function getInductance() {
|
||||||
const mu0 = Math.PI * 4e-7;
|
const mu0 = Math.PI * 4e-7;
|
||||||
|
@ -176,22 +232,57 @@
|
||||||
const a_coil_radius = loop_diameter_meters * 0.5;
|
const a_coil_radius = loop_diameter_meters * 0.5;
|
||||||
const coil_length = cond_diameter_meters * spacing_ratio * loop_turns;
|
const coil_length = cond_diameter_meters * spacing_ratio * loop_turns;
|
||||||
var retval = 0.0;
|
var retval = 0.0;
|
||||||
if(loop_turns > 1) {
|
|
||||||
retval = (loop_turns**2.0) * mu0 * Math.PI * (a_coil_radius**2.0) * nagaokaCoefficient() / coil_length;
|
if(shape == "circle") {
|
||||||
} else {
|
if(loop_turns > 1) {
|
||||||
const b_conductor_radius = cond_diameter_meters * 0.5;
|
retval = (loop_turns**2.0) * mu0 * Math.PI * (a_coil_radius**2.0) * nagaokaCoefficient() / coil_length;
|
||||||
retval = mu0 * a_coil_radius * (Math.log(8.0 * a_coil_radius / b_conductor_radius) - 2.0);
|
} else {
|
||||||
|
const b_conductor_radius = cond_diameter_meters * 0.5;
|
||||||
|
retval = mu0 * a_coil_radius * (Math.log(8.0 * a_coil_radius / b_conductor_radius) - 2.0);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if(shape == "octagon") {
|
||||||
|
const N = loop_turns;
|
||||||
|
const s = (100.0 * loop_diameter_meters) * 0.414213; // side length in cm
|
||||||
|
const l = (N>1) ? (coil_length * 100.0) : (cond_diameter_meters * 100.0); // coil length in cm
|
||||||
|
const bOn2r = l / (1.09868411*s);
|
||||||
|
//retval = 1e-6 * 0.016 * (N**2) * s * ( Math.log((2.613*s*N)/((N+1)*l)) + 0.75143 + ((0.07153*(N+1)*l) / (s*N)));
|
||||||
|
retval = 1e-6 * 0.016 * (N**2) * s * ( Math.log(1.0/bOn2r) + 0.75143 + 0.18693*bOn2r + 0.11969*bOn2r**2 - 0.08234*bOn2r**4);
|
||||||
|
} else
|
||||||
|
if(shape == "hexagon") {
|
||||||
|
const N = loop_turns;
|
||||||
|
const s = (100.0 * loop_diameter_meters) * 0.57735; // side length in cm
|
||||||
|
const l = (N>1) ? (coil_length * 100.0) : (cond_diameter_meters * 100.0); // coil length in cm
|
||||||
|
const bOn2r = l / (loop_diameter_meters * 115.470);
|
||||||
|
//console.log(N, s, l);
|
||||||
|
//retval = 1e-6 * 0.012 * (N**2) * s * ( Math.log((2.0*s*N)/((N+1)*l)) + 0.65533 + ((0.1348*(N+1)*l) / (s*N)));
|
||||||
|
retval = 1e-6 * 0.012 * (N**2) * s * ( Math.log(1.0/bOn2r) + 0.65533 + 0.26960*bOn2r + 0.07736*bOn2r**2 - 0.05504*bOn2r**4);
|
||||||
|
} else
|
||||||
|
if(shape == "square") {
|
||||||
|
const N = loop_turns;
|
||||||
|
const s = (100.0 * loop_diameter_meters); // side length in cm
|
||||||
|
const l = (N>1) ? (coil_length * 100.0) : (cond_diameter_meters * 100.0); // coil length in cm
|
||||||
|
const bOn2r = l / (loop_diameter_meters * 141.4214);
|
||||||
|
//console.log(N, s, l);
|
||||||
|
//retval = 1e-6 * 0.008 * (N**2) * s * ( Math.log((1.4142*s*N)/((N+1)*l)) + 0.37942 + ((0.3333*(N+1)*l)/(s*N)));
|
||||||
|
retval = 1e-6 * 0.008 * (N**2) * s * ( Math.log(1.0/bOn2r) + 0.37942 + 0.47140*bOn2r - 0.014298*bOn2r**2 - 0.02904*bOn2r**4);
|
||||||
}
|
}
|
||||||
return retval; // In Henries
|
return retval; // In Henries
|
||||||
}
|
}
|
||||||
|
|
||||||
function radiationResistance(frequency) {
|
function radiationResistance(frequency) {
|
||||||
const n_turns = loop_turns_slider.value;
|
const n_turns = loop_turns_slider.value;
|
||||||
const k = 20.0 * (Math.PI ** 2.0);
|
|
||||||
const wavelength = 3e8 / frequency;
|
const wavelength = 3e8 / frequency;
|
||||||
const l = (Math.PI * loop_diameter_slider.value) / wavelength;
|
var retval = 0.0;
|
||||||
const rr = (n_turns ** 2.0) * k * (l ** 4.0);
|
|
||||||
return rr;
|
if(shape == "circle") {
|
||||||
|
const k = 20.0 * (Math.PI ** 2.0);
|
||||||
|
const l = (Math.PI * loop_diameter_slider.value) / wavelength;
|
||||||
|
retval = (n_turns ** 2.0) * k * (l ** 4.0);
|
||||||
|
} else {
|
||||||
|
retval = (31171.0 * n_turns**2.0 * area**2.0) / (wavelength**4.0);
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
function calculateRadiationResistance() {
|
function calculateRadiationResistance() {
|
||||||
|
@ -204,7 +295,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function inductiveReactance(frequency) {
|
function inductiveReactance(frequency) {
|
||||||
const inductance = getInductance();
|
//const inductance = getInductance();
|
||||||
const reactance = 2.0 * Math.PI * frequency * inductance;
|
const reactance = 2.0 * Math.PI * frequency * inductance;
|
||||||
return reactance;
|
return reactance;
|
||||||
}
|
}
|
||||||
|
@ -229,6 +320,7 @@
|
||||||
const w = -0.47 / (0.755 + x)**1.44;
|
const w = -0.47 / (0.755 + x)**1.44;
|
||||||
const p = k0 + 3.437/x + k2/x**2 + w;
|
const p = k0 + 3.437/x + k2/x**2 + w;
|
||||||
retval = zk * (Math.log(1 + 1/zk) + 1/p);
|
retval = zk * (Math.log(1 + 1/zk) + 1/p);
|
||||||
|
//console.log(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,18 +344,24 @@
|
||||||
const ex = 1.0; // Assume external epsilon is air (or free-space)
|
const ex = 1.0; // Assume external epsilon is air (or free-space)
|
||||||
const solenoid_length = loop_turns_slider.value * h;
|
const solenoid_length = loop_turns_slider.value * h;
|
||||||
const ff = solenoid_length / loop_diameter_slider.value;
|
const ff = solenoid_length / loop_diameter_slider.value;
|
||||||
var multiloop_capacitance = 1e-12 * (ctdw(ff, ei, ex) / Math.sqrt(1 - h**2 / loop_diameter_slider.value**2) + ciae(ff, ei, ex)) * loop_diameter_slider.value;
|
|
||||||
return multiloop_capacitance; // in Farads
|
// How much longer is the perimeter compared to the circumference if it were circular:
|
||||||
|
const shape_factor = perimeter / (Math.PI * loop_diameter_slider.value);
|
||||||
|
|
||||||
|
var l_multiloop_capacitance = 1e-12 * shape_factor * (ctdw(ff, ei, ex) / Math.sqrt(1 - h**2 / loop_diameter_slider.value**2) + ciae(ff, ei, ex)) * loop_diameter_slider.value;
|
||||||
|
return l_multiloop_capacitance; // in Farads
|
||||||
}
|
}
|
||||||
|
|
||||||
function tuningCapacitance(frequency) {
|
function tuningCapacitance(frequency) {
|
||||||
// frequency is in Hertz
|
// frequency is in Hertz
|
||||||
const reactance = inductiveReactance(frequency);
|
const reactance = inductiveReactance(frequency);
|
||||||
|
/*
|
||||||
var multiloop_capacitance = 0.0;
|
var multiloop_capacitance = 0.0;
|
||||||
if(loop_turns_slider.value > 1) {
|
if(loop_turns_slider.value > 1) {
|
||||||
// Only compensate for multiloop capacitance when we have more than 1 turn:
|
// Only compensate for multiloop capacitance when we have more than 1 turn:
|
||||||
multiloop_capacitance = multiloopCapacitance();
|
multiloop_capacitance = multiloopCapacitance();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
const capacitance = 1e12 * ((1.0 / (2.0 * Math.PI * frequency * reactance)) - multiloop_capacitance);
|
const capacitance = 1e12 * ((1.0 / (2.0 * Math.PI * frequency * reactance)) - multiloop_capacitance);
|
||||||
return capacitance; // in picofarads
|
return capacitance; // in picofarads
|
||||||
}
|
}
|
||||||
|
@ -314,11 +412,15 @@
|
||||||
const n_turns = loop_turns_slider.value;
|
const n_turns = loop_turns_slider.value;
|
||||||
const loop_spacing_ratio = loop_spacing_slider.value;
|
const loop_spacing_ratio = loop_spacing_slider.value;
|
||||||
const mu0 = 4.0 * Math.PI * 1e-7;
|
const mu0 = 4.0 * Math.PI * 1e-7;
|
||||||
|
|
||||||
|
// How much longer is the perimeter compared to the circumference if it were circular:
|
||||||
|
const shape_factor = perimeter / (Math.PI * loop_diameter_slider.value);
|
||||||
|
|
||||||
const k = (n_turns * a_coil_radius / b_conductor_radius);
|
const k = (n_turns * a_coil_radius / b_conductor_radius);
|
||||||
const Rp = getProximityResFromSpacing(loop_spacing_ratio);
|
const Rp = getProximityResFromSpacing(loop_spacing_ratio);
|
||||||
const Rs = Math.sqrt(Math.PI * frequency * mu0 / conductivity);
|
const Rs = Math.sqrt(Math.PI * frequency * mu0 / conductivity);
|
||||||
//const R0 = (n_turns * Rs) / (2.0 * Math.PI * b_conductor_radius);
|
//const R0 = (n_turns * Rs) / (2.0 * Math.PI * b_conductor_radius);
|
||||||
const R_ohmic = k * Rs * (Rp + 1.0);
|
const R_ohmic = shape_factor * k * Rs * (Rp + 1.0);
|
||||||
//const R_ohmic = k * Rs * (Rp / R0 + 1.0);
|
//const R_ohmic = k * Rs * (Rp / R0 + 1.0);
|
||||||
return R_ohmic;
|
return R_ohmic;
|
||||||
}
|
}
|
||||||
|
@ -414,6 +516,7 @@
|
||||||
metric_radio.oninput = function() {
|
metric_radio.oninput = function() {
|
||||||
units = metric_radio.value;
|
units = metric_radio.value;
|
||||||
//console.log(units);
|
//console.log(units);
|
||||||
|
setGlobals();
|
||||||
drawFrontDesign();
|
drawFrontDesign();
|
||||||
drawSideDesign();
|
drawSideDesign();
|
||||||
}
|
}
|
||||||
|
@ -427,6 +530,7 @@
|
||||||
|
|
||||||
copper_radio.oninput = function() {
|
copper_radio.oninput = function() {
|
||||||
conductivity = 58e6;
|
conductivity = 58e6;
|
||||||
|
setGlobals();
|
||||||
drawFrontDesign();
|
drawFrontDesign();
|
||||||
drawSideDesign();
|
drawSideDesign();
|
||||||
updateFrequencies();
|
updateFrequencies();
|
||||||
|
@ -444,6 +548,79 @@
|
||||||
|
|
||||||
aluminium_radio.oninput = function() {
|
aluminium_radio.oninput = function() {
|
||||||
conductivity = 35e6;
|
conductivity = 35e6;
|
||||||
|
setGlobals();
|
||||||
|
drawFrontDesign();
|
||||||
|
drawSideDesign();
|
||||||
|
updateFrequencies();
|
||||||
|
myChart.data.datasets[0].data = calculateTuningCapacitor();
|
||||||
|
myChart.data.datasets[1].data = calculateCapacitorVoltage();
|
||||||
|
myChart.data.datasets[2].data = calculateBandwidth();
|
||||||
|
myChart.data.datasets[3].data = calculateEfficiencyFactor();
|
||||||
|
myChart.data.datasets[4].data = calculateRadiationResistance();
|
||||||
|
myChart.data.datasets[5].data = calculateLossResistance();
|
||||||
|
myChart.data.datasets[6].data = calculateInductiveReactance();
|
||||||
|
myChart.data.datasets[7].data = calculateQualityFactor();
|
||||||
|
myChart.data.datasets[8].data = calculateCirculatingCurrent();
|
||||||
|
myChart.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
circle_radio.oninput = function() {
|
||||||
|
shape = "circle";
|
||||||
|
setGlobals();
|
||||||
|
drawFrontDesign();
|
||||||
|
drawSideDesign();
|
||||||
|
updateFrequencies();
|
||||||
|
myChart.data.datasets[0].data = calculateTuningCapacitor();
|
||||||
|
myChart.data.datasets[1].data = calculateCapacitorVoltage();
|
||||||
|
myChart.data.datasets[2].data = calculateBandwidth();
|
||||||
|
myChart.data.datasets[3].data = calculateEfficiencyFactor();
|
||||||
|
myChart.data.datasets[4].data = calculateRadiationResistance();
|
||||||
|
myChart.data.datasets[5].data = calculateLossResistance();
|
||||||
|
myChart.data.datasets[6].data = calculateInductiveReactance();
|
||||||
|
myChart.data.datasets[7].data = calculateQualityFactor();
|
||||||
|
myChart.data.datasets[8].data = calculateCirculatingCurrent();
|
||||||
|
myChart.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
oct_radio.oninput = function() {
|
||||||
|
shape = "octagon";
|
||||||
|
setGlobals();
|
||||||
|
drawFrontDesign();
|
||||||
|
drawSideDesign();
|
||||||
|
updateFrequencies();
|
||||||
|
myChart.data.datasets[0].data = calculateTuningCapacitor();
|
||||||
|
myChart.data.datasets[1].data = calculateCapacitorVoltage();
|
||||||
|
myChart.data.datasets[2].data = calculateBandwidth();
|
||||||
|
myChart.data.datasets[3].data = calculateEfficiencyFactor();
|
||||||
|
myChart.data.datasets[4].data = calculateRadiationResistance();
|
||||||
|
myChart.data.datasets[5].data = calculateLossResistance();
|
||||||
|
myChart.data.datasets[6].data = calculateInductiveReactance();
|
||||||
|
myChart.data.datasets[7].data = calculateQualityFactor();
|
||||||
|
myChart.data.datasets[8].data = calculateCirculatingCurrent();
|
||||||
|
myChart.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
hex_radio.oninput = function() {
|
||||||
|
shape = "hexagon";
|
||||||
|
setGlobals();
|
||||||
|
drawFrontDesign();
|
||||||
|
drawSideDesign();
|
||||||
|
updateFrequencies();
|
||||||
|
myChart.data.datasets[0].data = calculateTuningCapacitor();
|
||||||
|
myChart.data.datasets[1].data = calculateCapacitorVoltage();
|
||||||
|
myChart.data.datasets[2].data = calculateBandwidth();
|
||||||
|
myChart.data.datasets[3].data = calculateEfficiencyFactor();
|
||||||
|
myChart.data.datasets[4].data = calculateRadiationResistance();
|
||||||
|
myChart.data.datasets[5].data = calculateLossResistance();
|
||||||
|
myChart.data.datasets[6].data = calculateInductiveReactance();
|
||||||
|
myChart.data.datasets[7].data = calculateQualityFactor();
|
||||||
|
myChart.data.datasets[8].data = calculateCirculatingCurrent();
|
||||||
|
myChart.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
square_radio.oninput = function() {
|
||||||
|
shape = "square";
|
||||||
|
setGlobals();
|
||||||
drawFrontDesign();
|
drawFrontDesign();
|
||||||
drawSideDesign();
|
drawSideDesign();
|
||||||
updateFrequencies();
|
updateFrequencies();
|
||||||
|
@ -490,6 +667,7 @@
|
||||||
}, emphasis_delay);
|
}, emphasis_delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setGlobals();
|
||||||
drawFrontDesign();
|
drawFrontDesign();
|
||||||
drawSideDesign();
|
drawSideDesign();
|
||||||
updateFrequencies();
|
updateFrequencies();
|
||||||
|
@ -528,6 +706,7 @@
|
||||||
}, emphasis_delay);
|
}, emphasis_delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setGlobals();
|
||||||
drawFrontDesign();
|
drawFrontDesign();
|
||||||
drawSideDesign();
|
drawSideDesign();
|
||||||
myChart.data.datasets[0].data = calculateTuningCapacitor();
|
myChart.data.datasets[0].data = calculateTuningCapacitor();
|
||||||
|
@ -562,6 +741,7 @@
|
||||||
}, emphasis_delay);
|
}, emphasis_delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setGlobals();
|
||||||
drawFrontDesign();
|
drawFrontDesign();
|
||||||
drawSideDesign();
|
drawSideDesign();
|
||||||
updateFrequencies();
|
updateFrequencies();
|
||||||
|
@ -597,6 +777,7 @@
|
||||||
}, emphasis_delay);
|
}, emphasis_delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setGlobals();
|
||||||
drawFrontDesign();
|
drawFrontDesign();
|
||||||
drawSideDesign();
|
drawSideDesign();
|
||||||
if(loop_turns_slider.value > 1) {
|
if(loop_turns_slider.value > 1) {
|
||||||
|
@ -634,6 +815,7 @@
|
||||||
}, emphasis_delay);
|
}, emphasis_delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setGlobals();
|
||||||
drawFrontDesign();
|
drawFrontDesign();
|
||||||
myChart.data.datasets[1].data = calculateCapacitorVoltage();
|
myChart.data.datasets[1].data = calculateCapacitorVoltage();
|
||||||
myChart.data.datasets[8].data = calculateCirculatingCurrent();
|
myChart.data.datasets[8].data = calculateCirculatingCurrent();
|
||||||
|
@ -668,8 +850,6 @@
|
||||||
function drawFrontDesign() {
|
function drawFrontDesign() {
|
||||||
const win_width = document.getElementById("antenna-front-container").offsetWidth;
|
const win_width = document.getElementById("antenna-front-container").offsetWidth;
|
||||||
const win_height = document.getElementById("antenna-front-container").offsetHeight;
|
const win_height = document.getElementById("antenna-front-container").offsetHeight;
|
||||||
//const win_width = afront_canvas.getBoundingClientRect().width;
|
|
||||||
//const win_height = afront_canvas.getBoundingClientRect().height;
|
|
||||||
afront_canvas.width = win_width-2;
|
afront_canvas.width = win_width-2;
|
||||||
afront_canvas.height = win_height-2;
|
afront_canvas.height = win_height-2;
|
||||||
|
|
||||||
|
@ -678,28 +858,306 @@
|
||||||
const cond_radius = conductor_diameter_slider.value / 6;
|
const cond_radius = conductor_diameter_slider.value / 6;
|
||||||
const loopx = win_width/2;
|
const loopx = win_width/2;
|
||||||
const loopy = win_height/2;
|
const loopy = win_height/2;
|
||||||
|
|
||||||
|
if(shape == "circle") {
|
||||||
|
// Draw loop:
|
||||||
|
fctx.beginPath();
|
||||||
|
fctx.arc(loopx, loopy, loop_radius + cond_radius, -0.5 * Math.PI + 0.025, -0.5 * Math.PI - 0.025, false);
|
||||||
|
fctx.arc(loopx, loopy, loop_radius - cond_radius, -0.5 * Math.PI - 0.025, -0.5 * Math.PI + 0.025, true);
|
||||||
|
fctx.closePath();
|
||||||
|
fctx.fill();
|
||||||
|
|
||||||
|
// Draw variable capacitor:
|
||||||
|
fctx.lineWidth = 3;
|
||||||
|
fctx.beginPath();
|
||||||
|
fctx.moveTo(loopx - 3, loopy - loop_radius - 3*cond_radius);
|
||||||
|
fctx.lineTo(loopx - 3, loopy - loop_radius + 3*cond_radius);
|
||||||
|
fctx.moveTo(loopx + 3, loopy - loop_radius - 3*cond_radius);
|
||||||
|
fctx.lineTo(loopx + 3, loopy - loop_radius + 3*cond_radius);
|
||||||
|
fctx.moveTo(loopx - 12, loopy - loop_radius + 3*cond_radius);
|
||||||
|
fctx.lineTo(loopx + 12, loopy - loop_radius - 3*cond_radius);
|
||||||
|
/*
|
||||||
|
fctx.moveTo(loopx + 8, loopy - loop_radius - 3*cond_radius);
|
||||||
|
fctx.lineTo(loopx + 14, loopy - loop_radius - 3*cond_radius);
|
||||||
|
fctx.lineTo(loopx + 14, loopy - loop_radius - 3*cond_radius + 6);
|
||||||
|
*/
|
||||||
|
fctx.stroke();
|
||||||
|
|
||||||
|
// Draw coupling loop:
|
||||||
|
fctx.lineWidth = 2;
|
||||||
|
fctx.beginPath();
|
||||||
|
fctx.arc(loopx, loopy + (loop_radius - loop_radius/5) - cond_radius , loop_radius/5, 0, 2*Math.PI, true);
|
||||||
|
fctx.stroke();
|
||||||
|
|
||||||
|
// Draw conductor diameter arrow:
|
||||||
|
fctx.lineWidth = cond_dia_thickness;
|
||||||
|
fctx.beginPath();
|
||||||
|
var p1x = loopx + 0.45 * (loop_radius - cond_radius);
|
||||||
|
var p1y = loopy + 0.45 * (loop_radius - cond_radius);
|
||||||
|
var p2x = loopx + 0.707 * (loop_radius - cond_radius);
|
||||||
|
var p2y = loopy + 0.707 * (loop_radius - cond_radius);
|
||||||
|
var p3x = loopx + 0.707 * (loop_radius - cond_radius) - 3*cond_radius;
|
||||||
|
var p3y = loopy + 0.707 * (loop_radius - cond_radius);
|
||||||
|
var p4x = loopx + 0.707 * (loop_radius - cond_radius);
|
||||||
|
var p4y = loopy + 0.707 * (loop_radius - cond_radius) - 3*cond_radius;
|
||||||
|
fctx.moveTo(win_width-p1x, p1y);
|
||||||
|
fctx.lineTo(p1x, p1y);
|
||||||
|
fctx.lineTo(p2x, p2y);
|
||||||
|
fctx.lineTo(p3x, p3y);
|
||||||
|
fctx.lineTo(p4x, p4y);
|
||||||
|
fctx.lineTo(p2x, p2y);
|
||||||
|
|
||||||
// Draw loop:
|
p1x = loopx + 1.0 * (loop_radius + cond_radius);
|
||||||
fctx.beginPath();
|
p1y = loopy + 1.0 * (loop_radius + cond_radius);
|
||||||
fctx.arc(loopx, loopy, loop_radius + cond_radius, -0.5 * Math.PI + 0.025, -0.5 * Math.PI - 0.025, false);
|
p2x = loopx + 0.707 * (loop_radius + cond_radius);
|
||||||
fctx.arc(loopx, loopy, loop_radius - cond_radius, -0.5 * Math.PI - 0.025, -0.5 * Math.PI + 0.025, true);
|
p2y = loopy + 0.707 * (loop_radius + cond_radius);
|
||||||
fctx.closePath();
|
p3x = loopx + 0.707 * (loop_radius + cond_radius) + 3*cond_radius;
|
||||||
fctx.fill();
|
p3y = loopy + 0.707 * (loop_radius + cond_radius);
|
||||||
|
p4x = loopx + 0.707 * (loop_radius + cond_radius);
|
||||||
// Draw cap:
|
p4y = loopy + 0.707 * (loop_radius + cond_radius) + 3*cond_radius;
|
||||||
fctx.lineWidth = 3;
|
fctx.moveTo(p1x, p1y);
|
||||||
fctx.beginPath();
|
fctx.lineTo(p2x, p2y);
|
||||||
fctx.moveTo(loopx - 3, loopy - loop_radius - 3*cond_radius);
|
fctx.lineTo(p3x, p3y);
|
||||||
fctx.lineTo(loopx - 3, loopy - loop_radius + 3*cond_radius);
|
fctx.lineTo(p4x, p4y);
|
||||||
fctx.moveTo(loopx + 3, loopy - loop_radius - 3*cond_radius);
|
fctx.lineTo(p2x, p2y);
|
||||||
fctx.lineTo(loopx + 3, loopy - loop_radius + 3*cond_radius);
|
fctx.stroke();
|
||||||
fctx.stroke();
|
fctx.lineWidth = normal_width;
|
||||||
fctx.lineWidth = 1;
|
} else
|
||||||
|
if(shape == "octagon") {
|
||||||
// Draw coupling loop:
|
// Draw octagon:
|
||||||
fctx.beginPath();
|
//const width = loop_diameter_slider.value;
|
||||||
fctx.arc(loopx, loopy + (loop_radius - loop_radius/5) - cond_radius , loop_radius/5, 0, 2*Math.PI, true);
|
const a = 0.4142135 * loop_radius * 2.0;
|
||||||
fctx.stroke();
|
const circumradius = 1.30656296 * a;
|
||||||
|
fctx.lineWidth = 2 * cond_radius;
|
||||||
|
fctx.beginPath();
|
||||||
|
fctx.moveTo(loopx - 3, loopy - loop_radius);
|
||||||
|
for(var i=0; i<8; i++) {
|
||||||
|
fctx.lineTo(loopx - circumradius * Math.sin(Math.PI * (i/4.0 + 1.0/8)), loopy - circumradius * Math.cos(Math.PI * (i/4.0 + 1.0/8)));
|
||||||
|
}
|
||||||
|
fctx.lineTo(loopx + 3, loopy - loop_radius);
|
||||||
|
fctx.stroke();
|
||||||
|
|
||||||
|
// Draw variable capacitor:
|
||||||
|
fctx.lineWidth = 3;
|
||||||
|
fctx.beginPath();
|
||||||
|
fctx.moveTo(loopx - 3, loopy - loop_radius - 3*cond_radius);
|
||||||
|
fctx.lineTo(loopx - 3, loopy - loop_radius + 3*cond_radius);
|
||||||
|
fctx.moveTo(loopx + 3, loopy - loop_radius - 3*cond_radius);
|
||||||
|
fctx.lineTo(loopx + 3, loopy - loop_radius + 3*cond_radius);
|
||||||
|
fctx.moveTo(loopx - 12, loopy - loop_radius + 3*cond_radius);
|
||||||
|
fctx.lineTo(loopx + 12, loopy - loop_radius - 3*cond_radius);
|
||||||
|
fctx.stroke();
|
||||||
|
|
||||||
|
// Draw coupling loop:
|
||||||
|
fctx.lineWidth = 2;
|
||||||
|
fctx.beginPath();
|
||||||
|
fctx.arc(loopx, loopy + (loop_radius - loop_radius/5) - cond_radius , loop_radius/5, 0, 2*Math.PI, true);
|
||||||
|
fctx.stroke();
|
||||||
|
|
||||||
|
fctx.font = normal_font;
|
||||||
|
fctx.save();
|
||||||
|
fctx.translate(loopx - loop_radius - cond_radius - 8, loopy);
|
||||||
|
fctx.rotate(-Math.PI * 0.5);
|
||||||
|
fctx.textAlign = "center";
|
||||||
|
const s = (100.0 * loop_diameter_slider.value) * 0.414213; // side length in cm
|
||||||
|
if(units == "metric") {
|
||||||
|
fctx.fillText(s.toPrecision(3).toString() + " cm", 0, 0);
|
||||||
|
} else {
|
||||||
|
fctx.fillText((s*0.03281).toPrecision(3).toString() + "\'", 0, 0);
|
||||||
|
}
|
||||||
|
fctx.restore();
|
||||||
|
|
||||||
|
// Draw conductor diameter arrow:
|
||||||
|
fctx.lineWidth = cond_dia_thickness;
|
||||||
|
fctx.beginPath();
|
||||||
|
var p1x = loopx + 0.45 * (loop_radius - cond_radius);
|
||||||
|
var p1y = loopy + 0.45 * (loop_radius - cond_radius);
|
||||||
|
var p2x = loopx + 0.707 * (loop_radius - cond_radius);
|
||||||
|
var p2y = loopy + 0.707 * (loop_radius - cond_radius);
|
||||||
|
var p3x = loopx + 0.707 * (loop_radius - cond_radius) - 3*cond_radius;
|
||||||
|
var p3y = loopy + 0.707 * (loop_radius - cond_radius);
|
||||||
|
var p4x = loopx + 0.707 * (loop_radius - cond_radius);
|
||||||
|
var p4y = loopy + 0.707 * (loop_radius - cond_radius) - 3*cond_radius;
|
||||||
|
fctx.moveTo(win_width-p1x, p1y);
|
||||||
|
fctx.lineTo(p1x, p1y);
|
||||||
|
fctx.lineTo(p2x, p2y);
|
||||||
|
fctx.lineTo(p3x, p3y);
|
||||||
|
fctx.lineTo(p4x, p4y);
|
||||||
|
fctx.lineTo(p2x, p2y);
|
||||||
|
|
||||||
|
p1x = loopx + 1.0 * (loop_radius + cond_radius);
|
||||||
|
p1y = loopy + 1.0 * (loop_radius + cond_radius);
|
||||||
|
p2x = loopx + 0.707 * (loop_radius + cond_radius);
|
||||||
|
p2y = loopy + 0.707 * (loop_radius + cond_radius);
|
||||||
|
p3x = loopx + 0.707 * (loop_radius + cond_radius) + 3*cond_radius;
|
||||||
|
p3y = loopy + 0.707 * (loop_radius + cond_radius);
|
||||||
|
p4x = loopx + 0.707 * (loop_radius + cond_radius);
|
||||||
|
p4y = loopy + 0.707 * (loop_radius + cond_radius) + 3*cond_radius;
|
||||||
|
fctx.moveTo(p1x, p1y);
|
||||||
|
fctx.lineTo(p2x, p2y);
|
||||||
|
fctx.lineTo(p3x, p3y);
|
||||||
|
fctx.lineTo(p4x, p4y);
|
||||||
|
fctx.lineTo(p2x, p2y);
|
||||||
|
fctx.stroke();
|
||||||
|
fctx.lineWidth = normal_width;
|
||||||
|
} else
|
||||||
|
if(shape == "hexagon") {
|
||||||
|
// Draw hexagon:
|
||||||
|
const radius = 2.0 * loop_radius * 0.57735;
|
||||||
|
fctx.lineWidth = 2 * cond_radius;
|
||||||
|
fctx.beginPath();
|
||||||
|
fctx.moveTo(loopx - 3, loopy - radius);
|
||||||
|
for(var i=1; i<6; i++) {
|
||||||
|
fctx.lineTo(loopx - radius * Math.sin(Math.PI * (i/3.0)), loopy - radius * Math.cos(Math.PI * (i/3.0)));
|
||||||
|
}
|
||||||
|
fctx.lineTo(loopx + 3, loopy - radius);
|
||||||
|
fctx.stroke();
|
||||||
|
|
||||||
|
// Draw variable capacitor:
|
||||||
|
fctx.lineWidth = 3;
|
||||||
|
fctx.beginPath();
|
||||||
|
fctx.moveTo(loopx - 3, loopy - radius - 3*cond_radius);
|
||||||
|
fctx.lineTo(loopx - 3, loopy - radius + 3*cond_radius);
|
||||||
|
fctx.moveTo(loopx + 3, loopy - radius - 3*cond_radius);
|
||||||
|
fctx.lineTo(loopx + 3, loopy - radius + 3*cond_radius);
|
||||||
|
fctx.moveTo(loopx - 12, loopy - radius + 3*cond_radius);
|
||||||
|
fctx.lineTo(loopx + 12, loopy - radius - 3*cond_radius);
|
||||||
|
fctx.stroke();
|
||||||
|
|
||||||
|
// Draw coupling loop:
|
||||||
|
fctx.lineWidth = 2;
|
||||||
|
fctx.beginPath();
|
||||||
|
fctx.arc(loopx, loopy + (radius - radius/4) - cond_radius , radius/5, 0, 2*Math.PI, true);
|
||||||
|
fctx.stroke();
|
||||||
|
|
||||||
|
fctx.font = normal_font;
|
||||||
|
fctx.save();
|
||||||
|
fctx.translate(loopx - loop_radius - cond_radius - 8, loopy);
|
||||||
|
fctx.rotate(-Math.PI * 0.5);
|
||||||
|
fctx.textAlign = "center";
|
||||||
|
const s = (100.0 * loop_diameter_slider.value) * 0.57735; // side length in cm
|
||||||
|
if(units == "metric") {
|
||||||
|
fctx.fillText(s.toPrecision(3).toString() + " cm", 0, 0);
|
||||||
|
} else {
|
||||||
|
fctx.fillText((s*0.03281).toPrecision(3).toString() + "\'", 0, 0);
|
||||||
|
}
|
||||||
|
fctx.restore();
|
||||||
|
|
||||||
|
// Draw conductor diameter arrow:
|
||||||
|
fctx.lineWidth = cond_dia_thickness;
|
||||||
|
fctx.beginPath();
|
||||||
|
var p0x = loopx + 0.45 * loop_radius;
|
||||||
|
var p0y = loopy + 0.45 * loop_radius;
|
||||||
|
var p1x = loopx + loop_radius - cond_radius - 4*cond_radius;
|
||||||
|
var p1y = loopy + 0.45 * loop_radius;
|
||||||
|
var p2x = loopx + loop_radius - cond_radius;
|
||||||
|
var p2y = loopy + 0.45 * loop_radius;
|
||||||
|
var p3x = loopx + loop_radius - cond_radius - 2*cond_radius;
|
||||||
|
var p3y = loopy + 0.45 * loop_radius - 2*cond_radius;
|
||||||
|
var p4x = loopx + loop_radius - cond_radius - 2*cond_radius;
|
||||||
|
var p4y = loopy + 0.45 * loop_radius + 2*cond_radius;
|
||||||
|
fctx.moveTo(win_width-p0x, p0y);
|
||||||
|
fctx.lineTo(p0x, p0y);
|
||||||
|
//fctx.lineTo(p1x, p1y);
|
||||||
|
fctx.lineTo(p2x, p2y);
|
||||||
|
fctx.lineTo(p3x, p3y);
|
||||||
|
fctx.lineTo(p4x, p4y);
|
||||||
|
fctx.lineTo(p2x, p2y);
|
||||||
|
|
||||||
|
p1x = loopx + loop_radius + cond_radius + 4*cond_radius;
|
||||||
|
//p1y = loopy + 1.0 * (loop_radius + cond_radius);
|
||||||
|
p2x = loopx + loop_radius + cond_radius;
|
||||||
|
//p2y = loopy + 0.707 * (loop_radius + cond_radius);
|
||||||
|
p3x = loopx + loop_radius + cond_radius + 2*cond_radius;
|
||||||
|
//p3y = loopy + 0.707 * (loop_radius + cond_radius);
|
||||||
|
p4x = loopx + loop_radius + cond_radius + 2*cond_radius;
|
||||||
|
//p4y = loopy + 0.707 * (loop_radius + cond_radius) + 3*cond_radius;
|
||||||
|
fctx.moveTo(p1x, p1y);
|
||||||
|
fctx.lineTo(p2x, p2y);
|
||||||
|
fctx.lineTo(p3x, p3y);
|
||||||
|
fctx.lineTo(p4x, p4y);
|
||||||
|
fctx.lineTo(p2x, p2y);
|
||||||
|
fctx.stroke();
|
||||||
|
fctx.lineWidth = normal_width;
|
||||||
|
} else {
|
||||||
|
// Draw square:
|
||||||
|
const radius = 1.414 * loop_radius;
|
||||||
|
fctx.lineWidth = 2 * cond_radius;
|
||||||
|
fctx.beginPath();
|
||||||
|
fctx.moveTo(loopx - 3, loopy - loop_radius);
|
||||||
|
for(var i=0; i<4; i++) {
|
||||||
|
fctx.lineTo(loopx - radius * Math.sin(Math.PI * (i/2.0 + 0.25)), loopy - radius * Math.cos(Math.PI * (i/2.0 + 0.25)));
|
||||||
|
}
|
||||||
|
fctx.lineTo(loopx + 3, loopy - loop_radius);
|
||||||
|
fctx.stroke();
|
||||||
|
|
||||||
|
// Draw variable capacitor:
|
||||||
|
fctx.lineWidth = 3;
|
||||||
|
fctx.beginPath();
|
||||||
|
fctx.moveTo(loopx - 3, loopy - loop_radius - 3*cond_radius);
|
||||||
|
fctx.lineTo(loopx - 3, loopy - loop_radius + 3*cond_radius);
|
||||||
|
fctx.moveTo(loopx + 3, loopy - loop_radius - 3*cond_radius);
|
||||||
|
fctx.lineTo(loopx + 3, loopy - loop_radius + 3*cond_radius);
|
||||||
|
fctx.moveTo(loopx - 12, loopy - loop_radius + 3*cond_radius);
|
||||||
|
fctx.lineTo(loopx + 12, loopy - loop_radius - 3*cond_radius);
|
||||||
|
fctx.stroke();
|
||||||
|
|
||||||
|
// Draw coupling loop:
|
||||||
|
fctx.lineWidth = 2;
|
||||||
|
fctx.beginPath();
|
||||||
|
fctx.arc(loopx, loopy + (loop_radius - loop_radius/5) - cond_radius , loop_radius/5, 0, 2*Math.PI, true);
|
||||||
|
fctx.stroke();
|
||||||
|
|
||||||
|
fctx.font = normal_font;
|
||||||
|
fctx.save();
|
||||||
|
fctx.translate(loopx - loop_radius - cond_radius - 8, loopy);
|
||||||
|
fctx.rotate(-Math.PI * 0.5);
|
||||||
|
fctx.textAlign = "center";
|
||||||
|
const s = (100.0 * loop_diameter_slider.value); // side length in cm
|
||||||
|
if(units == "metric") {
|
||||||
|
fctx.fillText(s.toPrecision(3).toString() + " cm", 0, 0);
|
||||||
|
} else {
|
||||||
|
fctx.fillText((s*0.03281).toPrecision(3).toString() + "\'", 0, 0);
|
||||||
|
}
|
||||||
|
fctx.restore();
|
||||||
|
|
||||||
|
// Draw conductor diameter arrow:
|
||||||
|
fctx.lineWidth = cond_dia_thickness;
|
||||||
|
fctx.beginPath();
|
||||||
|
var p0x = loopx + 0.45 * (loop_radius - cond_radius);
|
||||||
|
var p0y = loopy + 0.45 * (loop_radius - cond_radius);
|
||||||
|
var p1x = loopx + loop_radius - cond_radius - 4*cond_radius;
|
||||||
|
var p1y = loopy + 0.7 * loop_radius;
|
||||||
|
var p2x = loopx + loop_radius - cond_radius;
|
||||||
|
var p2y = loopy + 0.7 * loop_radius;
|
||||||
|
var p3x = loopx + loop_radius - cond_radius - 2*cond_radius;
|
||||||
|
var p3y = loopy + 0.7 * loop_radius - 2*cond_radius;
|
||||||
|
var p4x = loopx + loop_radius - cond_radius - 2*cond_radius;
|
||||||
|
var p4y = loopy + 0.7 * loop_radius + 2*cond_radius;
|
||||||
|
fctx.moveTo(win_width-p0x, p0y);
|
||||||
|
fctx.lineTo(p0x, p0y);
|
||||||
|
fctx.lineTo(p1x, p1y);
|
||||||
|
fctx.lineTo(p2x, p2y);
|
||||||
|
fctx.lineTo(p3x, p3y);
|
||||||
|
fctx.lineTo(p4x, p4y);
|
||||||
|
fctx.lineTo(p2x, p2y);
|
||||||
|
|
||||||
|
p1x = loopx + loop_radius + cond_radius + 4*cond_radius;
|
||||||
|
//p1y = loopy + 1.0 * (loop_radius + cond_radius);
|
||||||
|
p2x = loopx + loop_radius + cond_radius;
|
||||||
|
//p2y = loopy + 0.707 * (loop_radius + cond_radius);
|
||||||
|
p3x = loopx + loop_radius + cond_radius + 2*cond_radius;
|
||||||
|
//p3y = loopy + 0.707 * (loop_radius + cond_radius);
|
||||||
|
p4x = loopx + loop_radius + cond_radius + 2*cond_radius;
|
||||||
|
//p4y = loopy + 0.707 * (loop_radius + cond_radius) + 3*cond_radius;
|
||||||
|
fctx.moveTo(p1x, p1y);
|
||||||
|
fctx.lineTo(p2x, p2y);
|
||||||
|
fctx.lineTo(p3x, p3y);
|
||||||
|
fctx.lineTo(p4x, p4y);
|
||||||
|
fctx.lineTo(p2x, p2y);
|
||||||
|
fctx.stroke();
|
||||||
|
fctx.lineWidth = normal_width;
|
||||||
|
}
|
||||||
|
|
||||||
// Draw loop diameter arrow:
|
// Draw loop diameter arrow:
|
||||||
fctx.lineWidth = loop_dia_thickness;
|
fctx.lineWidth = loop_dia_thickness;
|
||||||
|
@ -717,7 +1175,8 @@
|
||||||
|
|
||||||
// Write loop inductance:
|
// Write loop inductance:
|
||||||
fctx.font = normal_font;
|
fctx.font = normal_font;
|
||||||
const L = getInductance() * 1.0e+6;
|
const L = inductance * 1.0e+6;
|
||||||
|
//const L = getInductance() * 1.0e+6;
|
||||||
fctx.fillText("L = " + L.toPrecision(3).toString() + " \u03bcH", 8, 18);
|
fctx.fillText("L = " + L.toPrecision(3).toString() + " \u03bcH", 8, 18);
|
||||||
|
|
||||||
// Write Tx power text:
|
// Write Tx power text:
|
||||||
|
@ -737,6 +1196,7 @@
|
||||||
fctx.font = normal_font;
|
fctx.font = normal_font;
|
||||||
|
|
||||||
// Draw conductor diameter arrow:
|
// Draw conductor diameter arrow:
|
||||||
|
/*
|
||||||
fctx.lineWidth = cond_dia_thickness;
|
fctx.lineWidth = cond_dia_thickness;
|
||||||
fctx.beginPath();
|
fctx.beginPath();
|
||||||
var p1x = loopx + 0.4 * (loop_radius - cond_radius);
|
var p1x = loopx + 0.4 * (loop_radius - cond_radius);
|
||||||
|
@ -769,9 +1229,9 @@
|
||||||
fctx.lineTo(p2x, p2y);
|
fctx.lineTo(p2x, p2y);
|
||||||
fctx.stroke();
|
fctx.stroke();
|
||||||
fctx.lineWidth = normal_width;
|
fctx.lineWidth = normal_width;
|
||||||
|
*/
|
||||||
p1x = loopx + 0.4 * (loop_radius - cond_radius);
|
p1x = loopx + 0.45 * (loop_radius - cond_radius);
|
||||||
p1y = loopy + 0.4 * (loop_radius - cond_radius) - 5;
|
p1y = loopy + 0.45 * (loop_radius - cond_radius) - 5;
|
||||||
//fctx.textAlign = "right";
|
//fctx.textAlign = "right";
|
||||||
const cond_dia = 1.0 * conductor_diameter_slider.value;
|
const cond_dia = 1.0 * conductor_diameter_slider.value;
|
||||||
fctx.textAlign = "center";
|
fctx.textAlign = "center";
|
||||||
|
@ -781,20 +1241,20 @@
|
||||||
fctx.font = normal_font;
|
fctx.font = normal_font;
|
||||||
// Write loop area:
|
// Write loop area:
|
||||||
fctx.textAlign = "right";
|
fctx.textAlign = "right";
|
||||||
fctx.fillText("A = " + (Math.PI * (0.5*dia)**2).toPrecision(3).toString() + " m\u00B2", win_width-8, 18);
|
fctx.fillText("A = " + area.toPrecision(3).toString() + " m\u00B2", win_width-8, 18);
|
||||||
|
|
||||||
// Write Tx power text:
|
// Write Tx power text:
|
||||||
fctx.fillText("circ = " + (Math.PI * dia).toPrecision(3).toString() + " m", win_width-8, win_height * 0.8 + 20);
|
fctx.fillText("peri = " + perimeter.toPrecision(3).toString() + " m", win_width-8, win_height * 0.8 + 20);
|
||||||
} else {
|
} else {
|
||||||
fctx.font = cond_dia_font;
|
fctx.font = cond_dia_font;
|
||||||
fctx.fillText("\u2300a = " + (cond_dia/25.4).toPrecision(3).toString() + "\"", loopx, p1y+1);
|
fctx.fillText("\u2300a = " + (cond_dia/25.4).toPrecision(3).toString() + "\"", loopx, p1y+1);
|
||||||
fctx.font = normal_font;
|
fctx.font = normal_font;
|
||||||
// Write loop area:
|
// Write loop area:
|
||||||
fctx.textAlign = "right";
|
fctx.textAlign = "right";
|
||||||
fctx.fillText("A = " + (Math.PI * (0.5*dia*3.28084)**2).toPrecision(3).toString() + " ft\u00B2", win_width-8, 18);
|
fctx.fillText("A = " + (area * 10.76391).toPrecision(3).toString() + " ft\u00B2", win_width-8, 18);
|
||||||
|
|
||||||
// Write Tx power text:
|
// Write Tx power text:
|
||||||
fctx.fillText("circ = " + (Math.PI * dia*3.28084).toPrecision(3).toString() + " ft", win_width-8, win_height * 0.8 + 20);
|
fctx.fillText("peri = " + (perimeter*3.28084).toPrecision(3).toString() + " ft", win_width-8, win_height * 0.8 + 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -805,17 +1265,10 @@
|
||||||
function drawSideDesign() {
|
function drawSideDesign() {
|
||||||
const win_width = document.getElementById("antenna-side-container").offsetWidth;
|
const win_width = document.getElementById("antenna-side-container").offsetWidth;
|
||||||
const win_height = document.getElementById("antenna-side-container").offsetHeight;
|
const win_height = document.getElementById("antenna-side-container").offsetHeight;
|
||||||
//const win_width = aside_canvas.getBoundingClientRect().width;
|
|
||||||
//const win_height = aside_canvas.getBoundingClientRect().height;
|
|
||||||
//console.log(win_width, win_height);
|
|
||||||
aside_canvas.width = win_width-2;
|
aside_canvas.width = win_width-2;
|
||||||
aside_canvas.height = win_height-2;
|
aside_canvas.height = win_height-2;
|
||||||
//const win_width = aside_canvas.width;
|
|
||||||
//const win_height = aside_canvas.height;
|
|
||||||
sctx.clearRect(0, 0, win_width, win_height);
|
sctx.clearRect(0, 0, win_width, win_height);
|
||||||
|
|
||||||
//const loop_radius = win_width < win_height ? 0.40 * win_width : 0.40 * win_height;
|
|
||||||
|
|
||||||
const cond_radius = conductor_diameter_slider.value / 6;
|
const cond_radius = conductor_diameter_slider.value / 6;
|
||||||
const cond_spacing = 2 * cond_radius * loop_spacing_slider.value;
|
const cond_spacing = 2 * cond_radius * loop_spacing_slider.value;
|
||||||
const start_x = win_width/2 - loop_turns_slider.value * cond_spacing * 0.5;
|
const start_x = win_width/2 - loop_turns_slider.value * cond_spacing * 0.5;
|
||||||
|
@ -877,11 +1330,11 @@
|
||||||
|
|
||||||
sctx.textAlign = "right";
|
sctx.textAlign = "right";
|
||||||
sctx.fillText("cond = " , win_width-8, dim_y + 08);
|
sctx.fillText("cond = " , win_width-8, dim_y + 08);
|
||||||
const cond_length = ((((Math.PI * loop_diameter_slider.value * loop_turns_slider.value) ** 2.0) + ((loop_spacing_slider.value * conductor_diameter_slider.value * 1e-3 * loop_turns_slider.value) ** 2.0)) ** 0.5);
|
// const cond_length = ((((Math.PI * loop_diameter_slider.value * loop_turns_slider.value) ** 2.0) + ((loop_spacing_slider.value * conductor_diameter_slider.value * 1e-3 * loop_turns_slider.value) ** 2.0)) ** 0.5);
|
||||||
if(units == "metric") {
|
if(units == "metric") {
|
||||||
sctx.fillText(cond_length.toPrecision(4).toString() + " m", win_width-8, dim_y + 20);
|
sctx.fillText(conductor_length.toPrecision(4).toString() + " m", win_width-8, dim_y + 20);
|
||||||
} else {
|
} else {
|
||||||
sctx.fillText((cond_length * 3.28084).toPrecision(4).toString() + " ft", win_width-8, dim_y + 20);
|
sctx.fillText((conductor_length * 3.28084).toPrecision(4).toString() + " ft", win_width-8, dim_y + 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw spacing text:
|
// Draw spacing text:
|
||||||
|
@ -893,6 +1346,11 @@
|
||||||
sctx.fillText("c = " + (spc/25.4).toPrecision(3).toString() + " in", start_x + cond_spacing, dim_y + 20);
|
sctx.fillText("c = " + (spc/25.4).toPrecision(3).toString() + " in", start_x + cond_spacing, dim_y + 20);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update the frequencies, now that we have the sliders available:
|
||||||
|
updateFrequencies();
|
||||||
|
setGlobals();
|
||||||
|
|
||||||
drawFrontDesign();
|
drawFrontDesign();
|
||||||
drawSideDesign();
|
drawSideDesign();
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue