/* Copyright (C) Paul Falstad and Iain Sharp This file is part of CircuitJS1. CircuitJS1 is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. CircuitJS1 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with CircuitJS1. If not, see <http://www.gnu.org/licenses/>. */ package com.lushprojects.circuitjs1.client; //import java.awt.*; //import java.util.StringTokenizer; class SweepElm extends CircuitElm { double maxV, maxF, minF, sweepTime, frequency; final int FLAG_LOG = 1; final int FLAG_BIDIR = 2; public SweepElm(int xx, int yy) { super(xx, yy); minF = 20; maxF = 4000; maxV = 5; sweepTime = .1; flags = FLAG_BIDIR; reset(); } public SweepElm(int xa, int ya, int xb, int yb, int f, StringTokenizer st) { super(xa, ya, xb, yb, f); minF = new Double(st.nextToken()).doubleValue(); maxF = new Double(st.nextToken()).doubleValue(); maxV = new Double(st.nextToken()).doubleValue(); sweepTime = new Double(st.nextToken()).doubleValue(); reset(); } int getDumpType() { return 170; } int getPostCount() { return 1; } final int circleSize = 17; String dump() { return super.dump() + " " + minF + " " + maxF + " " + maxV + " " + sweepTime; } void setPoints() { super.setPoints(); lead1 = interpPoint(point1, point2, 1-circleSize/dn); } void draw(Graphics g) { setBbox(point1, point2, circleSize); setVoltageColor(g, volts[0]); drawThickLine(g, point1, lead1); g.setColor(needsHighlight() ? selectColor : Color.gray); setPowerColor(g, false); int xc = point2.x; int yc = point2.y; drawThickCircle(g, xc, yc, circleSize); int wl = 8; adjustBbox(xc-circleSize, yc-circleSize, xc+circleSize, yc+circleSize); int i; int xl = 10; long tm = System.currentTimeMillis(); //double w = (this == mouseElm ? 3 : 2); tm %= 2000; if (tm > 1000) tm = 2000-tm; double w = 1+tm*.002; if (sim.simIsRunning()) w = 1+2*(frequency-minF)/(maxF-minF); g.context.beginPath(); g.context.setLineWidth(3.0); for (i = -xl; i <= xl; i++) { int yy = yc+(int) (.95*Math.sin(i*pi*w/xl)*wl); if (i == -xl) g.context.moveTo(xc+i, yy); else g.context.lineTo(xc+i, yy); } g.context.stroke(); g.context.setLineWidth(1.0); if (sim.showValuesCheckItem.getState()) { String s = getShortUnitText(frequency, "Hz"); if (dx == 0 || dy == 0) drawValues(g, s, circleSize); } drawPosts(g); curcount = updateDotCount(-current, curcount); if (sim.dragElm != this) drawDots(g, point1, lead1, curcount); } void stamp() { sim.stampVoltageSource(0, nodes[0], voltSource); } double fadd, fmul, freqTime, savedTimeStep; int dir = 1; void setParams() { if (frequency < minF || frequency > maxF) { frequency = minF; freqTime = 0; dir = 1; } if ((flags & FLAG_LOG) == 0) { fadd = dir*sim.timeStep*(maxF-minF)/sweepTime; fmul = 1; } else { fadd = 0; fmul = Math.pow(maxF/minF, dir*sim.timeStep/sweepTime); } savedTimeStep = sim.timeStep; } void reset() { frequency = minF; freqTime = 0; dir = 1; setParams(); } double v; void startIteration() { // has timestep been changed? if (sim.timeStep != savedTimeStep) setParams(); v = Math.sin(freqTime)*maxV; freqTime += frequency*2*pi*sim.timeStep; frequency = frequency*fmul+fadd; if (frequency >= maxF && dir == 1) { if ((flags & FLAG_BIDIR) != 0) { fadd = -fadd; fmul = 1/fmul; dir = -1; } else frequency = minF; } if (frequency <= minF && dir == -1) { fadd = -fadd; fmul = 1/fmul; dir = 1; } } void doStep() { sim.updateVoltageSource(0, nodes[0], voltSource, v); } double getVoltageDiff() { return volts[0]; } int getVoltageSourceCount() { return 1; } boolean hasGroundConnection(int n1) { return true; } void getInfo(String arr[]) { arr[0] = "sweep " + (((flags & FLAG_LOG) == 0) ? "(linear)" : "(log)"); arr[1] = "I = " + getCurrentDText(getCurrent()); arr[2] = "V = " + getVoltageText(volts[0]); arr[3] = "f = " + getUnitText(frequency, "Hz"); arr[4] = "range = " + getUnitText(minF, "Hz") + " .. " + getUnitText(maxF, "Hz"); arr[5] = "time = " + getUnitText(sweepTime, "s"); } public EditInfo getEditInfo(int n) { if (n == 0) return new EditInfo("Min Frequency (Hz)", minF, 0, 0); if (n == 1) return new EditInfo("Max Frequency (Hz)", maxF, 0, 0); if (n == 2) return new EditInfo("Sweep Time (s)", sweepTime, 0, 0); if (n == 3) { EditInfo ei = new EditInfo("", 0, -1, -1); ei.checkbox = new Checkbox("Logarithmic", (flags & FLAG_LOG) != 0); return ei; } if (n == 4) return new EditInfo("Max Voltage", maxV, 0, 0); if (n == 5) { EditInfo ei = new EditInfo("", 0, -1, -1); ei.checkbox = new Checkbox("Bidirectional", (flags & FLAG_BIDIR) != 0); return ei; } return null; } public void setEditValue(int n, EditInfo ei) { double maxfreq = 1/(8*sim.timeStep); if (n == 0) { minF = ei.value; if (minF > maxfreq) minF = maxfreq; } if (n == 1) { maxF = ei.value; if (maxF > maxfreq) maxF = maxfreq; } if (n == 2) sweepTime = ei.value; if (n == 3) { flags &= ~FLAG_LOG; if (ei.checkbox.getState()) flags |= FLAG_LOG; } if (n == 4) maxV = ei.value; if (n == 5) { flags &= ~FLAG_BIDIR; if (ei.checkbox.getState()) flags |= FLAG_BIDIR; } setParams(); } }