CircuitJS1 First Version

This commit is contained in:
Iain Sharp
2015-06-15 03:13:30 +01:00
parent 005634f9f9
commit 67ab27fa6a
415 changed files with 27555 additions and 0 deletions

11
.classpath Normal file
View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="com.google.gwt.eclipse.core.GWT_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5">
<attributes>
<attribute name="owner.project.facets" value="java"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="war/WEB-INF/classes"/>
</classpath>

6
.gitignore vendored
View File

@@ -1,3 +1,9 @@
#GWT cache
gwt-unitCache/
war/circuitjs1/
war/circuitjs1/circuits/
war/WEB-INF/
# Windows image file caches
Thumbs.db
ehthumbs.db

34
.project Normal file
View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>circuitjs1</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.wst.common.project.facet.core.builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.google.gdt.eclipse.core.webAppProjectValidator</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.google.gwt.eclipse.core.gwtProjectValidator</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>com.google.gwt.eclipse.core.gwtNature</nature>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
</natures>
</projectDescription>

View File

@@ -0,0 +1,2 @@
eclipse.preferences.version=1
filesCopiedToWebInfLib=

View File

@@ -0,0 +1,5 @@
eclipse.preferences.version=1
jarsExcludedFromWebInfLib=
launchConfigExternalUrlPrefix=
warSrcDir=war
warSrcDirIsOutput=true

View File

@@ -0,0 +1,3 @@
eclipse.preferences.version=1
filesCopiedToWebInfLib=gwt-servlet.jar
gwtCompileSettings=PGd3dC1jb21waWxlLXNldHRpbmdzPjxsb2ctbGV2ZWw+SU5GTzwvbG9nLWxldmVsPjxvdXRwdXQtc3R5bGU+T0JGVVNDQVRFRDwvb3V0cHV0LXN0eWxlPjxleHRyYS1hcmdzPjwhW0NEQVRBW11dPjwvZXh0cmEtYXJncz48dm0tYXJncz48IVtDREFUQVstWG14NTEybV1dPjwvdm0tYXJncz48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5sdXNocHJvamVjdHMuY2lyY3VpdGpzMS5jaXJjdWl0anMxPC9lbnRyeS1wb2ludC1tb2R1bGU+PC9nd3QtY29tcGlsZS1zZXR0aW5ncz4\=

View File

@@ -0,0 +1,11 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.5

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<installed facet="java" version="1.5"/>
</faceted-project>

339
COPYING.txt Normal file
View File

@@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program 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.
This program 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 this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

77
README.md Normal file
View File

@@ -0,0 +1,77 @@
#CircuitJS1
##Introduction
CircuitJS1 is an electronic circuit simulator that runs in the browser. It was originally written by Paul Falstad as a Java Applet. It was adapted by Iain Sharp to run in the browser using GWT.
For a hosted version of the application see:
* Paul's Page: [http://www.falstad.com/circuit/](http://www.falstad.com/circuit/)
* Iain's Page: [http://lushprojects.com/circuitjs/](http://lushprojects.com/circuitjs/)
Thanks to Edward Calver for 15 new components and other improvements. Thanks to Rodrigo Hausen for file import/export and many other UI improvements. Thanks to J. Mike Rollins for the Zener diode code. Thanks to Julius Schmidt for the spark gap code and some examples. Thanks to Dustin Soodak for help with the user interface improvements. Thanks to Jacob Calvert for the T Flip Flop.
##Building the application
The tools you will need to build the project are:
* Eclipse - I am using the Kepler version.
* Google plugin for Eclipse to provide GWT.
This archive is a project folder for your Eclipse project space. Once you have a local copy you can then build and run in development mode or build for deployment. Running in development mode is done using the normal Eclipse run button or "Run As..." and choosing "Web Application (Super Dev Mode)" and then picking "Circuitjs1.html" as the initial page. Building for deployment is done using the Google button on the Eclipse taskbar and choosing "GWT Compile Project...".
GWT will build it's output in to the "war" directory. In the "war" directory the file "iframe.html" is loaded as an iFrame in to the spare space at the bottom of the right hand pannel. It can be used for branding etc.
##Deployment
* "GWT Compile Project..." as explained above. This will put the outputs in to the "war" directory in the Eclipse project folder. You then need to copy everything in the "war" directory, except the "WEB-INF" directory, on to your web server.
* Customize the header of the file "circuitjs1.html" to include your tracking, favicon etc.
* Customize the "iframe.html" file to include any branding you want in the right hand panel of the application
The link for the full-page version of the application is now:
`http://<your host>/<your path>/circuitjs1.html`
(you can rename the "circuitjs1.html" file if you want too).
Just for reference the files should look like this
```
-+ Directory containing the front page (eg "circuitjs")
+- circuitjs.html - full page version of application
+- iframe.html - see notes above
++ circuitjs1 (directory)
+- various files built by GWT
+- circuits (directory, containing example circuits)
+- setuplist.txt (index in to example circuit directory)
```
## Embedding
You can link to the full page version of the application using the link shown above.
If you want to embed the application in another page then use an iframe with the src being the full-page version.
You can add query parameters to link to the full page version to change it's startup behaviour. The following are supported:
```
.../circuitjs1.html?cct=<string> // Load the circuit from the URL (like the # in the Java version)
.../circuitjs1.html?startCircuit=<filename> // Loads the circuit named "filename" from the "Circuits" directory
.../circuitjs1.html?euroResistors=<true|false>
.../circuitjs1.html?whiteBackground=<true|false>
.../circuitjs1.html?conventionalCurrent=<true|false>
```
## License
This program 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.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<module rename-to="circuitjs1">
<inherits name="com.google.gwt.user.User" />
<inherits name="com.google.gwt.http.HTTP" />
<inherits name='com.google.gwt.user.theme.clean.Clean'/>
<entry-point class="com.lushprojects.circuitjs1.client.circuitjs1" />
</module>

View File

@@ -0,0 +1,26 @@
/*
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;
class ACRailElm extends RailElm {
public ACRailElm(int xx, int yy) { super(xx, yy, WF_AC); }
Class getDumpClass() { return RailElm.class; }
int getShortcut() { return 0; }
}

View File

@@ -0,0 +1,25 @@
/*
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;
class ACVoltageElm extends VoltageElm {
public ACVoltageElm(int xx, int yy) { super(xx, yy, WF_AC); }
Class getDumpClass() { return VoltageElm.class; }
}

View File

@@ -0,0 +1,60 @@
/*
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 ADCElm extends ChipElm {
public ADCElm(int xx, int yy) { super(xx, yy); }
public ADCElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f, st);
}
String getChipName() { return "ADC"; }
boolean needsBits() { return true; }
void setupPins() {
sizeX = 2;
sizeY = bits > 2 ? bits : 2;
pins = new Pin[getPostCount()];
int i;
for (i = 0; i != bits; i++) {
pins[i] = new Pin(bits-1-i, SIDE_E, "D" + i);
pins[i].output = true;
}
pins[bits] = new Pin(0, SIDE_W, "In");
pins[bits+1] = new Pin(sizeY-1, SIDE_W, "V+");
allocNodes();
}
void execute() {
int imax = (1<<bits)-1;
// if we round, the half-flash doesn't work
double val = imax*volts[bits]/volts[bits+1]; // + .5;
int ival = (int) val;
ival = min(imax, max(0, ival));
int i;
for (i = 0; i != bits; i++)
pins[i].value = ((ival & (1<<i)) != 0);
}
int getVoltageSourceCount() { return bits; }
int getPostCount() { return bits+2; }
int getDumpType() { return 167; }
}

View File

@@ -0,0 +1,146 @@
/*
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;
// contributed by Edward Calver
class AMElm extends CircuitElm {
static final int FLAG_COS = 2;
double carrierfreq,signalfreq, maxVoltage, freqTimeZero;
public AMElm(int xx, int yy) {
super(xx, yy);
maxVoltage = 5;
carrierfreq = 1000;
signalfreq=40;
reset();
}
public AMElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f);
carrierfreq = new Double(st.nextToken()).doubleValue();
signalfreq= new Double(st.nextToken()).doubleValue();
maxVoltage = new Double(st.nextToken()).doubleValue();
if ((flags & FLAG_COS) != 0) {
flags &= ~FLAG_COS;
}
reset();
}
int getDumpType() { return 200; }
String dump() {
return super.dump() + " " +carrierfreq+" " + signalfreq + " " +maxVoltage;
}
/*void setCurrent(double c) {
current = c;
System.out.print("v current set to " + c + "\n");
}*/
void reset() {
freqTimeZero = 0;
curcount = 0;
}
int getPostCount() { return 1; }
void stamp() {
sim.stampVoltageSource(0, nodes[0], voltSource);
}
void doStep() {
sim.updateVoltageSource(0, nodes[0], voltSource, getVoltage());
}
double getVoltage() {
double w = 2*pi*(sim.t-freqTimeZero);
return ((Math.sin(w*signalfreq)+1)/2)*Math.sin(w*carrierfreq)*maxVoltage;
}
final int circleSize = 17;
void draw(Graphics g) {
setBbox(point1, point2, circleSize);
setVoltageColor(g, volts[0]);
drawThickLine(g, point1, lead1);
Font f = new Font("SansSerif", 0, 12);
g.setFont(f);
g.setColor(needsHighlight() ? selectColor : whiteColor);
setPowerColor(g, false);
double v = getVoltage();
String s = "AM";
drawCenteredText(g, s, x2, y2, true);
drawWaveform(g, point2);
drawPosts(g);
curcount = updateDotCount(-current, curcount);
if (sim.dragElm != this)
drawDots(g, point1, lead1, curcount);
}
void drawWaveform(Graphics g, Point center) {
g.setColor(needsHighlight() ? selectColor : Color.gray);
setPowerColor(g, false);
int xc = center.x; int yc = center.y;
drawThickCircle(g, xc, yc, circleSize);
int wl = 8;
adjustBbox(xc-circleSize, yc-circleSize,
xc+circleSize, yc+circleSize);
}
void setPoints() {
super.setPoints();
lead1 = interpPoint(point1, point2, 1-circleSize/dn);
}
double getVoltageDiff() { return volts[0]; }
boolean hasGroundConnection(int n1) { return true; }
int getVoltageSourceCount() {
return 1;
}
double getPower() { return -getVoltageDiff()*current; }
void getInfo(String arr[]) {
arr[0] = "AM Source";
arr[1] = "I = " + getCurrentText(getCurrent());
arr[2] = "V = " +
getVoltageText(getVoltageDiff());
arr[3] = "cf = " + getUnitText(carrierfreq, "Hz");
arr[4] = "sf = " + getUnitText(signalfreq, "Hz");
arr[5] = "Vmax = " + getVoltageText(maxVoltage);
}
public EditInfo getEditInfo(int n) {
if (n == 0)
return new EditInfo("Max Voltage", maxVoltage, -20, 20);
if (n == 1)
return new EditInfo("Carrier Frequency (Hz)", carrierfreq, 4, 500);
if (n == 2)
return new EditInfo("Signal Frequency (Hz)", signalfreq, 4, 500);
return null;
}
public void setEditValue(int n, EditInfo ei) {
if (n == 0)
maxVoltage = ei.value;
if (n == 1)
carrierfreq = ei.value;
if (n == 2)
signalfreq=ei.value;
}
}

View File

@@ -0,0 +1,76 @@
/*
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 com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.event.dom.client.MouseWheelEvent;
import com.google.gwt.event.dom.client.MouseWheelHandler;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Button;
public class AboutBox extends PopupPanel {
VerticalPanel vp;
Button okButton;
AboutBox(String version) {
super();
vp = new VerticalPanel();
setWidget(vp);
vp.setWidth("400px");
vp.add(new HTML("<p>Circuit Simulator version "+version+".</p>"+
"<p>Original by Paul Falstad.<br><a href=\"http://www.falstad.com/\" target=\"_blank\">http://www.falstad.com/</a></p>"+
"<p>JavaScript conversion by Iain Sharp.<br><a href=\"http://lushprojects.com/\" target=\"_blank\">http://lushprojects.com/</a></p>"+
"<p style=\"font-size:9px\">This program 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.</p>"+
"<p style=\"font-size:9px\">This program 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.</p>"+
"<p style=\"font-size:9px\">For details of licensing see <A href=\"http://www.gnu.org/licenses/\" target=\"_blank\">http://www.gnu.org/licenses/</A>.</p>"));
vp.add(okButton = new Button("OK"));
okButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
close();
}
});
center();
show();
}
public void close() {
hide();
}
}

View File

@@ -0,0 +1,113 @@
/*
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 AnalogSwitch2Elm extends AnalogSwitchElm {
public AnalogSwitch2Elm(int xx, int yy) {
super(xx, yy);
}
public AnalogSwitch2Elm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f, st);
}
final int openhs = 16;
Point swposts[], swpoles[], ctlPoint;
void setPoints() {
super.setPoints();
calcLeads(32);
swposts = newPointArray(2);
swpoles = newPointArray(2);
interpPoint2(lead1, lead2, swpoles[0], swpoles[1], 1, openhs);
interpPoint2(point1, point2, swposts[0], swposts[1], 1, openhs);
ctlPoint = interpPoint(point1, point2, .5, openhs);
}
int getPostCount() { return 4; }
void draw(Graphics g) {
setBbox(point1, point2, openhs);
// draw first lead
setVoltageColor(g, volts[0]);
drawThickLine(g, point1, lead1);
// draw second lead
setVoltageColor(g, volts[1]);
drawThickLine(g, swpoles[0], swposts[0]);
// draw third lead
setVoltageColor(g, volts[2]);
drawThickLine(g, swpoles[1], swposts[1]);
// draw switch
g.setColor(lightGrayColor);
int position = (open) ? 1 : 0;
drawThickLine(g, lead1, swpoles[position]);
updateDotCount();
drawDots(g, point1, lead1, curcount);
drawDots(g, swpoles[position], swposts[position], curcount);
drawPosts(g);
}
Point getPost(int n) {
return (n == 0) ? point1 : (n == 3) ? ctlPoint : swposts[n-1];
}
int getDumpType() { return 160; }
void calculateCurrent() {
if (open)
current = (volts[0]-volts[2])/r_on;
else
current = (volts[0]-volts[1])/r_on;
}
void stamp() {
sim.stampNonLinear(nodes[0]);
sim.stampNonLinear(nodes[1]);
sim.stampNonLinear(nodes[2]);
}
void doStep() {
open = (volts[3] < 2.5);
if ((flags & FLAG_INVERT) != 0)
open = !open;
if (open) {
sim.stampResistor(nodes[0], nodes[2], r_on);
sim.stampResistor(nodes[0], nodes[1], r_off);
} else {
sim.stampResistor(nodes[0], nodes[1], r_on);
sim.stampResistor(nodes[0], nodes[2], r_off);
}
}
boolean getConnection(int n1, int n2) {
if (n1 == 3 || n2 == 3)
return false;
return true;
}
void getInfo(String arr[]) {
arr[0] = "analog switch (SPDT)";
arr[1] = "I = " + getCurrentDText(getCurrent());
}
}

View File

@@ -0,0 +1,153 @@
/*
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 AnalogSwitchElm extends CircuitElm {
final int FLAG_INVERT = 1;
double resistance, r_on, r_off;
public AnalogSwitchElm(int xx, int yy) {
super(xx, yy);
r_on = 20;
r_off = 1e10;
}
public AnalogSwitchElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f);
r_on = 20;
r_off = 1e10;
try {
r_on = new Double(st.nextToken()).doubleValue();
r_off = new Double(st.nextToken()).doubleValue();
} catch (Exception e) { }
}
String dump() {
return super.dump() + " " + r_on + " " + r_off;
}
int getDumpType() { return 159; }
boolean open;
Point ps, point3, lead3;
void setPoints() {
super.setPoints();
calcLeads(32);
ps = new Point();
int openhs = 16;
point3 = interpPoint(point1, point2, .5, -openhs);
lead3 = interpPoint(point1, point2, .5, -openhs/2);
}
void draw(Graphics g) {
int openhs = 16;
int hs = (open) ? openhs : 0;
setBbox(point1, point2, openhs);
draw2Leads(g);
g.setColor(lightGrayColor);
interpPoint(lead1, lead2, ps, 1, hs);
drawThickLine(g, lead1, ps);
setVoltageColor(g, volts[2]);
drawThickLine(g, point3, lead3);
if (!open)
doDots(g);
drawPosts(g);
}
void calculateCurrent() {
current = (volts[0]-volts[1])/resistance;
}
// we need this to be able to change the matrix for each step
boolean nonLinear() { return true; }
void stamp() {
sim.stampNonLinear(nodes[0]);
sim.stampNonLinear(nodes[1]);
}
void doStep() {
open = (volts[2] < 2.5);
if ((flags & FLAG_INVERT) != 0)
open = !open;
resistance = (open) ? r_off : r_on;
sim.stampResistor(nodes[0], nodes[1], resistance);
}
void drag(int xx, int yy) {
xx = sim.snapGrid(xx);
yy = sim.snapGrid(yy);
if (abs(x-xx) < abs(y-yy))
xx = x;
else
yy = y;
int q1 = abs(x-xx)+abs(y-yy);
int q2 = (q1/2) % sim.gridSize;
if (q2 != 0)
return;
x2 = xx; y2 = yy;
setPoints();
}
int getPostCount() { return 3; }
Point getPost(int n) {
return (n == 0) ? point1 : (n == 1) ? point2 : point3;
}
void getInfo(String arr[]) {
arr[0] = "analog switch";
arr[1] = open ? "open" : "closed";
arr[2] = "Vd = " + getVoltageDText(getVoltageDiff());
arr[3] = "I = " + getCurrentDText(getCurrent());
arr[4] = "Vc = " + getVoltageText(volts[2]);
}
// we have to just assume current will flow either way, even though that
// might cause singular matrix errors
boolean getConnection(int n1, int n2) {
if (n1 == 2 || n2 == 2)
return false;
return true;
}
public EditInfo getEditInfo(int n) {
if (n == 0) {
EditInfo ei = new EditInfo("", 0, -1, -1);
ei.checkbox = new Checkbox("Normally closed",
(flags & FLAG_INVERT) != 0);
return ei;
}
if (n == 1)
return new EditInfo("On Resistance (ohms)", r_on, 0, 0);
if (n == 2)
return new EditInfo("Off Resistance (ohms)", r_off, 0, 0);
return null;
}
public void setEditValue(int n, EditInfo ei) {
if (n == 0)
flags = (ei.checkbox.getState()) ?
(flags | FLAG_INVERT) :
(flags & ~FLAG_INVERT);
if (n == 1 && ei.value > 0)
r_on = ei.value;
if (n == 2 && ei.value > 0)
r_off = ei.value;
}
}

View File

@@ -0,0 +1,63 @@
/*
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 AndGateElm extends GateElm {
public AndGateElm(int xx, int yy) { super(xx, yy); }
public AndGateElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f, st);
}
void setPoints() {
super.setPoints();
// 0=topleft, 1-10 = top curve, 11 = right, 12-21=bottom curve,
// 22 = bottom left
Point triPoints[] = newPointArray(23);
interpPoint2(lead1, lead2, triPoints[0], triPoints[22], 0, hs2);
int i;
for (i = 0; i != 10; i++) {
double a = i*.1;
double b = Math.sqrt(1-a*a);
interpPoint2(lead1, lead2,
triPoints[i+1], triPoints[21-i],
.5+a/2, b*hs2);
}
triPoints[11] = new Point(lead2);
if (isInverting()) {
pcircle = interpPoint(point1, point2, .5+(ww+4)/dn);
lead2 = interpPoint(point1, point2, .5+(ww+8)/dn);
}
gatePoly = createPolygon(triPoints);
}
String getGateName() { return "AND gate"; }
boolean calcFunction() {
int i;
boolean f = true;
for (i = 0; i != inputCount; i++)
f &= getInput(i);
return f;
}
int getDumpType() { return 150; }
int getShortcut() { return '2'; }
}

View File

@@ -0,0 +1,48 @@
/*
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 AntennaElm extends RailElm {
public AntennaElm(int xx, int yy) { super(xx, yy, WF_DC); }
public AntennaElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f, st);
waveform = WF_DC;
}
double fmphase;
void stamp() {
sim.stampVoltageSource(0, nodes[0], voltSource);
}
void doStep() {
sim.updateVoltageSource(0, nodes[0], voltSource, getVoltage());
}
double getVoltage() {
fmphase += 2*pi*(2200+Math.sin(2*pi*sim.t*13)*100)*sim.timeStep;
double fm = 3*Math.sin(fmphase);
return Math.sin(2*pi*sim.t*3000)*(1.3+Math.sin(2*pi*sim.t*12))*3 +
Math.sin(2*pi*sim.t*2710)*(1.3+Math.sin(2*pi*sim.t*13))*3 +
Math.sin(2*pi*sim.t*2433)*(1.3+Math.sin(2*pi*sim.t*14))*3 + fm;
}
int getDumpType() { return 'A'; }
int getShortcut() { return 0; }
}

View File

@@ -0,0 +1,89 @@
/*
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;
import java.util.Vector;
class BoxElm extends GraphicElm {
public BoxElm(int xx, int yy) {
super(xx, yy);
x2 = xx + 16;
y2 = yy + 16;
setBbox(x, y, x2, y2);
}
public BoxElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f);
x2 = xb;
y2 = yb;
/* if ( st.hasMoreTokens() )
x = new Integer(st.nextToken()).intValue();
if ( st.hasMoreTokens() )
y = new Integer(st.nextToken()).intValue();
if ( st.hasMoreTokens() )
x2 = new Integer(st.nextToken()).intValue();
if ( st.hasMoreTokens() )
y2 = new Integer(st.nextToken()).intValue();*/
setBbox(x, y, x2, y2);
}
String dump() {
return super.dump();
}
int getDumpType() { return 'b'; }
void drag(int xx, int yy) {
x = xx;
y = yy;
}
void draw(Graphics g) {
//g.setColor(needsHighlight() ? selectColor : lightGrayColor);
g.setColor(needsHighlight() ? selectColor : Color.GRAY);
setBbox(x, y, x2, y2);
if ( x < x2 && y < y2 )
g.fillRect(x,y, x2-x, y2-y);
else if ( x > x2 && y < y2 )
g.fillRect(x2,y, x-x2, y2-y);
else if ( x < x2 && y > y2 )
g.fillRect(x, y2, x2-x, y-y2);
else
g.fillRect(x2, y2, x-x2, y-y2);
}
public EditInfo getEditInfo(int n) {
return null;
}
public void setEditValue(int n, EditInfo ei) {
}
void getInfo(String arr[]) {
}
@Override
int getShortcut() { return 0; }
}

View File

@@ -0,0 +1,73 @@
/*
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 CC2Elm extends ChipElm {
double gain;
public CC2Elm(int xx, int yy) { super(xx, yy); gain = 1; }
public CC2Elm(int xx, int yy, int g) { super(xx, yy); gain = g; }
public CC2Elm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f, st);
gain = new Double(st.nextToken()).doubleValue();
}
String dump() {
return super.dump() + " " + gain;
}
String getChipName() { return "CC2"; }
void setupPins() {
sizeX = 2;
sizeY = 3;
pins = new Pin[3];
pins[0] = new Pin(0, SIDE_W, "X");
pins[0].output = true;
pins[1] = new Pin(2, SIDE_W, "Y");
pins[2] = new Pin(1, SIDE_E, "Z");
}
void getInfo(String arr[]) {
arr[0] = (gain == 1) ? "CCII+" : "CCII-";
arr[1] = "X,Y = " + getVoltageText(volts[0]);
arr[2] = "Z = " + getVoltageText(volts[2]);
arr[3] = "I = " + getCurrentText(pins[0].current);
}
//boolean nonLinear() { return true; }
void stamp() {
// X voltage = Y voltage
sim.stampVoltageSource(0, nodes[0], pins[0].voltSource);
sim.stampVCVS(0, nodes[1], 1, pins[0].voltSource);
// Z current = gain * X current
sim.stampCCCS(0, nodes[2], pins[0].voltSource, gain);
}
void draw(Graphics g) {
pins[2].current = pins[0].current * gain;
drawChip(g);
}
int getPostCount() { return 3; }
int getVoltageSourceCount() { return 1; }
int getDumpType() { return 179; }
}
class CC2NegElm extends CC2Elm {
public CC2NegElm(int xx, int yy) { super(xx, yy, -1); }
Class getDumpClass() { return CC2Elm.class; }
}

View File

@@ -0,0 +1,160 @@
/*
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 CapacitorElm extends CircuitElm {
double capacitance;
double compResistance, voltdiff;
Point plate1[], plate2[];
public static final int FLAG_BACK_EULER = 2;
public CapacitorElm(int xx, int yy) {
super(xx, yy);
capacitance = 1e-5;
}
public CapacitorElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f);
capacitance = new Double(st.nextToken()).doubleValue();
voltdiff = new Double(st.nextToken()).doubleValue();
}
boolean isTrapezoidal() { return (flags & FLAG_BACK_EULER) == 0; }
void setNodeVoltage(int n, double c) {
super.setNodeVoltage(n, c);
voltdiff = volts[0]-volts[1];
}
void reset() {
current = curcount = 0;
// put small charge on caps when reset to start oscillators
voltdiff = 1e-3;
}
int getDumpType() { return 'c'; }
String dump() {
return super.dump() + " " + capacitance + " " + voltdiff;
}
void setPoints() {
super.setPoints();
double f = (dn/2-4)/dn;
// calc leads
lead1 = interpPoint(point1, point2, f);
lead2 = interpPoint(point1, point2, 1-f);
// calc plates
plate1 = newPointArray(2);
plate2 = newPointArray(2);
interpPoint2(point1, point2, plate1[0], plate1[1], f, 12);
interpPoint2(point1, point2, plate2[0], plate2[1], 1-f, 12);
}
void draw(Graphics g) {
int hs = 12;
setBbox(point1, point2, hs);
// draw first lead and plate
setVoltageColor(g, volts[0]);
drawThickLine(g, point1, lead1);
setPowerColor(g, false);
drawThickLine(g, plate1[0], plate1[1]);
if (sim.powerCheckItem.getState())
g.setColor(Color.gray);
// draw second lead and plate
setVoltageColor(g, volts[1]);
drawThickLine(g, point2, lead2);
setPowerColor(g, false);
drawThickLine(g, plate2[0], plate2[1]);
updateDotCount();
if (sim.dragElm != this) {
drawDots(g, point1, lead1, curcount);
drawDots(g, point2, lead2, -curcount);
}
drawPosts(g);
if (sim.showValuesCheckItem.getState()) {
String s = getShortUnitText(capacitance, "F");
drawValues(g, s, hs);
}
}
void stamp() {
// capacitor companion model using trapezoidal approximation
// (Norton equivalent) consists of a current source in
// parallel with a resistor. Trapezoidal is more accurate
// than backward euler but can cause oscillatory behavior
// if RC is small relative to the timestep.
if (isTrapezoidal())
compResistance = sim.timeStep/(2*capacitance);
else
compResistance = sim.timeStep/capacitance;
sim.stampResistor(nodes[0], nodes[1], compResistance);
sim.stampRightSide(nodes[0]);
sim.stampRightSide(nodes[1]);
}
void startIteration() {
if (isTrapezoidal())
curSourceValue = -voltdiff/compResistance-current;
else
curSourceValue = -voltdiff/compResistance;
//System.out.println("cap " + compResistance + " " + curSourceValue + " " + current + " " + voltdiff);
}
void calculateCurrent() {
double voltdiff = volts[0] - volts[1];
// we check compResistance because this might get called
// before stamp(), which sets compResistance, causing
// infinite current
if (compResistance > 0)
current = voltdiff/compResistance + curSourceValue;
}
double curSourceValue;
void doStep() {
sim.stampCurrentSource(nodes[0], nodes[1], curSourceValue);
}
void getInfo(String arr[]) {
arr[0] = "capacitor";
getBasicInfo(arr);
arr[3] = "C = " + getUnitText(capacitance, "F");
arr[4] = "P = " + getUnitText(getPower(), "W");
//double v = getVoltageDiff();
//arr[4] = "U = " + getUnitText(.5*capacitance*v*v, "J");
}
public EditInfo getEditInfo(int n) {
if (n == 0)
return new EditInfo("Capacitance (F)", capacitance, 0, 0);
if (n == 1) {
EditInfo ei = new EditInfo("", 0, -1, -1);
ei.checkbox = new Checkbox("Trapezoidal Approximation", isTrapezoidal());
return ei;
}
return null;
}
public void setEditValue(int n, EditInfo ei) {
if (n == 0 && ei.value > 0)
capacitance = ei.value;
if (n == 1) {
if (ei.checkbox.getState())
flags &= ~FLAG_BACK_EULER;
else
flags |= FLAG_BACK_EULER;
}
}
int getShortcut() { return 'c'; }
}

View File

@@ -0,0 +1,42 @@
/*
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 com.google.gwt.user.client.ui.CheckBox;
class Checkbox extends CheckBox {
public Checkbox(String s){
super(s);
}
public Checkbox(String s, boolean b){
super(s);
this.setValue(b);
}
public boolean getState(){
return this.getValue();
}
public void setState(boolean s){
this.setValue(s);
}
}

View File

@@ -0,0 +1,32 @@
/*
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 com.google.gwt.user.client.Command;
import com.google.gwt.user.client.ui.MenuItem;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
public class CheckboxAlignedMenuItem extends MenuItem {
public CheckboxAlignedMenuItem(String s, Command cmd) {
super(SafeHtmlUtils.fromTrustedString(CheckboxMenuItem.checkBoxHtml+"&nbsp;</div>"+s), cmd);
}
}

View File

@@ -0,0 +1,92 @@
/*
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 com.google.gwt.user.client.ui.MenuItem;
import com.google.gwt.user.client.Command;
import com.google.gwt.core.client.GWT;
public class CheckboxMenuItem extends MenuItem implements Command {
private boolean on=false;
private String name="";
private String shortcut="";
private Command extcmd=null;
static String checkBoxHtml="<div style=\"display:inline-block;width:15px;\">";
public CheckboxMenuItem(String s){
super(s, (Command)null);
super.setScheduledCommand(this);
name=s;
setState(false);
}
public CheckboxMenuItem(String s, Command cmd){
super(s, (Command)null);
super.setScheduledCommand(this);
extcmd=cmd;
name=s;
setState(false);
}
public CheckboxMenuItem(String s, String c, Command cmd){
this(s, cmd);
shortcut=c;
}
public CheckboxMenuItem(String s, String c){
this(s);
shortcut=c;
}
public void addShortcut(String s) {
shortcut=s;
}
public void execute() {
setState(!on);
if (extcmd!=null)
extcmd.execute();
}
public void setState(boolean newstate) {
on = newstate;
String s;
if (on)
// super.setHTML("&#10004;&nbsp;"+name);
s = checkBoxHtml+"&#10004;</div>"+name;
else
// super.setHTML("&emsp;&nbsp;"+name);
s = checkBoxHtml+"&nbsp;</div>"+name;
if (shortcut!="")
if (shortcut.length()==1)
s = s + "<div style=\"display:inline-block;width:20px;right:10px;text-align:center;position:absolute;\">"+shortcut+"</div>";
else
s = s + "<div style=\"display:inline-block;right:10px;text-align:right;position:absolute;\">"+shortcut+"</div>";
setHTML(s);
}
public boolean getState(){
return on;
}
}

View File

@@ -0,0 +1,320 @@
/*
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;
import com.google.gwt.canvas.dom.client.TextMetrics;
abstract class ChipElm extends CircuitElm {
int csize, cspc, cspc2;
int bits;
final int FLAG_SMALL = 1;
final int FLAG_FLIP_X = 1024;
final int FLAG_FLIP_Y = 2048;
public ChipElm(int xx, int yy) {
super(xx, yy);
if (needsBits())
bits = (this instanceof DecadeElm) ? 10 : 4;
noDiagonal = true;
setupPins();
setSize(sim.smallGridCheckItem.getState() ? 1 : 2);
}
public ChipElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f);
if (needsBits())
bits = new Integer(st.nextToken()).intValue();
noDiagonal = true;
setupPins();
setSize((f & FLAG_SMALL) != 0 ? 1 : 2);
int i;
for (i = 0; i != getPostCount(); i++) {
if (pins[i].state) {
volts[i] = new Double(st.nextToken()).doubleValue();
pins[i].value = volts[i] > 2.5;
}
}
}
boolean needsBits() { return false; }
void setSize(int s) {
csize = s;
cspc = 8*s;
cspc2 = cspc*2;
flags &= ~FLAG_SMALL;
flags |= (s == 1) ? FLAG_SMALL : 0;
}
abstract void setupPins();
void draw(Graphics g) {
drawChip(g);
}
void drawChip(Graphics g) {
int i;
Font oldfont = g.getFont();
Font f = new Font("SansSerif", 0, 10*csize);
g.setFont(f);
// FontMetrics fm = g.getFontMetrics();
for (i = 0; i != getPostCount(); i++) {
Pin p = pins[i];
setVoltageColor(g, volts[i]);
Point a = p.post;
Point b = p.stub;
drawThickLine(g, a, b);
p.curcount = updateDotCount(p.current, p.curcount);
drawDots(g, b, a, p.curcount);
if (p.bubble) {
g.setColor(sim.printableCheckItem.getState() ?
Color.white : Color.black);
drawThickCircle(g, p.bubbleX, p.bubbleY, 1);
g.setColor(lightGrayColor);
drawThickCircle(g, p.bubbleX, p.bubbleY, 3);
}
g.setColor(whiteColor);
// int sw = fm.stringWidth(p.text);
int sw=(int)g.context.measureText(p.text).getWidth();
int asc=(int)g.currentFontSize;
g.drawString(p.text, p.textloc.x-sw/2,
p.textloc.y+asc/2);
if (p.lineOver) {
int ya = p.textloc.y-asc/2;
g.drawLine(p.textloc.x-sw/2, ya, p.textloc.x+sw/2, ya);
}
}
g.setColor(needsHighlight() ? selectColor : lightGrayColor);
drawThickPolygon(g, rectPointsX, rectPointsY, 4);
if (clockPointsX != null)
g.drawPolyline(clockPointsX, clockPointsY, 3);
for (i = 0; i != getPostCount(); i++)
drawPost(g, pins[i].post.x, pins[i].post.y, nodes[i]);
g.setFont(oldfont);
}
int rectPointsX[], rectPointsY[];
int clockPointsX[], clockPointsY[];
Pin pins[];
int sizeX, sizeY;
boolean lastClock;
void drag(int xx, int yy) {
yy = sim.snapGrid(yy);
if (xx < x) {
xx = x; yy = y;
} else {
y = y2 = yy;
x2 = sim.snapGrid(xx);
}
setPoints();
}
void setPoints() {
if (x2-x > sizeX*cspc2 && this == sim.dragElm)
setSize(2);
int hs = cspc;
int x0 = x+cspc2; int y0 = y;
int xr = x0-cspc;
int yr = y0-cspc;
int xs = sizeX*cspc2;
int ys = sizeY*cspc2;
rectPointsX = new int[] { xr, xr+xs, xr+xs, xr };
rectPointsY = new int[] { yr, yr, yr+ys, yr+ys };
setBbox(xr, yr, rectPointsX[2], rectPointsY[2]);
int i;
for (i = 0; i != getPostCount(); i++) {
Pin p = pins[i];
switch (p.side) {
case SIDE_N: p.setPoint(x0, y0, 1, 0, 0, -1, 0, 0); break;
case SIDE_S: p.setPoint(x0, y0, 1, 0, 0, 1, 0, ys-cspc2);break;
case SIDE_W: p.setPoint(x0, y0, 0, 1, -1, 0, 0, 0); break;
case SIDE_E: p.setPoint(x0, y0, 0, 1, 1, 0, xs-cspc2, 0);break;
}
}
}
Point getPost(int n) {
return pins[n].post;
}
abstract int getVoltageSourceCount(); // output count
void setVoltageSource(int j, int vs) {
int i;
for (i = 0; i != getPostCount(); i++) {
Pin p = pins[i];
if (p.output && j-- == 0) {
p.voltSource = vs;
return;
}
}
System.out.println("setVoltageSource failed for " + this);
}
void stamp() {
int i;
for (i = 0; i != getPostCount(); i++) {
Pin p = pins[i];
if (p.output)
sim.stampVoltageSource(0, nodes[i], p.voltSource);
}
}
void execute() {}
void doStep() {
int i;
for (i = 0; i != getPostCount(); i++) {
Pin p = pins[i];
if (!p.output)
p.value = volts[i] > 2.5;
}
execute();
for (i = 0; i != getPostCount(); i++) {
Pin p = pins[i];
if (p.output)
sim.updateVoltageSource(0, nodes[i], p.voltSource,
p.value ? 5 : 0);
}
}
void reset() {
int i;
for (i = 0; i != getPostCount(); i++) {
pins[i].value = false;
pins[i].curcount = 0;
volts[i] = 0;
}
lastClock = false;
}
String dump() {
int t = getDumpType();
String s = super.dump();
if (needsBits())
s += " " + bits;
int i;
for (i = 0; i != getPostCount(); i++) {
if (pins[i].state)
s += " " + volts[i];
}
return s;
}
void getInfo(String arr[]) {
arr[0] = getChipName();
int i, a = 1;
for (i = 0; i != getPostCount(); i++) {
Pin p = pins[i];
if (arr[a] != null)
arr[a] += "; ";
else
arr[a] = "";
String t = p.text;
if (p.lineOver)
t += '\'';
if (p.clock)
t = "Clk";
arr[a] += t + " = " + getVoltageText(volts[i]);
if (i % 2 == 1)
a++;
}
}
void setCurrent(int x, double c) {
int i;
for (i = 0; i != getPostCount(); i++)
if (pins[i].output && pins[i].voltSource == x)
pins[i].current = c;
}
String getChipName() { return "chip"; }
boolean getConnection(int n1, int n2) { return false; }
boolean hasGroundConnection(int n1) {
return pins[n1].output;
}
public EditInfo getEditInfo(int n) {
if (n == 0) {
EditInfo ei = new EditInfo("", 0, -1, -1);
ei.checkbox = new Checkbox("Flip X", (flags & FLAG_FLIP_X) != 0);
return ei;
}
if (n == 1) {
EditInfo ei = new EditInfo("", 0, -1, -1);
ei.checkbox = new Checkbox("Flip Y", (flags & FLAG_FLIP_Y) != 0);
return ei;
}
return null;
}
public void setEditValue(int n, EditInfo ei) {
if (n == 0) {
if (ei.checkbox.getState())
flags |= FLAG_FLIP_X;
else
flags &= ~FLAG_FLIP_X;
setPoints();
}
if (n == 1) {
if (ei.checkbox.getState())
flags |= FLAG_FLIP_Y;
else
flags &= ~FLAG_FLIP_Y;
setPoints();
}
}
final int SIDE_N = 0;
final int SIDE_S = 1;
final int SIDE_W = 2;
final int SIDE_E = 3;
class Pin {
Pin(int p, int s, String t) {
pos = p; side = s; text = t;
}
Point post, stub;
Point textloc;
int pos, side, voltSource, bubbleX, bubbleY;
String text;
boolean lineOver, bubble, clock, output, value, state;
double curcount, current;
void setPoint(int px, int py, int dx, int dy, int dax, int day,
int sx, int sy) {
if ((flags & FLAG_FLIP_X) != 0) {
dx = -dx;
dax = -dax;
px += cspc2*(sizeX-1);
sx = -sx;
}
if ((flags & FLAG_FLIP_Y) != 0) {
dy = -dy;
day = -day;
py += cspc2*(sizeY-1);
sy = -sy;
}
int xa = px+cspc2*dx*pos+sx;
int ya = py+cspc2*dy*pos+sy;
post = new Point(xa+dax*cspc2, ya+day*cspc2);
stub = new Point(xa+dax*cspc , ya+day*cspc );
textloc = new Point(xa , ya );
if (bubble) {
bubbleX = xa+dax*10*csize;
bubbleY = ya+day*10*csize;
}
if (clock) {
clockPointsX = new int[3];
clockPointsY = new int[3];
clockPointsX[0] = xa+dax*cspc-dx*cspc/2;
clockPointsY[0] = ya+day*cspc-dy*cspc/2;
clockPointsX[1] = xa;
clockPointsY[1] = ya;
clockPointsX[2] = xa+dax*cspc+dx*cspc/2;
clockPointsY[2] = ya+day*cspc+dy*cspc/2;
}
}
}
}

View File

@@ -0,0 +1,37 @@
/*
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 com.google.gwt.user.client.ui.ListBox;
public class Choice extends ListBox {
Choice() {
super();
}
public void add(String s){
this.addItem(s);
}
public void select(int i){
this.setSelectedIndex(i);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,750 @@
/*
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.text.DecimalFormat;
//import java.text.NumberFormat;
import com.google.gwt.canvas.client.Canvas;
import com.google.gwt.canvas.dom.client.CanvasGradient;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.canvas.dom.client.Context2d;
import com.google.gwt.canvas.dom.client.TextMetrics;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.i18n.client.NumberFormat;
public abstract class CircuitElm implements Editable {
static double voltageRange = 5;
static int colorScaleCount = 32;
static Color colorScale[];
static double currentMult, powerMult;
static Point ps1, ps2;
static CirSim sim;
static Color whiteColor, selectColor, lightGrayColor;
static Font unitsFont;
static NumberFormat showFormat, shortFormat;//, noCommaFormat;
static final double pi = 3.14159265358979323846;
int x, y, x2, y2, flags, nodes[], voltSource;
int dx, dy, dsign;
double dn, dpx1, dpy1;
Point point1, point2, lead1, lead2;
double volts[];
double current, curcount;
Rectangle boundingBox;
boolean noDiagonal;
public boolean selected;
private boolean iAmMouseElm=false;
int getDumpType() { return 0; }
Class getDumpClass() { return getClass(); }
int getDefaultFlags() { return 0; }
static void initClass(CirSim s) {
unitsFont = new Font("SansSerif", 0, 12);
sim = s;
colorScale = new Color[colorScaleCount];
int i;
for (i = 0; i != colorScaleCount; i++) {
double v = i*2./colorScaleCount - 1;
if (v < 0) {
int n1 = (int) (128*-v)+127;
int n2 = (int) (127*(1+v));
colorScale[i] = new Color(n1, n2, n2);
} else {
int n1 = (int) (128*v)+127;
int n2 = (int) (127*(1-v));
colorScale[i] = new Color(n2, n1, n2);
}
}
ps1 = new Point();
ps2 = new Point();
// showFormat = DecimalFormat.getInstance();
// showFormat.setMaximumFractionDigits(2);
showFormat=NumberFormat.getFormat("####.##");
// shortFormat = DecimalFormat.getInstance();
// shortFormat.setMaximumFractionDigits(1);
shortFormat=NumberFormat.getFormat("####.#");
// noCommaFormat = DecimalFormat.getInstance();
// noCommaFormat.setMaximumFractionDigits(10);
// noCommaFormat.setGroupingUsed(false);
}
CircuitElm(int xx, int yy) {
x = x2 = xx;
y = y2 = yy;
flags = getDefaultFlags();
allocNodes();
initBoundingBox();
}
CircuitElm(int xa, int ya, int xb, int yb, int f) {
x = xa; y = ya; x2 = xb; y2 = yb; flags = f;
allocNodes();
initBoundingBox();
}
void initBoundingBox() {
boundingBox = new Rectangle();
boundingBox.setBounds(min(x, x2), min(y, y2),
abs(x2-x)+1, abs(y2-y)+1);
}
void allocNodes() {
nodes = new int[getPostCount()+getInternalNodeCount()];
volts = new double[getPostCount()+getInternalNodeCount()];
}
String dump() {
int t = getDumpType();
return (t < 127 ? ((char)t)+" " : t+" ") + x + " " + y + " " +
x2 + " " + y2 + " " + flags;
}
void reset() {
int i;
for (i = 0; i != getPostCount()+getInternalNodeCount(); i++)
volts[i] = 0;
curcount = 0;
}
void draw(Graphics g) {}
void setCurrent(int x, double c) { current = c; }
double getCurrent() { return current; }
void doStep() {}
void delete() {}
void startIteration() {}
double getPostVoltage(int x) { return volts[x]; }
void setNodeVoltage(int n, double c) {
volts[n] = c;
calculateCurrent();
}
void calculateCurrent() {}
void setPoints() {
dx = x2-x; dy = y2-y;
dn = Math.sqrt(dx*dx+dy*dy);
dpx1 = dy/dn;
dpy1 = -dx/dn;
dsign = (dy == 0) ? sign(dx) : sign(dy);
point1 = new Point(x , y );
point2 = new Point(x2, y2);
}
void calcLeads(int len) {
if (dn < len || len == 0) {
lead1 = point1;
lead2 = point2;
return;
}
lead1 = interpPoint(point1, point2, (dn-len)/(2*dn));
lead2 = interpPoint(point1, point2, (dn+len)/(2*dn));
}
Point interpPoint(Point a, Point b, double f) {
Point p = new Point();
interpPoint(a, b, p, f);
return p;
}
void interpPoint(Point a, Point b, Point c, double f) {
int xpd = b.x-a.x;
int ypd = b.y-a.y;
/*double q = (a.x*(1-f)+b.x*f+.48);
System.out.println(q + " " + (int) q);*/
c.x = (int) Math.floor(a.x*(1-f)+b.x*f+.48);
c.y = (int) Math.floor(a.y*(1-f)+b.y*f+.48);
}
void interpPoint(Point a, Point b, Point c, double f, double g) {
// int xpd = b.x-a.x;
// int ypd = b.y-a.y;
int gx = b.y-a.y;
int gy = a.x-b.x;
g /= Math.sqrt(gx*gx+gy*gy);
c.x = (int) Math.floor(a.x*(1-f)+b.x*f+g*gx+.48);
c.y = (int) Math.floor(a.y*(1-f)+b.y*f+g*gy+.48);
}
Point interpPoint(Point a, Point b, double f, double g) {
Point p = new Point();
interpPoint(a, b, p, f, g);
return p;
}
void interpPoint2(Point a, Point b, Point c, Point d, double f, double g) {
// int xpd = b.x-a.x;
// int ypd = b.y-a.y;
int gx = b.y-a.y;
int gy = a.x-b.x;
g /= Math.sqrt(gx*gx+gy*gy);
c.x = (int) Math.floor(a.x*(1-f)+b.x*f+g*gx+.48);
c.y = (int) Math.floor(a.y*(1-f)+b.y*f+g*gy+.48);
d.x = (int) Math.floor(a.x*(1-f)+b.x*f-g*gx+.48);
d.y = (int) Math.floor(a.y*(1-f)+b.y*f-g*gy+.48);
}
void draw2Leads(Graphics g) {
// draw first lead
setVoltageColor(g, volts[0]);
drawThickLine(g, point1, lead1);
// draw second lead
setVoltageColor(g, volts[1]);
drawThickLine(g, lead2, point2);
}
Point [] newPointArray(int n) {
Point a[] = new Point[n];
while (n > 0)
a[--n] = new Point();
return a;
}
void drawDots(Graphics g, Point pa, Point pb, double pos) {
if (sim.stoppedCheck.getState() || pos == 0 || !sim.dotsCheckItem.getState())
return;
int dx = pb.x-pa.x;
int dy = pb.y-pa.y;
double dn = Math.sqrt(dx*dx+dy*dy);
g.setColor(sim.conventionCheckItem.getState()?Color.yellow:Color.cyan);
int ds = 16;
pos %= ds;
if (pos < 0)
pos += ds;
double di = 0;
for (di = pos; di < dn; di += ds) {
int x0 = (int) (pa.x+di*dx/dn);
int y0 = (int) (pa.y+di*dy/dn);
g.fillRect(x0-2, y0-2, 4, 4);
}
}
Polygon calcArrow(Point a, Point b, double al, double aw) {
Polygon poly = new Polygon();
Point p1 = new Point();
Point p2 = new Point();
int adx = b.x-a.x;
int ady = b.y-a.y;
double l = Math.sqrt(adx*adx+ady*ady);
poly.addPoint(b.x, b.y);
interpPoint2(a, b, p1, p2, 1-al/l, aw);
poly.addPoint(p1.x, p1.y);
poly.addPoint(p2.x, p2.y);
return poly;
}
Polygon createPolygon(Point a, Point b, Point c) {
Polygon p = new Polygon();
p.addPoint(a.x, a.y);
p.addPoint(b.x, b.y);
p.addPoint(c.x, c.y);
return p;
}
Polygon createPolygon(Point a, Point b, Point c, Point d) {
Polygon p = new Polygon();
p.addPoint(a.x, a.y);
p.addPoint(b.x, b.y);
p.addPoint(c.x, c.y);
p.addPoint(d.x, d.y);
return p;
}
Polygon createPolygon(Point a[]) {
Polygon p = new Polygon();
int i;
for (i = 0; i != a.length; i++)
p.addPoint(a[i].x, a[i].y);
return p;
}
void drag(int xx, int yy) {
xx = sim.snapGrid(xx);
yy = sim.snapGrid(yy);
if (noDiagonal) {
if (Math.abs(x-xx) < Math.abs(y-yy)) {
xx = x;
} else {
yy = y;
}
}
x2 = xx; y2 = yy;
setPoints();
}
void move(int dx, int dy) {
x += dx; y += dy; x2 += dx; y2 += dy;
boundingBox.move(dx, dy);
setPoints();
}
// determine if moving this element by (dx,dy) will put it on top of another element
boolean allowMove(int dx, int dy) {
int nx = x+dx;
int ny = y+dy;
int nx2 = x2+dx;
int ny2 = y2+dy;
int i;
for (i = 0; i != sim.elmList.size(); i++) {
CircuitElm ce = sim.getElm(i);
if (ce.x == nx && ce.y == ny && ce.x2 == nx2 && ce.y2 == ny2)
return false;
if (ce.x == nx2 && ce.y == ny2 && ce.x2 == nx && ce.y2 == ny)
return false;
}
return true;
}
void movePoint(int n, int dx, int dy) {
// modified by IES to prevent the user dragging points to create zero sized nodes
// that then render improperly
int oldx=x;
int oldy=y;
int oldx2=x2;
int oldy2=y2;
if (n == 0) {
x += dx; y += dy;
} else {
x2 += dx; y2 += dy;
}
if (x==x2 && y==y2) {
x=oldx;
y=oldy;
x2=oldx2;
y2=oldy2;
}
setPoints();
}
void drawPosts(Graphics g) {
int i;
for (i = 0; i != getPostCount(); i++) {
Point p = getPost(i);
drawPost(g, p.x, p.y, nodes[i]);
}
}
void drawHandles(Graphics g, Color c) {
g.setColor(c);
g.fillRect(x-3, y-3, 7, 7);
g.fillRect(x2-3, y2-3, 7, 7);
}
void stamp() {}
int getVoltageSourceCount() { return 0; }
int getInternalNodeCount() { return 0; }
void setNode(int p, int n) { nodes[p] = n; }
void setVoltageSource(int n, int v) { voltSource = v; }
int getVoltageSource() { return voltSource; }
double getVoltageDiff() {
return volts[0] - volts[1];
}
boolean nonLinear() { return false; }
int getPostCount() { return 2; }
int getNode(int n) { return nodes[n]; }
Point getPost(int n) {
return (n == 0) ? point1 : (n == 1) ? point2 : null;
}
void drawPost(Graphics g, int x0, int y0, int n) {
if (sim.dragElm == null && !needsHighlight() &&
sim.getCircuitNode(n).links.size() == 2)
return;
if (sim.mouseMode == CirSim.MODE_DRAG_ROW ||
sim.mouseMode == CirSim.MODE_DRAG_COLUMN)
return;
drawPost(g, x0, y0);
}
void drawPost(Graphics g, int x0, int y0) {
g.setColor(whiteColor);
g.fillOval(x0-3, y0-3, 7, 7);
}
void setBbox(int x1, int y1, int x2, int y2) {
if (x1 > x2) { int q = x1; x1 = x2; x2 = q; }
if (y1 > y2) { int q = y1; y1 = y2; y2 = q; }
boundingBox.setBounds(x1, y1, x2-x1+1, y2-y1+1);
}
void setBbox(Point p1, Point p2, double w) {
setBbox(p1.x, p1.y, p2.x, p2.y);
int gx = p2.y-p1.y;
int gy = p1.x-p2.x;
int dpx = (int) (dpx1*w);
int dpy = (int) (dpy1*w);
adjustBbox(p1.x+dpx, p1.y+dpy, p1.x-dpx, p1.y-dpy);
}
void adjustBbox(int x1, int y1, int x2, int y2) {
if (x1 > x2) { int q = x1; x1 = x2; x2 = q; }
if (y1 > y2) { int q = y1; y1 = y2; y2 = q; }
x1 = min(boundingBox.x, x1);
y1 = min(boundingBox.y, y1);
x2 = max(boundingBox.x+boundingBox.width-1, x2);
y2 = max(boundingBox.y+boundingBox.height-1, y2);
boundingBox.setBounds(x1, y1, x2-x1, y2-y1);
}
void adjustBbox(Point p1, Point p2) {
adjustBbox(p1.x, p1.y, p2.x, p2.y);
}
boolean isCenteredText() { return false; }
void drawCenteredText(Graphics g, String s, int x, int y, boolean cx) {
// FontMetrics fm = g.getFontMetrics();
//int w = fm.stringWidth(s);
// int w=0;
// if (cx)
// x -= w/2;
// g.drawString(s, x, y+fm.getAscent()/2);
// adjustBbox(x, y-fm.getAscent()/2,
// x+w, y+fm.getAscent()/2+fm.getDescent());
int w=(int)g.context.measureText(s).getWidth();
int h2=(int)g.currentFontSize/2;
g.context.save();
g.context.setTextBaseline("middle");
if (cx) {
g.context.setTextAlign("center");
adjustBbox(x-w/2,y-h2,x+w/2,y+h2);
} else {
adjustBbox(x,y-h2,x+w,y+h2);
}
if (cx)
g.context.setTextAlign("center");
g.drawString(s, x, y);
g.context.restore();
}
void drawValues(Graphics g, String s, double hs) {
if (s == null)
return;
g.setFont(unitsFont);
//FontMetrics fm = g.getFontMetrics();
int w = (int)g.context.measureText(s).getWidth();;
g.setColor(whiteColor);
int ya = (int)g.currentFontSize/2;
int xc, yc;
if (this instanceof RailElm || this instanceof SweepElm) {
xc = x2;
yc = y2;
} else {
xc = (x2+x)/2;
yc = (y2+y)/2;
}
int dpx = (int) (dpx1*hs);
int dpy = (int) (dpy1*hs);
if (dpx == 0) {
g.drawString(s, xc-w/2, yc-abs(dpy)-2);
} else {
int xx = xc+abs(dpx)+2;
if (this instanceof VoltageElm || (x < x2 && y > y2))
xx = xc-(w+abs(dpx)+2);
g.drawString(s, xx, yc+dpy+ya);
}
}
void drawCoil(Graphics g, int hs, Point p1, Point p2,
double v1, double v2) {
double len = distance(p1, p2);
int segments = 30; // 10*(int) (len/10);
int i;
double segf = 1./segments;
ps1.setLocation(p1);
for (i = 0; i != segments; i++) {
double cx = (((i+1)*6.*segf) % 2)-1;
double hsx = Math.sqrt(1-cx*cx);
if (hsx < 0)
hsx = -hsx;
interpPoint(p1, p2, ps2, i*segf, hsx*hs);
double v = v1+(v2-v1)*i/segments;
setVoltageColor(g, v);
drawThickLine(g, ps1, ps2);
ps1.setLocation(ps2);
}
// GWT.log("Coil"+hs+" "+p1.x+" "+p1.y+" "+p2.x+" "+p2.y);
// g.context.save();
// g.context.setLineWidth(3.0);
// g.context.setTransform(((double)(p2.x-p1.x))/len, ((double)(p2.y-p1.y))/len, -((double)(p2.y-p1.y))/len,((double)(p2.x-p1.x))/len,p1.x,p1.y);
// CanvasGradient grad = g.context.createLinearGradient(0,0,len,0);
// grad.addColorStop(0, getVoltageColor(g,v1).getHexValue());
// grad.addColorStop(1.0, getVoltageColor(g,v2).getHexValue());
// g.context.setStrokeStyle(grad);
// g.context.beginPath();
// g.context.arc(len*0.16667,0,len*0.16667,pi,(hs<0)?0:pi*2.0, hs<0);
// g.context.arc(len*0.5,0,len*0.16667,pi,pi*2.0);
// g.context.arc(len*0.83333,0,len*0.16667,pi,pi*2.0);
// g.context.stroke();
// g.context.restore();
// g.context.setTransform(1.0, 0, 0, 1.0, 0, 0);
// g.context.setLineWidth(1.0);
}
static void drawThickLine(Graphics g, int x, int y, int x2, int y2) {
// g.drawLine(x, y, x2, y2);
// g.drawLine(x+1, y, x2+1, y2);
// g.drawLine(x, y+1, x2, y2+1);
// g.drawLine(x+1, y+1, x2+1, y2+1);
g.setLineWidth(3.0);
g.drawLine(x,y,x2,y2);
g.setLineWidth(1.0);
}
static void drawThickLine(Graphics g, Point pa, Point pb) {
// g.drawLine(pa.x, pa.y, pb.x, pb.y);
// g.drawLine(pa.x+1, pa.y, pb.x+1, pb.y);
// g.drawLine(pa.x, pa.y+1, pb.x, pb.y+1);
// g.drawLine(pa.x+1, pa.y+1, pb.x+1, pb.y+1);
g.setLineWidth(3.0);
g.drawLine(pa.x, pa.y, pb.x, pb.y);
g.setLineWidth(1.0);
}
static void drawThickPolygon(Graphics g, int xs[], int ys[], int c) {
int i;
for (i = 0; i != c-1; i++)
drawThickLine(g, xs[i], ys[i], xs[i+1], ys[i+1]);
drawThickLine(g, xs[i], ys[i], xs[0], ys[0]);
}
static void drawThickPolygon(Graphics g, Polygon p) {
drawThickPolygon(g, p.xpoints, p.ypoints, p.npoints);
}
static void drawThickCircle(Graphics g, int cx, int cy, int ri) {
int a;
double m = pi/180;
double r = ri*.98;
for (a = 0; a != 360; a += 20) {
double ax = Math.cos(a*m)*r + cx;
double ay = Math.sin(a*m)*r + cy;
double bx = Math.cos((a+20)*m)*r + cx;
double by = Math.sin((a+20)*m)*r + cy;
drawThickLine(g, (int) ax, (int) ay, (int) bx, (int) by);
}
}
static String getVoltageDText(double v) {
return getUnitText(Math.abs(v), "V");
}
static String getVoltageText(double v) {
return getUnitText(v, "V");
}
// IES - hacking
static String getUnitText(double v, String u) {
return myGetUnitText(v,u, false);
}
static String getShortUnitText(double v, String u) {
return myGetUnitText(v,u, true);
}
static String myGetUnitText(double v, String u, boolean sf) {
NumberFormat s;
if (sf)
s=shortFormat;
else
s=showFormat;
double va = Math.abs(v);
if (va < 1e-14)
return "0 " + u;
if (va < 1e-9)
return s.format(v*1e12) + " p" + u;
if (va < 1e-6)
return s.format(v*1e9) + " n" + u;
if (va < 1e-3)
return s.format(v*1e6) + " " + CirSim.muString + u;
if (va < 1)
return s.format(v*1e3) + " m" + u;
if (va < 1e3)
return s.format(v) + " " + u;
if (va < 1e6)
return s.format(v*1e-3) + " k" + u;
if (va < 1e9)
return s.format(v*1e-6) + " M" + u;
return s.format(v*1e-9) + " G" + u;
}
/*
static String getUnitText(double v, String u) {
double va = Math.abs(v);
if (va < 1e-14)
return "0 " + u;
if (va < 1e-9)
return showFormat.format(v*1e12) + " p" + u;
if (va < 1e-6)
return showFormat.format(v*1e9) + " n" + u;
if (va < 1e-3)
return showFormat.format(v*1e6) + " " + CirSim.muString + u;
if (va < 1)
return showFormat.format(v*1e3) + " m" + u;
if (va < 1e3)
return showFormat.format(v) + " " + u;
if (va < 1e6)
return showFormat.format(v*1e-3) + " k" + u;
if (va < 1e9)
return showFormat.format(v*1e-6) + " M" + u;
return showFormat.format(v*1e-9) + " G" + u;
}
static String getShortUnitText(double v, String u) {
double va = Math.abs(v);
if (va < 1e-13)
return null;
if (va < 1e-9)
return shortFormat.format(v*1e12) + "p" + u;
if (va < 1e-6)
return shortFormat.format(v*1e9) + "n" + u;
if (va < 1e-3)
return shortFormat.format(v*1e6) + CirSim.muString + u;
if (va < 1)
return shortFormat.format(v*1e3) + "m" + u;
if (va < 1e3)
return shortFormat.format(v) + u;
if (va < 1e6)
return shortFormat.format(v*1e-3) + "k" + u;
if (va < 1e9)
return shortFormat.format(v*1e-6) + "M" + u;
return shortFormat.format(v*1e-9) + "G" + u;
}*/
static String getCurrentText(double i) {
return getUnitText(i, "A");
}
static String getCurrentDText(double i) {
return getUnitText(Math.abs(i), "A");
}
void updateDotCount() {
curcount = updateDotCount(current, curcount);
}
double updateDotCount(double cur, double cc) {
if (sim.stoppedCheck.getState())
return cc;
double cadd = cur*currentMult;
/*if (cur != 0 && cadd <= .05 && cadd >= -.05)
cadd = (cadd < 0) ? -.05 : .05;*/
cadd %= 8;
/*if (cadd > 8)
cadd = 8;
if (cadd < -8)
cadd = -8;*/
return cc + cadd;
}
void doDots(Graphics g) {
updateDotCount();
if (sim.dragElm != this)
drawDots(g, point1, point2, curcount);
}
void doAdjust() {}
void setupAdjust() {}
void getInfo(String arr[]) {
}
int getBasicInfo(String arr[]) {
arr[1] = "I = " + getCurrentDText(getCurrent());
arr[2] = "Vd = " + getVoltageDText(getVoltageDiff());
return 3;
}
Color getVoltageColor(Graphics g, double volts) {
if (needsHighlight()) {
return (selectColor);
}
if (!sim.voltsCheckItem.getState()) {
if (!sim.powerCheckItem.getState()) // && !conductanceCheckItem.getState())
return(whiteColor);
return (g.lastColor);
}
int c = (int) ((volts+voltageRange)*(colorScaleCount-1)/
(voltageRange*2));
if (c < 0)
c = 0;
if (c >= colorScaleCount)
c = colorScaleCount-1;
return (colorScale[c]);
}
void setVoltageColor(Graphics g, double volts) {
g.setColor(getVoltageColor(g, volts));
}
void setPowerColor(Graphics g, boolean yellow) {
/*if (conductanceCheckItem.getState()) {
setConductanceColor(g, current/getVoltageDiff());
return;
}*/
if (!sim.powerCheckItem.getState())
return;
setPowerColor(g, getPower());
}
void setPowerColor(Graphics g, double w0) {
w0 *= powerMult;
//System.out.println(w);
double w = (w0 < 0) ? -w0 : w0;
if (w > 1)
w = 1;
int rg = 128+(int) (w*127);
int b = (int) (128*(1-w));
/*if (yellow)
g.setColor(new Color(rg, rg, b));
else */
if (w0 > 0)
g.setColor(new Color(rg, b, b));
else
g.setColor(new Color(b, rg, b));
}
void setConductanceColor(Graphics g, double w0) {
w0 *= powerMult;
//System.out.println(w);
double w = (w0 < 0) ? -w0 : w0;
if (w > 1)
w = 1;
int rg = (int) (w*255);
g.setColor(new Color(rg, rg, rg));
}
double getPower() { return getVoltageDiff()*current; }
double getScopeValue(int x) {
return (x == 1) ? getPower() : getVoltageDiff();
}
String getScopeUnits(int x) {
return (x == 1) ? "W" : "V";
}
public EditInfo getEditInfo(int n) { return null; }
public void setEditValue(int n, EditInfo ei) {}
boolean getConnection(int n1, int n2) { return true; }
boolean hasGroundConnection(int n1) { return false; }
boolean isWire() { return false; }
boolean canViewInScope() { return getPostCount() <= 2; }
boolean comparePair(int x1, int x2, int y1, int y2) {
return ((x1 == y1 && x2 == y2) || (x1 == y2 && x2 == y1));
}
boolean needsHighlight() { return iAmMouseElm || selected; }
boolean isSelected() { return selected; }
void setSelected(boolean x) { selected = x; }
void selectRect(Rectangle r) {
selected = r.intersects(boundingBox);
}
static int abs(int x) { return x < 0 ? -x : x; }
static int sign(int x) { return (x < 0) ? -1 : (x == 0) ? 0 : 1; }
static int min(int a, int b) { return (a < b) ? a : b; }
static int max(int a, int b) { return (a > b) ? a : b; }
static double distance(Point p1, Point p2) {
double x = p1.x-p2.x;
double y = p1.y-p2.y;
return Math.sqrt(x*x+y*y);
}
Rectangle getBoundingBox() { return boundingBox; }
boolean needsShortcut() { return getShortcut() > 0; }
int getShortcut() { return 0; }
boolean isGraphicElmt() { return false; }
void setMouseElm(boolean v) {iAmMouseElm=v;}
boolean isMouseElm() {return iAmMouseElm; }
}

View File

@@ -0,0 +1,29 @@
/*
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.util.Vector;
class CircuitNode {
int x, y;
Vector<CircuitNodeLink> links;
boolean internal;
CircuitNode() { links = new Vector<CircuitNodeLink>(); }
}

View File

@@ -0,0 +1,25 @@
/*
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;
class CircuitNodeLink {
int num;
CircuitElm elm;
}

View File

@@ -0,0 +1,32 @@
/*
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;
class ClockElm extends RailElm {
public ClockElm(int xx, int yy) {
super(xx, yy, WF_SQUARE);
maxVoltage = 2.5;
bias = 2.5;
frequency = 100;
flags |= FLAG_CLOCK;
}
Class getDumpClass() { return RailElm.class; }
int getShortcut() { return 0; }
}

View File

@@ -0,0 +1,102 @@
/*
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;
public class Color
{
public final static Color white = new Color(255, 255, 255);
public final static Color lightGray = new Color(192, 192, 192);
public final static Color gray = new Color(128, 128, 128);
public final static Color GRAY = new Color(128, 128, 128);
public final static Color dark_gray = new Color(64, 64, 64);
public final static Color darkGray = new Color(64, 64, 64);
public final static Color black = new Color(0, 0, 0);
public final static Color red = new Color(255, 0, 0);
public final static Color pink = new Color(255, 175, 175);
public final static Color orange = new Color(255, 200, 0);
public final static Color yellow = new Color(255, 255, 0);
public final static Color green = new Color(0, 255, 0);
public final static Color magenta = new Color(255, 0, 255);
public final static Color cyan = new Color(0, 255, 255);
public final static Color blue = new Color(0, 0, 255);
public static final Color NONE = new Color("");
private int r, g, b;
// only for special cases, like no color, or maybe named colors
private String colorText = null;
private Color (String colorText) {
this.colorText = colorText;
}
public Color (int r, int g, int b)
{
this.r = r;
this.g = g;
this.b = b;
}
public int getRed ()
{
return r;
}
public int getGreen ()
{
return g;
}
public int getBlue ()
{
return b;
}
public String getHexValue ()
{
if (colorText != null) {
return colorText;
}
return "#"
+ pad(Integer.toHexString(r))
+ pad(Integer.toHexString(g))
+ pad(Integer.toHexString(b));
}
private String pad (String in)
{
if (in.length() == 0) {
return "00";
}
if (in.length() == 1) {
return "0" + in;
}
return in;
}
public String toString ()
{
if (colorText != null) {
return colorText;
}
return "red=" + r + ", green=" + g + ", blue=" + b;
}
}

View File

@@ -0,0 +1,138 @@
/*
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 CounterElm extends ChipElm {
final int FLAG_ENABLE = 2;
boolean invertreset=false;
public CounterElm(int xx, int yy) { super(xx, yy); }
public CounterElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f, st);
if(st.hasMoreTokens())invertreset=new Boolean(st.nextToken()).booleanValue();
else invertreset=true;
pins[1].bubble = invertreset;
}
String dump() {
return super.dump()+" "+invertreset;
}
boolean needsBits() { return true; }
String getChipName() { return "Counter"; }
void setupPins() {
sizeX = 2;
sizeY = bits > 2 ? bits : 2;
pins = new Pin[getPostCount()];
pins[0] = new Pin(0, SIDE_W, "");
pins[0].clock = true;
pins[1] = new Pin(sizeY-1, SIDE_W, "R");
pins[1].bubble = invertreset;
int i;
for (i = 0; i != bits; i++) {
int ii = i+2;
pins[ii] = new Pin(i, SIDE_E, "Q" + (bits-i-1));
pins[ii].output = pins[ii].state = true;
}
if (hasEnable())
pins[bits+2] = new Pin(sizeY-2, SIDE_W, "En");
allocNodes();
}
int getPostCount() {
if (hasEnable())
return bits+3;
return bits+2;
}
public EditInfo getEditInfo(int n) {
if (n == 0) {
EditInfo ei = new EditInfo("", 0, -1, -1);
ei.checkbox = new Checkbox("Flip X", (flags & FLAG_FLIP_X) != 0);
return ei;
}
if (n == 1) {
EditInfo ei = new EditInfo("", 0, -1, -1);
ei.checkbox = new Checkbox("Flip Y", (flags & FLAG_FLIP_Y) != 0);
return ei;
}
if (n == 2) {
EditInfo ei = new EditInfo("", 0, -1, -1);
ei.checkbox = new Checkbox("Invert reset pin",invertreset);
return ei;
}
return null;
}
public void setEditValue(int n, EditInfo ei) {
if (n == 0) {
if (ei.checkbox.getState())
flags |= FLAG_FLIP_X;
else
flags &= ~FLAG_FLIP_X;
setPoints();
}
if (n == 1) {
if (ei.checkbox.getState())
flags |= FLAG_FLIP_Y;
else
flags &= ~FLAG_FLIP_Y;
setPoints();
}
if (n == 2) {
if (ei.checkbox.getState())
{
invertreset=true;
pins[1].bubble = true;
}
else
{
invertreset=false;
pins[1].bubble = false;
}
setPoints();
}
}
boolean hasEnable() { return (flags & FLAG_ENABLE) != 0; }
int getVoltageSourceCount() { return bits; }
void execute() {
boolean en = true;
if (hasEnable())
en = pins[bits+2].value;
if (pins[0].value && !lastClock && en) {
int i;
for (i = bits-1; i >= 0; i--) {
int ii = i+2;
if (!pins[ii].value) {
pins[ii].value = true;
break;
}
pins[ii].value = false;
}
}
if (!pins[1].value==invertreset) {
int i;
for (i = 0; i != bits; i++)
pins[i+2].value = false;
}
lastClock = pins[0].value;
}
int getDumpType() { return 164; }
}

View File

@@ -0,0 +1,94 @@
/*
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 CurrentElm extends CircuitElm {
double currentValue;
public CurrentElm(int xx, int yy) {
super(xx, yy);
currentValue = .01;
}
public CurrentElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f);
try {
currentValue = new Double(st.nextToken()).doubleValue();
} catch (Exception e) {
currentValue = .01;
}
}
String dump() {
return super.dump() + " " + currentValue;
}
int getDumpType() { return 'i'; }
Polygon arrow;
Point ashaft1, ashaft2, center;
void setPoints() {
super.setPoints();
calcLeads(26);
ashaft1 = interpPoint(lead1, lead2, .25);
ashaft2 = interpPoint(lead1, lead2, .6);
center = interpPoint(lead1, lead2, .5);
Point p2 = interpPoint(lead1, lead2, .75);
arrow = calcArrow(center, p2, 4, 4);
}
void draw(Graphics g) {
int cr = 12;
draw2Leads(g);
setVoltageColor(g, (volts[0]+volts[1])/2);
setPowerColor(g, false);
drawThickCircle(g, center.x, center.y, cr);
drawThickLine(g, ashaft1, ashaft2);
g.fillPolygon(arrow);
setBbox(point1, point2, cr);
doDots(g);
if (sim.showValuesCheckItem.getState()) {
String s = getShortUnitText(currentValue, "A");
if (dx == 0 || dy == 0)
drawValues(g, s, cr);
}
drawPosts(g);
}
void stamp() {
current = currentValue;
sim.stampCurrentSource(nodes[0], nodes[1], current);
}
public EditInfo getEditInfo(int n) {
if (n == 0)
return new EditInfo("Current (A)", currentValue, 0, .1);
return null;
}
public void setEditValue(int n, EditInfo ei) {
currentValue = ei.value;
}
void getInfo(String arr[]) {
arr[0] = "current source";
getBasicInfo(arr);
}
double getVoltageDiff() {
return volts[1] - volts[0];
}
}

View File

@@ -0,0 +1,59 @@
/*
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 DACElm extends ChipElm {
public DACElm(int xx, int yy) { super(xx, yy); }
public DACElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f, st);
}
String getChipName() { return "DAC"; }
boolean needsBits() { return true; }
void setupPins() {
sizeX = 2;
sizeY = bits > 2 ? bits : 2;
pins = new Pin[getPostCount()];
int i;
for (i = 0; i != bits; i++)
pins[i] = new Pin(bits-1-i, SIDE_W, "D" + i);
pins[bits] = new Pin(0, SIDE_E, "O");
pins[bits].output = true;
pins[bits+1] = new Pin(sizeY-1, SIDE_E, "V+");
allocNodes();
}
void doStep() {
int ival = 0;
int i;
for (i = 0; i != bits; i++)
if (volts[i] > 2.5)
ival |= 1<<i;
int ivalmax = (1<<bits)-1;
double v = ival*volts[bits+1]/ivalmax;
sim.updateVoltageSource(0, nodes[bits], pins[bits].voltSource, v);
}
int getVoltageSourceCount() { return 1; }
int getPostCount() { return bits+2; }
int getDumpType() { return 166; }
}

View File

@@ -0,0 +1,27 @@
/*
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;
class DCVoltageElm extends VoltageElm {
public DCVoltageElm(int xx, int yy) { super(xx, yy, WF_DC); }
Class getDumpClass() { return VoltageElm.class; }
int getShortcut() { return 'v'; }
}

View File

@@ -0,0 +1,118 @@
/*
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 DFlipFlopElm extends ChipElm {
final int FLAG_RESET = 2;
final int FLAG_SET = 4;
boolean hasReset() { return (flags & FLAG_RESET) != 0 || hasSet(); }
boolean hasSet() { return (flags & FLAG_SET) != 0; }
public DFlipFlopElm(int xx, int yy) { super(xx, yy); }
public DFlipFlopElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f, st);
pins[2].value = !pins[1].value;
}
String getChipName() { return "D flip-flop"; }
void setupPins() {
sizeX = 2;
sizeY = 3;
pins = new Pin[getPostCount()];
pins[0] = new Pin(0, SIDE_W, "D");
pins[1] = new Pin(0, SIDE_E, "Q");
pins[1].output = pins[1].state = true;
pins[2] = new Pin(hasSet()?1:2, SIDE_E, "Q");
pins[2].output = true;
pins[2].lineOver = true;
pins[3] = new Pin(1, SIDE_W, "");
pins[3].clock = true;
if (!hasSet()) {
if (hasReset())
pins[4] = new Pin(2, SIDE_W, "R");
} else {
pins[5] = new Pin(2, SIDE_W, "S");
pins[4] = new Pin(2, SIDE_E, "R");
}
}
int getPostCount() {
return 4 + (hasReset() ? 1 : 0) + (hasSet() ? 1 : 0);
}
int getVoltageSourceCount() { return 2; }
void reset() {
super.reset();
volts[2] = 5;
pins[2].value = true;
}
void execute() {
if (pins[3].value && !lastClock) {
pins[1].value = pins[0].value;
pins[2].value = !pins[0].value;
}
if(hasSet() && pins[5].value)
{
pins[1].value = true;
pins[2].value = false;
}
if(hasReset() && pins[4].value)
{
pins[1].value = false;
pins[2].value = true;
}
lastClock = pins[3].value;
}
int getDumpType() { return 155; }
public EditInfo getEditInfo(int n) {
if (n == 2) {
EditInfo ei = new EditInfo("", 0, -1, -1);
ei.checkbox = new Checkbox("Reset Pin", hasReset());
return ei;
}
if (n == 3) {
EditInfo ei = new EditInfo("", 0, -1, -1);
ei.checkbox = new Checkbox("Set Pin", hasSet());
return ei;
}
return super.getEditInfo(n);
}
public void setEditValue(int n, EditInfo ei) {
if (n == 2) {
if (ei.checkbox.getState())
flags |= FLAG_RESET;
else
flags &= ~FLAG_RESET|FLAG_SET;
setupPins();
allocNodes();
setPoints();
}
if (n == 3) {
if (ei.checkbox.getState())
flags |= FLAG_SET;
else
flags &= ~FLAG_SET;
setupPins();
allocNodes();
setPoints();
}
super.setEditValue(n, ei);
}
}

View File

@@ -0,0 +1,73 @@
/*
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;
// contributed by Edward Calver
class DeMultiplexerElm extends ChipElm {
boolean hasReset() {return false;}
public DeMultiplexerElm(int xx, int yy) { super(xx, yy); }
public DeMultiplexerElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f, st);
}
String getChipName() { return "Multiplexer"; }
void setupPins() {
sizeX = 3;
sizeY = 5;
pins = new Pin[getPostCount()];
pins[0] = new Pin(0, SIDE_E, "Q0");
pins[0].output=true;
pins[1] = new Pin(1, SIDE_E, "Q1");
pins[1].output=true;
pins[2] = new Pin(2, SIDE_E, "Q2");
pins[2].output=true;
pins[3] = new Pin(3, SIDE_E, "Q3");
pins[3].output=true;
pins[4] = new Pin(0, SIDE_S, "S0");
pins[5] = new Pin(1, SIDE_S, "S1");
pins[6] = new Pin(0, SIDE_W, "Q");
}
int getPostCount() {
return 7;
}
int getVoltageSourceCount() {return 4;}
void execute() {
int selectedvalue=0;
if(pins[4].value)selectedvalue++;
if(pins[5].value)selectedvalue+=2;
for(int i=0;i<4;i++)pins[i].value=false;
pins[selectedvalue].value=pins[6].value;
}
int getDumpType() { return 185; }
}

View File

@@ -0,0 +1,70 @@
/*
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 DecadeElm extends ChipElm {
public DecadeElm(int xx, int yy) { super(xx, yy); }
public DecadeElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f, st);
}
String getChipName() { return "decade counter"; }
boolean needsBits() { return true; }
void setupPins() {
sizeX = bits > 2 ? bits : 2;
sizeY = 2;
pins = new Pin[getPostCount()];
pins[0] = new Pin(1, SIDE_W, "");
pins[0].clock = true;
pins[1] = new Pin(sizeX-1, SIDE_S, "R");
pins[1].bubble = true;
int i;
for (i = 0; i != bits; i++) {
int ii = i+2;
pins[ii] = new Pin(i, SIDE_N, "Q" + i);
pins[ii].output = pins[ii].state = true;
}
allocNodes();
}
int getPostCount() { return bits+2; }
int getVoltageSourceCount() { return bits; }
void execute() {
int i;
if (pins[0].value && !lastClock) {
for (i = 0; i != bits; i++)
if (pins[i+2].value)
break;
if (i < bits)
pins[i++ +2].value = false;
i %= bits;
pins[i+2].value = true;
}
if (!pins[1].value) {
for (i = 1; i != bits; i++)
pins[i+2].value = false;
pins[2].value = true;
}
lastClock = pins[0].value;
}
int getDumpType() { return 163; }
}

View File

@@ -0,0 +1,130 @@
/*
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;
// stub implementation of DiacElm, based on SparkGapElm
// FIXME need to add DiacElm.java to srclist
// FIXME need to uncomment DiacElm line from CirSim.java
//import java.awt.*;
//import java.util.StringTokenizer;
class DiacElm extends CircuitElm {
double onresistance, offresistance, breakdown, holdcurrent;
boolean state;
public DiacElm(int xx, int yy) {
super(xx, yy);
// FIXME need to adjust defaults to make sense for diac
offresistance = 1e9;
onresistance = 1e3;
breakdown = 1e3;
holdcurrent = 0.001;
state = false;
}
public DiacElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f);
onresistance = new Double(st.nextToken()).doubleValue();
offresistance = new Double(st.nextToken()).doubleValue();
breakdown = new Double(st.nextToken()).doubleValue();
holdcurrent = new Double(st.nextToken()).doubleValue();
}
boolean nonLinear() {return true;}
int getDumpType() { return 203; }
String dump() {
return super.dump() + " " + onresistance + " " + offresistance + " "
+ breakdown + " " + holdcurrent;
}
Point ps3, ps4;
void setPoints() {
super.setPoints();
calcLeads(32);
ps3 = new Point();
ps4 = new Point();
}
void draw(Graphics g) {
// FIXME need to draw Diac
int i;
double v1 = volts[0];
double v2 = volts[1];
setBbox(point1, point2, 6);
draw2Leads(g);
setPowerColor(g, true);
doDots(g);
drawPosts(g);
}
void calculateCurrent() {
double vd = volts[0] - volts[1];
if(state)
current = vd/onresistance;
else
current = vd/offresistance;
}
void startIteration() {
double vd = volts[0] - volts[1];
if(Math.abs(current) < holdcurrent) state = false;
if(Math.abs(vd) > breakdown) state = true;
//System.out.print(this + " res current set to " + current + "\n");
}
void doStep() {
if(state)
sim.stampResistor(nodes[0], nodes[1], onresistance);
else
sim.stampResistor(nodes[0], nodes[1], offresistance);
}
void stamp() {
sim.stampNonLinear(nodes[0]);
sim.stampNonLinear(nodes[1]);
}
void getInfo(String arr[]) {
// FIXME
arr[0] = "spark gap";
getBasicInfo(arr);
arr[3] = state ? "on" : "off";
arr[4] = "Ron = " + getUnitText(onresistance, sim.ohmString);
arr[5] = "Roff = " + getUnitText(offresistance, sim.ohmString);
arr[6] = "Vbrkdn = " + getUnitText(breakdown, "V");
arr[7] = "Ihold = " + getUnitText(holdcurrent, "A");
}
public EditInfo getEditInfo(int n) {
if (n == 0)
return new EditInfo("On resistance (ohms)", onresistance, 0, 0);
if (n == 1)
return new EditInfo("Off resistance (ohms)", offresistance, 0, 0);
if (n == 2)
return new EditInfo("Breakdown voltage (volts)", breakdown, 0, 0);
if (n == 3)
return new EditInfo("Hold current (amps)", holdcurrent, 0, 0);
return null;
}
public void setEditValue(int n, EditInfo ei) {
if (ei.value > 0 && n == 0)
onresistance = ei.value;
if (ei.value > 0 && n == 1)
offresistance = ei.value;
if (ei.value > 0 && n == 2)
breakdown = ei.value;
if (ei.value > 0 && n == 3)
holdcurrent = ei.value;
}
}

View File

@@ -0,0 +1,168 @@
/*
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;
class Diode {
int nodes[];
CirSim sim;
Diode(CirSim s) {
sim = s;
nodes = new int[2];
}
void setup(double fw, double zv) {
fwdrop = fw;
zvoltage = zv;
vdcoef = Math.log(1/leakage + 1)/fwdrop;
vt = 1/vdcoef;
// critical voltage for limiting; current is vt/sqrt(2) at
// this voltage
vcrit = vt * Math.log(vt/(Math.sqrt(2)*leakage));
if (zvoltage == 0)
zoffset = 0;
else {
// calculate offset which will give us 5mA at zvoltage
double i = -.005;
zoffset = zvoltage-Math.log(-(1+i/leakage))/vdcoef;
}
}
void reset() {
lastvoltdiff = 0;
}
public double leakage = 1e-14; // was 1e-9;
double vt, vdcoef, fwdrop, zvoltage, zoffset;
double lastvoltdiff;
double vcrit;
double limitStep(double vnew, double vold) {
double arg;
double oo = vnew;
// check new voltage; has current changed by factor of e^2?
if (vnew > vcrit && Math.abs(vnew - vold) > (vt + vt)) {
if(vold > 0) {
arg = 1 + (vnew - vold) / vt;
if(arg > 0) {
// adjust vnew so that the current is the same
// as in linearized model from previous iteration.
// current at vnew = old current * arg
vnew = vold + vt * Math.log(arg);
// current at v0 = 1uA
double v0 = Math.log(1e-6/leakage)*vt;
vnew = Math.max(v0, vnew);
} else {
vnew = vcrit;
}
} else {
// adjust vnew so that the current is the same
// as in linearized model from previous iteration.
// (1/vt = slope of load line)
vnew = vt *Math.log(vnew/vt);
}
sim.converged = false;
//System.out.println(vnew + " " + oo + " " + vold);
} else if (vnew < 0 && zoffset != 0) {
// for Zener breakdown, use the same logic but translate the values
vnew = -vnew - zoffset;
vold = -vold - zoffset;
if (vnew > vcrit && Math.abs(vnew - vold) > (vt + vt)) {
if(vold > 0) {
arg = 1 + (vnew - vold) / vt;
if(arg > 0) {
vnew = vold + vt * Math.log(arg);
double v0 = Math.log(1e-6/leakage)*vt;
vnew = Math.max(v0, vnew);
//System.out.println(oo + " " + vnew);
} else {
vnew = vcrit;
}
} else {
vnew = vt *Math.log(vnew/vt);
}
sim.converged = false;
}
vnew = -(vnew+zoffset);
}
return vnew;
}
void stamp(int n0, int n1) {
nodes[0] = n0;
nodes[1] = n1;
sim.stampNonLinear(nodes[0]);
sim.stampNonLinear(nodes[1]);
}
void doStep(double voltdiff) {
// used to have .1 here, but needed .01 for peak detector
if (Math.abs(voltdiff-lastvoltdiff) > .01)
sim.converged = false;
voltdiff = limitStep(voltdiff, lastvoltdiff);
lastvoltdiff = voltdiff;
if (voltdiff >= 0 || zvoltage == 0) {
// regular diode or forward-biased zener
double eval = Math.exp(voltdiff*vdcoef);
// make diode linear with negative voltages; aids convergence
if (voltdiff < 0)
eval = 1;
double geq = vdcoef*leakage*eval;
double nc = (eval-1)*leakage - geq*voltdiff;
sim.stampConductance(nodes[0], nodes[1], geq);
sim.stampCurrentSource(nodes[0], nodes[1], nc);
} else {
// Zener diode
/*
* I(Vd) = Is * (exp[Vd*C] - exp[(-Vd-Vz)*C] - 1 )
*
* geq is I'(Vd)
* nc is I(Vd) + I'(Vd)*(-Vd)
*/
double geq = leakage*vdcoef* (
Math.exp(voltdiff*vdcoef) + Math.exp((-voltdiff-zoffset)*vdcoef)
);
double nc = leakage* (
Math.exp(voltdiff*vdcoef)
- Math.exp((-voltdiff-zoffset)*vdcoef)
- 1
) + geq*(-voltdiff);
sim.stampConductance(nodes[0], nodes[1], geq);
sim.stampCurrentSource(nodes[0], nodes[1], nc);
}
}
double calculateCurrent(double voltdiff) {
if (voltdiff >= 0 || zvoltage == 0)
return leakage*(Math.exp(voltdiff*vdcoef)-1);
return leakage* (
Math.exp(voltdiff*vdcoef)
- Math.exp((-voltdiff-zoffset)*vdcoef)
- 1
);
}
}

View File

@@ -0,0 +1,132 @@
/*
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 DiodeElm extends CircuitElm {
Diode diode;
static final int FLAG_FWDROP = 1;
final double defaultdrop = .805904783;
double fwdrop, zvoltage;
public DiodeElm(int xx, int yy) {
super(xx, yy);
diode = new Diode(sim);
fwdrop = defaultdrop;
zvoltage = 0;
setup();
}
public DiodeElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f);
diode = new Diode(sim);
fwdrop = defaultdrop;
zvoltage = 0;
if ((f & FLAG_FWDROP) > 0) {
try {
fwdrop = new Double(st.nextToken()).doubleValue();
} catch (Exception e) {
}
}
setup();
}
boolean nonLinear() { return true; }
void setup() {
diode.setup(fwdrop, zvoltage);
}
int getDumpType() { return 'd'; }
String dump() {
flags |= FLAG_FWDROP;
return super.dump() + " " + fwdrop;
}
final int hs = 8;
Polygon poly;
Point cathode[];
void setPoints() {
super.setPoints();
calcLeads(16);
cathode = newPointArray(2);
Point pa[] = newPointArray(2);
interpPoint2(lead1, lead2, pa[0], pa[1], 0, hs);
interpPoint2(lead1, lead2, cathode[0], cathode[1], 1, hs);
poly = createPolygon(pa[0], pa[1], lead2);
}
void draw(Graphics g) {
drawDiode(g);
doDots(g);
drawPosts(g);
}
void reset() {
diode.reset();
volts[0] = volts[1] = curcount = 0;
}
void drawDiode(Graphics g) {
setBbox(point1, point2, hs);
double v1 = volts[0];
double v2 = volts[1];
draw2Leads(g);
// draw arrow thingy
setPowerColor(g, true);
setVoltageColor(g, v1);
g.fillPolygon(poly);
// draw thing arrow is pointing to
setVoltageColor(g, v2);
drawThickLine(g, cathode[0], cathode[1]);
}
void stamp() { diode.stamp(nodes[0], nodes[1]); }
void doStep() {
diode.doStep(volts[0]-volts[1]);
}
void calculateCurrent() {
current = diode.calculateCurrent(volts[0]-volts[1]);
}
void getInfo(String arr[]) {
arr[0] = "diode";
arr[1] = "I = " + getCurrentText(getCurrent());
arr[2] = "Vd = " + getVoltageText(getVoltageDiff());
arr[3] = "P = " + getUnitText(getPower(), "W");
arr[4] = "Vf = " + getVoltageText(fwdrop);
}
public EditInfo getEditInfo(int n) {
if (n == 0)
return new EditInfo("Fwd Voltage @ 1A", fwdrop, 10, 1000);
return null;
}
public void setEditValue(int n, EditInfo ei) {
fwdrop = ei.value;
setup();
}
int getShortcut() { return 'd'; }
}

View File

@@ -0,0 +1,327 @@
/*
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 com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.GwtEvent;
import com.google.gwt.user.client.ui.Widget;
import java.util.Iterator;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
//import java.awt.*;
//import java.awt.event.*;
//import java.text.NumberFormat;
//import java.text.DecimalFormat;
interface Editable {
EditInfo getEditInfo(int n);
void setEditValue(int n, EditInfo ei);
}
// class EditDialog extends Dialog implements AdjustmentListener, ActionListener, ItemListener {
class EditDialog extends DialogBox {
Editable elm;
CirSim cframe;
Button applyButton, okButton, cancelButton;
EditInfo einfos[];
int einfocount;
final int barmax = 1000;
VerticalPanel vp;
HorizontalPanel hp;
NumberFormat noCommaFormat;
EditDialog(Editable ce, CirSim f) {
// super(f, "Edit Component", false);
super(); // Do we need this?
setText("Edit Component");
cframe = f;
elm = ce;
// setLayout(new EditDialogLayout());
vp=new VerticalPanel();
setWidget(vp);
einfos = new EditInfo[10];
noCommaFormat=NumberFormat.getFormat("####.##########");
// noCommaFormat = DecimalFormat.getInstance();
// noCommaFormat.setMaximumFractionDigits(10);
// noCommaFormat.setGroupingUsed(false);
hp=new HorizontalPanel();
hp.setWidth("100%");
hp.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
hp.setStyleName("topSpace");
vp.add(hp);
hp.add(applyButton = new Button("Apply"));
applyButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
apply();
}
});
hp.add(okButton = new Button("OK"));
okButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
apply();
closeDialog();
}
});
hp.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
hp.add(cancelButton = new Button("Cancel"));
cancelButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
closeDialog();
}
});
buildDialog();
this.center();
}
void buildDialog() {
int i;
int idx;
Label l;
for (i = 0; ; i++) {
einfos[i] = elm.getEditInfo(i);
if (einfos[i] == null)
break;
EditInfo ei = einfos[i];
idx = vp.getWidgetIndex(hp);
vp.insert(l = new Label(ei.name),idx);
if (i!=0)
l.setStyleName("topSpace");
idx = vp.getWidgetIndex(hp);
if (ei.choice != null) {
vp.insert(ei.choice,idx);
ei.choice.addChangeHandler( new ChangeHandler() {
public void onChange(ChangeEvent e){
itemStateChanged(e);
}
});
// ei.choice.addItemListener(this);
} else if (ei.checkbox != null) {
vp.insert(ei.checkbox,idx);
ei.checkbox.addValueChangeHandler( new ValueChangeHandler<Boolean>() {
public void onValueChange(ValueChangeEvent<Boolean> e){
itemStateChanged(e);
}
});
// ei.checkbox.addItemListener(this);
} else {
vp.insert(ei.textf =
// new TextBox(unitString(ei), 10));
new TextBox(), idx);
if (ei.text != null)
ei.textf.setText(ei.text);
// ei.textf.addActionListener(this);
if (ei.text == null) {
// add(ei.bar = new Scrollbar(Scrollbar.HORIZONTAL,
// 50, 10, 0, barmax+2));
// setBar(ei);
// ei.bar.addAdjustmentListener(this);
ei.textf.setText(unitString(ei));
}
}
}
einfocount = i;
}
String unitString(EditInfo ei) {
double v = ei.value;
double va = Math.abs(v);
if (ei.dimensionless)
return noCommaFormat.format(v);
if (v == 0) return "0";
if (va < 1e-9)
return noCommaFormat.format(v*1e12) + "p";
if (va < 1e-6)
return noCommaFormat.format(v*1e9) + "n";
if (va < 1e-3)
return noCommaFormat.format(v*1e6) + "u";
if (va < 1 && !ei.forceLargeM)
return noCommaFormat.format(v*1e3) + "m";
if (va < 1e3)
return noCommaFormat.format(v);
if (va < 1e6)
return noCommaFormat.format(v*1e-3) + "k";
if (va < 1e9)
return noCommaFormat.format(v*1e-6) + "M";
return noCommaFormat.format(v*1e-9) + "G";
}
double parseUnits(EditInfo ei) throws java.text.ParseException {
String s = ei.textf.getText();
s = s.trim();
// rewrite shorthand (eg "2k2") in to normal format (eg 2.2k) using regex
s=s.replaceAll("([0-9]+)([pPnNuUmMkKgG])([0-9]+)", "$1.$3$2");
int len = s.length();
char uc = s.charAt(len-1);
double mult = 1;
switch (uc) {
case 'p': case 'P': mult = 1e-12; break;
case 'n': case 'N': mult = 1e-9; break;
case 'u': case 'U': mult = 1e-6; break;
// for ohm values, we assume mega for lowercase m, otherwise milli
case 'm': mult = (ei.forceLargeM) ? 1e6 : 1e-3; break;
case 'k': case 'K': mult = 1e3; break;
case 'M': mult = 1e6; break;
case 'G': case 'g': mult = 1e9; break;
}
if (mult != 1)
s = s.substring(0, len-1).trim();
return noCommaFormat.parse(s) * mult;
}
void apply() {
int i;
for (i = 0; i != einfocount; i++) {
EditInfo ei = einfos[i];
// if (ei.textf == null)
// continue;
// if (ei.text == null) {
if (ei.textf!=null && ei.text==null) {
try {
double d = parseUnits(ei);
ei.value = d;
} catch (Exception ex) { /* ignored */ }
}
elm.setEditValue(i, ei);
// if (ei.text == null)
// setBar(ei);
}
cframe.needAnalyze();
}
// public void actionPerformed(ActionEvent e) {
// int i;
// Object src = e.getSource();
// for (i = 0; i != einfocount; i++) {
// EditInfo ei = einfos[i];
// if (src == ei.textf) {
// if (ei.text == null) {
// try {
// double d = parseUnits(ei);
// ei.value = d;
// } catch (Exception ex) { /* ignored */ }
// }
// elm.setEditValue(i, ei);
// if (ei.text == null)
// setBar(ei);
// cframe.needAnalyze();
// }
// }
// if (e.getSource() == okButton) {
// apply();
// closeDialog();
// }
// if (e.getSource() == applyButton)
// apply();
// }
//
// public void adjustmentValueChanged(AdjustmentEvent e) {
// Object src = e.getSource();
// int i;
// for (i = 0; i != einfocount; i++) {
// EditInfo ei = einfos[i];
// if (ei.bar == src) {
// double v = ei.bar.getValue() / 1000.;
// if (v < 0)
// v = 0;
// if (v > 1)
// v = 1;
// ei.value = (ei.maxval-ei.minval)*v + ei.minval;
// /*if (ei.maxval-ei.minval > 100)
// ei.value = Math.round(ei.value);
// else
// ei.value = Math.round(ei.value*100)/100.;*/
// ei.value = Math.round(ei.value/ei.minval)*ei.minval;
// elm.setEditValue(i, ei);
// ei.textf.setText(unitString(ei));
// cframe.needAnalyze();
// }
// }
// }
//
public void itemStateChanged(GwtEvent e) {
Object src = e.getSource();
int i;
boolean changed = false;
for (i = 0; i != einfocount; i++) {
EditInfo ei = einfos[i];
if (ei.choice == src || ei.checkbox == src) {
elm.setEditValue(i, ei);
if (ei.newDialog)
changed = true;
cframe.needAnalyze();
}
}
if (changed) {
// apply();
// setVisible(false);
// cframe.editDialog = new EditDialog(elm, cframe);
// cframe.editDialog.show();
clearDialog();
buildDialog();
}
}
public void clearDialog() {
// Iterator<Widget> wa = vp.iterator();
// while (wa.hasNext()){
// Widget w=wa.next();
// if (w!=hp)
// vp.remove(w);
// }
while (vp.getWidget(0)!=hp)
vp.remove(0);
}
//
// public boolean handleEvent(Event ev) {
// if (ev.id == Event.WINDOW_DESTROY) {
// closeDialog();
// return true;
// }
// return super.handleEvent(ev);
// }
//
// void setBar(EditInfo ei) {
// int x = (int) (barmax*(ei.value-ei.minval)/(ei.maxval-ei.minval));
// ei.bar.setValue(x);
// }
//
protected void closeDialog()
{
EditDialog.this.hide();
cframe.editDialog = null;
}
}

View File

@@ -0,0 +1,55 @@
/*
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 com.google.gwt.user.client.ui.TextBox;
//import java.awt.*;
class EditInfo {
EditInfo(String n, double val, double mn, double mx) {
name = n;
value = val;
if (mn == 0 && mx == 0 && val > 0) {
minval = 1e10;
while (minval > val/100)
minval /= 10.;
maxval = minval * 1000;
} else {
minval = mn;
maxval = mx;
}
forceLargeM = name.indexOf("(ohms)") > 0 ||
name.indexOf("(Hz)") > 0;
dimensionless = false;
}
EditInfo setDimensionless() { dimensionless = true; return this; }
String name, text;
double value, minval, maxval;
TextBox textf;
// Scrollbar bar;
Choice choice;
Checkbox checkbox;
boolean newDialog;
boolean forceLargeM;
boolean dimensionless;
}

View File

@@ -0,0 +1,43 @@
/*
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;
class EditOptions implements Editable {
CirSim sim;
public EditOptions(CirSim s) { sim = s; }
public EditInfo getEditInfo(int n) {
if (n == 0)
return new EditInfo("Time step size (s)", sim.timeStep, 0, 0);
if (n == 1)
return new EditInfo("Range for voltage color (V)",
CircuitElm.voltageRange, 0, 0);
return null;
}
public void setEditValue(int n, EditInfo ei) {
if (n == 0 && ei.value > 0)
sim.timeStep = ei.value;
if (n == 1 && ei.value > 0)
CircuitElm.voltageRange = ei.value;
}
};

View File

@@ -0,0 +1,77 @@
/*
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 com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.RichTextArea;
public class ExportAsLocalFileDialog extends DialogBox {
VerticalPanel vp;
static public final native boolean downloadIsSupported()
/*-{
return !!(("download" in $doc.createElement("a")));
}-*/;
static public final native String getBlobUrl(String data)
/*-{
var datain=[""];
datain[0]=data;
var blob=new Blob(datain, {type: 'text/plain' } );
var url = URL.createObjectURL(blob);
return url;
}-*/;
public ExportAsLocalFileDialog(String data) {
super();
Button okButton;
Anchor a;
String url;
vp=new VerticalPanel();
setWidget(vp);
setText("Export as Local File");
vp.add(new Label("Click on the link below to save your circuit"));
url=getBlobUrl(data);
a=new Anchor("my circuit.txt", url);
a.getElement().setAttribute("Download", "my circuit.txt");
vp.add(a);
vp.add(okButton = new Button("OK"));
okButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
closeDialog();
}
});
this.center();
}
protected void closeDialog()
{
this.hide();
}
}

View File

@@ -0,0 +1,73 @@
/*
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 com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.RichTextArea;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.safehtml.shared.SafeHtml;
public class ExportAsTextDialog extends DialogBox {
VerticalPanel vp;
public ExportAsTextDialog( String s) {
super();
// RichTextArea tb;
TextArea ta;
Button okButton;
Label la2;
SafeHtml html;
vp=new VerticalPanel();
setWidget(vp);
setText("Export as Text");
vp.add(new Label("Text file for this circuit is..."));
// vp.add(tb = new RichTextArea());
// html=SafeHtmlUtils.fromString(s);
// html=SafeHtmlUtils.fromTrustedString(html.asString().replace("\n", "<BR>"));
// tb.setHTML(html);
vp.add(ta= new TextArea());
ta.setWidth("300px");
ta.setHeight("200px");
ta.setText(s);
vp.add(la2 = new Label("To save this file select it all (eg click in text and type control-A) and copy to your clipboard (eg control-C) before pasting to an empty text file (eg on Windows Notepad) and saving as a new file.", true));
la2.setWidth("300px");
vp.add(okButton = new Button("OK"));
okButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
closeDialog();
}
});
this.center();
}
protected void closeDialog()
{
this.hide();
}
}

View File

@@ -0,0 +1,69 @@
/*
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 com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.RichTextArea;
public class ExportAsUrlDialog extends DialogBox {
VerticalPanel vp;
public ExportAsUrlDialog( String s) {
super();
//TextBox tb;
RichTextArea tb;
Button okButton;
Label la1, la2;
vp=new VerticalPanel();
setWidget(vp);
setText("Export as URL");
vp.add(new Label("URL for this circuit is..."));
if (s.length()>2000) {
vp.add( la1= new Label("Warning: this URL is longer than 2000 characters and may not work in some browsers.", true));
la1.setWidth("300px");
}
vp.add(tb = new RichTextArea());
tb.setText(s);
// tb.setMaxLength(s.length());
// tb.setVisibleLength(s.length());
vp.add(la2 = new Label("To save this URL select it all (eg click in text and type control-A) and copy to your clipboard (eg control-C) before pasting to a suitable place.", true));
la2.setWidth("300px");
vp.add(okButton = new Button("OK"));
okButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
closeDialog();
}
});
this.center();
}
protected void closeDialog()
{
this.hide();
}
}

View File

@@ -0,0 +1,159 @@
/*
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;
// contributed by Edward Calver
class FMElm extends CircuitElm {
static final int FLAG_COS = 2;
double carrierfreq,signalfreq, maxVoltage, freqTimeZero,deviation;
double lasttime=0;
double funcx=0;
public FMElm(int xx, int yy) {
super(xx, yy);
deviation=200;
maxVoltage = 5;
carrierfreq =800;
signalfreq=40;
reset();
}
public FMElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f);
carrierfreq = new Double(st.nextToken()).doubleValue();
signalfreq= new Double(st.nextToken()).doubleValue();
maxVoltage = new Double(st.nextToken()).doubleValue();
deviation = new Double(st.nextToken()).doubleValue();
if ((flags & FLAG_COS) != 0) {
flags &= ~FLAG_COS;
}
reset();
}
int getDumpType() { return 201; }
String dump() {
return super.dump() + " " +carrierfreq+" " + signalfreq + " " +maxVoltage + " " +deviation;
}
/*void setCurrent(double c) {
current = c;
System.out.print("v current set to " + c + "\n");
}*/
void reset() {
freqTimeZero = 0;
curcount = 0;
}
int getPostCount() { return 1; }
void stamp() {
sim.stampVoltageSource(0, nodes[0], voltSource);
}
void doStep() {
sim.updateVoltageSource(0, nodes[0], voltSource, getVoltage());
}
double getVoltage() {
double deltaT=sim.t-lasttime;
lasttime=sim.t;
double signalamplitude=Math.sin((2*pi*(sim.t-freqTimeZero))*signalfreq);
funcx+=deltaT*(carrierfreq+(signalamplitude*deviation));
double w = 2*pi*funcx;
return Math.sin(w)*maxVoltage;
}
final int circleSize = 17;
void draw(Graphics g) {
setBbox(point1, point2, circleSize);
setVoltageColor(g, volts[0]);
drawThickLine(g, point1, lead1);
Font f = new Font("SansSerif", 0, 12);
g.setFont(f);
g.setColor(needsHighlight() ? selectColor : whiteColor);
setPowerColor(g, false);
double v = getVoltage();
String s = "FM";
drawCenteredText(g, s, x2, y2, true);
drawWaveform(g, point2);
drawPosts(g);
curcount = updateDotCount(-current, curcount);
if (sim.dragElm != this)
drawDots(g, point1, lead1, curcount);
}
void drawWaveform(Graphics g, Point center) {
g.setColor(needsHighlight() ? selectColor : Color.gray);
setPowerColor(g, false);
int xc = center.x; int yc = center.y;
drawThickCircle(g, xc, yc, circleSize);
int wl = 8;
adjustBbox(xc-circleSize, yc-circleSize,
xc+circleSize, yc+circleSize);
}
void setPoints() {
super.setPoints();
lead1 = interpPoint(point1, point2, 1-circleSize/dn);
}
double getVoltageDiff() { return volts[0]; }
boolean hasGroundConnection(int n1) { return true; }
int getVoltageSourceCount() {
return 1;
}
double getPower() { return -getVoltageDiff()*current; }
void getInfo(String arr[]) {
arr[0] = "FM Source";
arr[1] = "I = " + getCurrentText(getCurrent());
arr[2] = "V = " +
getVoltageText(getVoltageDiff());
arr[3] = "cf = " + getUnitText(carrierfreq, "Hz");
arr[4] = "sf = " + getUnitText(signalfreq, "Hz");
arr[5]= "dev =" + getUnitText(deviation, "Hz");
arr[6] = "Vmax = " + getVoltageText(maxVoltage);
}
public EditInfo getEditInfo(int n) {
if (n == 0)
return new EditInfo("Max Voltage", maxVoltage, -20, 20);
if (n == 1)
return new EditInfo("Carrier Frequency (Hz)", carrierfreq, 4, 500);
if (n == 2)
return new EditInfo("Signal Frequency (Hz)", signalfreq, 4, 500);
if (n == 3)
return new EditInfo("Deviation (Hz)", deviation, 4, 500);
return null;
}
public void setEditValue(int n, EditInfo ei) {
if (n == 0)
maxVoltage = ei.value;
if (n == 1)
carrierfreq = ei.value;
if (n == 2)
signalfreq=ei.value;
if (n == 3)
deviation=ei.value;
}
}

View File

@@ -0,0 +1,39 @@
/*
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;
class Font {
static final int BOLD=1;
String fontname;
int size;
public Font(String name, int style, int size){
String styleStr="normal ";
if (name=="SansSerif")
name="sans-serif";
if ((style & BOLD) !=0)
styleStr="bold ";
fontname=styleStr+size+"px "+name;
this.size=size;
}
}

View File

@@ -0,0 +1,61 @@
/*
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 FullAdderElm extends ChipElm {
boolean hasReset() {return false;}
public FullAdderElm(int xx, int yy) { super(xx, yy); }
public FullAdderElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f, st);
}
String getChipName() { return "Full Adder"; }
void setupPins() {
sizeX=2;
sizeY=3;
pins=new Pin[getPostCount()];
pins[0] = new Pin(2, SIDE_E, "S");
pins[0].output=true;
pins[1] = new Pin(0, SIDE_E, "C");
pins[1].output=true;
pins[2] = new Pin(0, SIDE_W, "A");
pins[3] = new Pin(1, SIDE_W, "B");
pins[4] = new Pin(2, SIDE_W, "Cin");
}
int getPostCount() {
return 5;
}
int getVoltageSourceCount() {return 2;}
void execute() {
pins[0].value=(pins[2].value^pins[3].value)^pins[4].value;
pins[1].value=(pins[2].value&&pins[3].value)||(pins[2].value&&pins[4].value)||
(pins[3].value&&pins[4].value);
}
int getDumpType() { return 196; }
}

View File

@@ -0,0 +1,151 @@
/*
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;
abstract class GateElm extends CircuitElm {
final int FLAG_SMALL = 1;
int inputCount = 2;
boolean lastOutput;
public GateElm(int xx, int yy) {
super(xx, yy);
noDiagonal = true;
inputCount = 2;
setSize(sim.smallGridCheckItem.getState() ? 1 : 2);
}
public GateElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f);
inputCount = new Integer(st.nextToken()).intValue();
lastOutput = new Double (st.nextToken()).doubleValue() > 2.5;
noDiagonal = true;
setSize((f & FLAG_SMALL) != 0 ? 1 : 2);
}
boolean isInverting() { return false; }
int gsize, gwidth, gwidth2, gheight, hs2;
void setSize(int s) {
gsize = s;
gwidth = 7*s;
gwidth2 = 14*s;
gheight = 8*s;
flags = (s == 1) ? FLAG_SMALL : 0;
}
String dump() {
return super.dump() + " " + inputCount + " " + volts[inputCount];
}
Point inPosts[], inGates[];
int ww;
void setPoints() {
super.setPoints();
if (dn > 150 && this == sim.dragElm)
setSize(2);
int hs = gheight;
int i;
ww = gwidth2; // was 24
if (ww > dn/2)
ww = (int) (dn/2);
if (isInverting() && ww+8 > dn/2)
ww = (int) (dn/2-8);
calcLeads(ww*2);
inPosts = new Point[inputCount];
inGates = new Point[inputCount];
allocNodes();
int i0 = -inputCount/2;
for (i = 0; i != inputCount; i++, i0++) {
if (i0 == 0 && (inputCount & 1) == 0)
i0++;
inPosts[i] = interpPoint(point1, point2, 0, hs*i0);
inGates[i] = interpPoint(lead1, lead2, 0, hs*i0);
volts[i] = (lastOutput ^ isInverting()) ? 5 : 0;
}
hs2 = gwidth*(inputCount/2+1);
setBbox(point1, point2, hs2);
}
void draw(Graphics g) {
int i;
for (i = 0; i != inputCount; i++) {
setVoltageColor(g, volts[i]);
drawThickLine(g, inPosts[i], inGates[i]);
}
setVoltageColor(g, volts[inputCount]);
drawThickLine(g, lead2, point2);
g.setColor(needsHighlight() ? selectColor : lightGrayColor);
drawThickPolygon(g, gatePoly);
if (linePoints != null)
for (i = 0; i != linePoints.length-1; i++)
drawThickLine(g, linePoints[i], linePoints[i+1]);
if (isInverting())
drawThickCircle(g, pcircle.x, pcircle.y, 3);
curcount = updateDotCount(current, curcount);
drawDots(g, lead2, point2, curcount);
drawPosts(g);
}
Polygon gatePoly;
Point pcircle, linePoints[];
int getPostCount() { return inputCount+1; }
Point getPost(int n) {
if (n == inputCount)
return point2;
return inPosts[n];
}
int getVoltageSourceCount() { return 1; }
abstract String getGateName();
void getInfo(String arr[]) {
arr[0] = getGateName();
arr[1] = "Vout = " + getVoltageText(volts[inputCount]);
arr[2] = "Iout = " + getCurrentText(getCurrent());
}
void stamp() {
sim.stampVoltageSource(0, nodes[inputCount], voltSource);
}
boolean getInput(int x) {
return volts[x] > 2.5;
}
abstract boolean calcFunction();
void doStep() {
int i;
boolean f = calcFunction();
if (isInverting())
f = !f;
lastOutput = f;
double res = f ? 5 : 0;
sim.updateVoltageSource(0, nodes[inputCount], voltSource, res);
}
public EditInfo getEditInfo(int n) {
if (n == 0)
return new EditInfo("# of Inputs", inputCount, 1, 8).
setDimensionless();
return null;
}
public void setEditValue(int n, EditInfo ei) {
inputCount = (int) ei.value;
setPoints();
}
// there is no current path through the gate inputs, but there
// is an indirect path through the output to ground.
boolean getConnection(int n1, int n2) { return false; }
boolean hasGroundConnection(int n1) {
return (n1 == inputCount);
}
}

View File

@@ -0,0 +1,37 @@
/*
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;
class GraphicElm extends CircuitElm
{
public GraphicElm(int xx, int yy)
{
super(xx,yy);
}
public GraphicElm(int xa, int ya, int xb, int yb, int flags)
{
super(xa, ya, xb, yb, flags);
}
int getPostCount() { return 0; }
}

View File

@@ -0,0 +1,128 @@
/*
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 com.google.gwt.canvas.dom.client.Context2d;
public class Graphics {
Context2d context;
int currentFontSize;
Font currentFont= null;
Color lastColor;
public Graphics(Context2d context) {
this.context = context;
}
public void setColor(Color color) {
if (color != null) {
String colorString = color.getHexValue();
context.setStrokeStyle(colorString);
context.setFillStyle(colorString);
} else {
System.out.println("Ignoring null-Color");
}
lastColor=color;
}
public void setColor(String color) {
context.setStrokeStyle(color);
context.setFillStyle(color);
lastColor=null;
}
public void fillRect(int x, int y, int width, int height) {
// context.beginPath();
context.fillRect(x, y, width, height);
// context.closePath();
}
public void drawRect(int x, int y, int width, int height) {
// context.beginPath();
context.strokeRect(x, y, width, height);
// context.closePath();
}
public void fillOval(int x, int y, int width, int height) {
context.beginPath();
context.arc(x+width/2, y+width/2, width/2, 0, 2.0*3.14159);
context.closePath();
context.fill();
}
public void drawString(String s, int x, int y){
// context.beginPath();
context.fillText(s, x, y);
// context.closePath();
}
public void setLineWidth(double width){
context.setLineWidth(width);
}
public void drawLine(int x1, int y1, int x2, int y2) {
context.beginPath();
context.moveTo(x1, y1);
context.lineTo(x2, y2);
context.stroke();
// context.closePath();
}
public void drawPolyline(int[] xpoints, int[] ypoints, int n) {
int i;
context.beginPath();
for (i=0; i<n;i++){
if (i==0)
context.moveTo(xpoints[i],ypoints[i]);
else
context.lineTo(xpoints[i],ypoints[i]);
}
context.closePath();
context.stroke();
}
public void fillPolygon(Polygon p) {
int i;
context.beginPath();
for (i=0; i<p.npoints;i++){
if (i==0)
context.moveTo(p.xpoints[i],p.ypoints[i]);
else
context.lineTo(p.xpoints[i],p.ypoints[i]);
}
context.closePath();
context.fill();
}
public void setFont(Font f){
if (f!=null){
context.setFont(f.fontname);
currentFontSize=f.size;
currentFont=f;
}
}
Font getFont(){
return currentFont;
}
}

View File

@@ -0,0 +1,57 @@
/*
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;
class GroundElm extends CircuitElm {
public GroundElm(int xx, int yy) { super(xx, yy); }
public GroundElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f);
}
int getDumpType() { return 'g'; }
int getPostCount() { return 1; }
void draw(Graphics g) {
setVoltageColor(g, 0);
drawThickLine(g, point1, point2);
int i;
for (i = 0; i != 3; i++) {
int a = 10-i*4;
int b = i*5; // -10;
interpPoint2(point1, point2, ps1, ps2, 1+b/dn, a);
drawThickLine(g, ps1, ps2);
}
doDots(g);
interpPoint(point1, point2, ps2, 1+11./dn);
setBbox(point1, ps2, 11);
drawPost(g, x, y, nodes[0]);
}
void setCurrent(int x, double c) { current = -c; }
void stamp() {
sim.stampVoltageSource(0, nodes[0], voltSource, 0);
}
double getVoltageDiff() { return 0; }
int getVoltageSourceCount() { return 1; }
void getInfo(String arr[]) {
arr[0] = "ground";
arr[1] = "I = " + getCurrentText(getCurrent());
}
boolean hasGroundConnection(int n1) { return true; }
int getShortcut() { return 'g'; }
}

View File

@@ -0,0 +1,59 @@
/*
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 HalfAdderElm extends ChipElm {
boolean hasReset() {return false;}
public HalfAdderElm(int xx, int yy) { super(xx, yy); }
public HalfAdderElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f, st);
}
String getChipName() { return "Half Adder"; }
void setupPins() {
sizeX=2;
sizeY=2;
pins=new Pin[getPostCount()];
pins[0] = new Pin(0, SIDE_E, "S");
pins[0].output=true;
pins[1] = new Pin(1, SIDE_E, "C");
pins[1].output=true;
pins[2] = new Pin(0, SIDE_W, "A");
pins[3] = new Pin(1, SIDE_W, "B");
}
int getPostCount() {
return 4;
}
int getVoltageSourceCount() {return 2;}
void execute() {
pins[0].value=pins[2].value^pins[3].value;
pins[1].value=pins[2].value&&pins[3].value;
}
int getDumpType() { return 195; }
}

View File

@@ -0,0 +1,86 @@
/*
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 com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.RichTextArea;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.safehtml.shared.SafeHtml;
public class ImportFromTextDialog extends DialogBox {
VerticalPanel vp;
HorizontalPanel hp;
CirSim sim;
// RichTextArea textBox;
TextArea textArea;
public ImportFromTextDialog( CirSim asim) {
super();
sim=asim;
Button okButton, cancelButton;
vp=new VerticalPanel();
setWidget(vp);
setText("Import from Text");
vp.add(new Label("Paste the text file for your circuit here..."));
// vp.add(textBox = new RichTextArea());
vp.add(textArea = new TextArea());
textArea.setWidth("300px");
textArea.setHeight("200px");
hp = new HorizontalPanel();
vp.add(hp);
hp.add(okButton = new Button("OK"));
okButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
String s;
sim.pushUndo();
closeDialog();
// s=textBox.getHTML();
// s=s.replace("<br>", "\r");
s=textArea.getText();
if (s!=null)
sim.readSetup(s, true);
}
});
hp.add(cancelButton = new Button("Cancel"));
cancelButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
closeDialog();
}
});
this.center();
show();
}
protected void closeDialog()
{
this.hide();
}
}

View File

@@ -0,0 +1,80 @@
/*
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;
class Inductor {
public static final int FLAG_BACK_EULER = 2;
int nodes[];
int flags;
CirSim sim;
double inductance;
double compResistance, current;
double curSourceValue;
Inductor(CirSim s) {
sim = s;
nodes = new int[2];
}
void setup(double ic, double cr, int f) {
inductance = ic;
current = cr;
flags = f;
}
boolean isTrapezoidal() { return (flags & FLAG_BACK_EULER) == 0; }
void reset() {
current = 0;
}
void stamp(int n0, int n1) {
// inductor companion model using trapezoidal or backward euler
// approximations (Norton equivalent) consists of a current
// source in parallel with a resistor. Trapezoidal is more
// accurate than backward euler but can cause oscillatory behavior.
// The oscillation is a real problem in circuits with switches.
nodes[0] = n0;
nodes[1] = n1;
if (isTrapezoidal())
compResistance = 2*inductance/sim.timeStep;
else // backward euler
compResistance = inductance/sim.timeStep;
sim.stampResistor(nodes[0], nodes[1], compResistance);
sim.stampRightSide(nodes[0]);
sim.stampRightSide(nodes[1]);
}
boolean nonLinear() { return false; }
void startIteration(double voltdiff) {
if (isTrapezoidal())
curSourceValue = voltdiff/compResistance+current;
else // backward euler
curSourceValue = current;
}
double calculateCurrent(double voltdiff) {
// we check compResistance because this might get called
// before stamp(), which sets compResistance, causing
// infinite current
if (compResistance > 0)
current = voltdiff/compResistance + curSourceValue;
return current;
}
void doStep(double voltdiff) {
sim.stampCurrentSource(nodes[0], nodes[1], curSourceValue);
}
}

View File

@@ -0,0 +1,115 @@
/*
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 InductorElm extends CircuitElm {
Inductor ind;
double inductance;
public InductorElm(int xx, int yy) {
super(xx, yy);
ind = new Inductor(sim);
inductance = 1;
ind.setup(inductance, current, flags);
}
public InductorElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f);
ind = new Inductor(sim);
inductance = new Double(st.nextToken()).doubleValue();
current = new Double(st.nextToken()).doubleValue();
ind.setup(inductance, current, flags);
}
int getDumpType() { return 'l'; }
String dump() {
return super.dump() + " " + inductance + " " + current;
}
void setPoints() {
super.setPoints();
calcLeads(32);
}
void draw(Graphics g) {
double v1 = volts[0];
double v2 = volts[1];
int i;
int hs = 8;
setBbox(point1, point2, hs);
draw2Leads(g);
setPowerColor(g, false);
drawCoil(g, 8, lead1, lead2, v1, v2);
if (sim.showValuesCheckItem.getState()) {
String s = getShortUnitText(inductance, "H");
drawValues(g, s, hs);
}
doDots(g);
drawPosts(g);
}
void reset() {
current = volts[0] = volts[1] = curcount = 0;
ind.reset();
}
void stamp() { ind.stamp(nodes[0], nodes[1]); }
void startIteration() {
ind.startIteration(volts[0]-volts[1]);
}
boolean nonLinear() { return ind.nonLinear(); }
void calculateCurrent() {
double voltdiff = volts[0]-volts[1];
current = ind.calculateCurrent(voltdiff);
}
void doStep() {
double voltdiff = volts[0]-volts[1];
ind.doStep(voltdiff);
}
void getInfo(String arr[]) {
arr[0] = "inductor";
getBasicInfo(arr);
arr[3] = "L = " + getUnitText(inductance, "H");
arr[4] = "P = " + getUnitText(getPower(), "W");
}
public EditInfo getEditInfo(int n) {
if (n == 0)
return new EditInfo("Inductance (H)", inductance, 0, 0);
if (n == 1) {
EditInfo ei = new EditInfo("", 0, -1, -1);
ei.checkbox = new Checkbox("Trapezoidal Approximation",
ind.isTrapezoidal());
return ei;
}
return null;
}
public void setEditValue(int n, EditInfo ei) {
if (n == 0)
inductance = ei.value;
if (n == 1) {
if (ei.checkbox.getState())
flags &= ~Inductor.FLAG_BACK_EULER;
else
flags |= Inductor.FLAG_BACK_EULER;
}
ind.setup(inductance, current, flags);
}
int getShortcut() { return 'L'; }
}

View File

@@ -0,0 +1,105 @@
/*
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 InverterElm extends CircuitElm {
double slewRate; // V/ns
public InverterElm(int xx, int yy) {
super(xx, yy);
noDiagonal = true;
slewRate = .5;
}
public InverterElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f);
noDiagonal = true;
try {
slewRate = new Double (st.nextToken()).doubleValue();
} catch (Exception e) {
slewRate = .5;
}
}
String dump() {
return super.dump() + " " + slewRate;
}
int getDumpType() { return 'I'; }
void draw(Graphics g) {
drawPosts(g);
draw2Leads(g);
g.setColor(needsHighlight() ? selectColor : lightGrayColor);
drawThickPolygon(g, gatePoly);
drawThickCircle(g, pcircle.x, pcircle.y, 3);
curcount = updateDotCount(current, curcount);
drawDots(g, lead2, point2, curcount);
}
Polygon gatePoly;
Point pcircle;
void setPoints() {
super.setPoints();
int hs = 16;
int ww = 16;
if (ww > dn/2)
ww = (int) (dn/2);
lead1 = interpPoint(point1, point2, .5-ww/dn);
lead2 = interpPoint(point1, point2, .5+(ww+2)/dn);
pcircle = interpPoint(point1, point2, .5+(ww-2)/dn);
Point triPoints[] = newPointArray(3);
interpPoint2(lead1, lead2, triPoints[0], triPoints[1], 0, hs);
triPoints[2] = interpPoint(point1, point2, .5+(ww-5)/dn);
gatePoly = createPolygon(triPoints);
setBbox(point1, point2, hs);
}
int getVoltageSourceCount() { return 1; }
void stamp() {
sim.stampVoltageSource(0, nodes[1], voltSource);
}
void doStep() {
double v0 = volts[1];
double out = volts[0] > 2.5 ? 0 : 5;
double maxStep = slewRate * sim.timeStep * 1e9;
out = Math.max(Math.min(v0+maxStep, out), v0-maxStep);
sim.updateVoltageSource(0, nodes[1], voltSource, out);
}
double getVoltageDiff() { return volts[0]; }
void getInfo(String arr[]) {
arr[0] = "inverter";
arr[1] = "Vi = " + getVoltageText(volts[0]);
arr[2] = "Vo = " + getVoltageText(volts[1]);
}
public EditInfo getEditInfo(int n) {
if (n == 0)
return new EditInfo("Slew Rate (V/ns)", slewRate, 0, 0);
return null;
}
public void setEditValue(int n, EditInfo ei) {
slewRate = ei.value;
}
// there is no current path through the inverter input, but there
// is an indirect path through the output to ground.
boolean getConnection(int n1, int n2) { return false; }
boolean hasGroundConnection(int n1) {
return (n1 == 1);
}
int getShortcut() { return '1'; }
}

View File

@@ -0,0 +1,186 @@
/*
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;
// contributed by Edward Calver
class InvertingSchmittElm extends CircuitElm {
double slewRate; // V/ns
double lowerTrigger;
double upperTrigger;
boolean state;
public InvertingSchmittElm(int xx, int yy) {
super(xx, yy);
noDiagonal = true;
slewRate = .5;
state=false;
lowerTrigger=1.66;
upperTrigger=3.33;
}
public InvertingSchmittElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f);
noDiagonal = true;
try {
slewRate = new Double (st.nextToken()).doubleValue();
lowerTrigger = new Double (st.nextToken()).doubleValue();
upperTrigger = new Double (st.nextToken()).doubleValue();
} catch (Exception e) {
slewRate = .5;
lowerTrigger=1.66;
upperTrigger=3.33;
}
}
String dump() {
return super.dump() + " " + slewRate+" "+lowerTrigger+" "+upperTrigger;
}
int getDumpType() { return 183; }//Trying to find unused type
void draw(Graphics g) {
drawPosts(g);
draw2Leads(g);
g.setColor(needsHighlight() ? selectColor : lightGrayColor);
drawThickPolygon(g, gatePoly);
drawThickPolygon(g, symbolPoly);
drawThickCircle(g, pcircle.x, pcircle.y, 3);
curcount = updateDotCount(current, curcount);
drawDots(g, lead2, point2, curcount);
}
Polygon gatePoly;
Polygon symbolPoly;
Point pcircle;
void setPoints() {
super.setPoints();
int hs = 16;
int ww = 16;
if (ww > dn/2)
ww = (int) (dn/2);
lead1 = interpPoint(point1, point2, .5-ww/dn);
lead2 = interpPoint(point1, point2, .5+(ww+2)/dn);
pcircle = interpPoint(point1, point2, .5+(ww-2)/dn);
Point triPoints[] = newPointArray(3);
Point symPoints[] = newPointArray(6);
Point dummy=new Point(0,0);
interpPoint2(lead1, lead2, triPoints[0], triPoints[1], 0, hs);
triPoints[2] = interpPoint(point1, point2, .5+(ww-5)/dn);
interpPoint2(lead1, lead2, symPoints[5], symPoints[4], 0.2, hs/4);// 0 5 1
interpPoint2(lead1, lead2, symPoints[1], symPoints[2], 0.35, hs/4);// 4 2 3
interpPoint2(lead1, lead2, symPoints[0],dummy, 0.1, hs/4);
interpPoint2(lead1, lead2,dummy,symPoints[3], 0.45, hs/4);
gatePoly = createPolygon(triPoints);
symbolPoly=createPolygon(symPoints);
setBbox(point1, point2, hs);
}
int getVoltageSourceCount() { return 1; }
void stamp() {
sim.stampVoltageSource(0, nodes[1], voltSource);
}
void doStep() {
double v0 = volts[1];
double out;
if(state)
{//Output is high
if(volts[0]>upperTrigger)//Input voltage high enough to set output low
{
state=false;
out=0;
}
else
{
out=5;
}
}
else
{//Output is low
if(volts[0]<lowerTrigger)//Input voltage low enough to set output high
{
state=true;
out=5;
}
else
{
out=0;
}
}
double maxStep = slewRate * sim.timeStep * 1e9;
out = Math.max(Math.min(v0+maxStep, out), v0-maxStep);
sim.updateVoltageSource(0, nodes[1], voltSource, out);
}
double getVoltageDiff() { return volts[0]; }
void getInfo(String arr[]) {
arr[0] = "InvertingSchmitt";
arr[1] = "Vi = " + getVoltageText(volts[0]);
arr[2] = "Vo = " + getVoltageText(volts[1]);
}
public EditInfo getEditInfo(int n) {
if (n == 0)
{
dlt=lowerTrigger;
return new EditInfo("Lower threshold (V)", lowerTrigger, 0.01,5);
}
if (n == 1)
{
dut=upperTrigger;
return new EditInfo("Upper threshold (V)", upperTrigger, 0.01,5);
}
if (n == 2)
return new EditInfo("Slew Rate (V/ns)", slewRate, 0, 0);
return null;
}
double dlt;
double dut;
public void setEditValue(int n, EditInfo ei) {
if (n == 0)
dlt=ei.value;
if (n == 1)
dut=ei.value;
if (n == 2)
slewRate = ei.value;
if(dlt>dut)
{
upperTrigger=dlt;
lowerTrigger=dut;
}
else
{
upperTrigger=dut;
lowerTrigger=dlt;
}
}
// there is no current path through the InvertingSchmitt input, but there
// is an indirect path through the output to ground.
boolean getConnection(int n1, int n2) { return false; }
boolean hasGroundConnection(int n1) {
return (n1 == 1);
}
}

View File

@@ -0,0 +1,105 @@
/*
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 JKFlipFlopElm extends ChipElm {
final int FLAG_RESET = 2;
boolean hasReset(){return (flags & FLAG_RESET)!= 0;}
public JKFlipFlopElm(int xx, int yy) { super(xx, yy); }
public JKFlipFlopElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f, st);
pins[4].value = !pins[3].value;
}
String getChipName() { return "JK flip-flop"; }
void setupPins() {
sizeX = 2;
sizeY = 3;
pins = new Pin[getPostCount()];
pins[0] = new Pin(0, SIDE_W, "J");
pins[1] = new Pin(1, SIDE_W, "");
pins[1].clock = true;
pins[1].bubble = true;
pins[2] = new Pin(2, SIDE_W, "K");
pins[3] = new Pin(0, SIDE_E, "Q");
pins[3].output = pins[3].state = true;
pins[4] = new Pin(2, SIDE_E, "Q");
pins[4].output = true;
pins[4].lineOver = true;
if(hasReset()){
pins[5] = new Pin(1, SIDE_E, "R");
}
}
int getPostCount() { return 5 + (hasReset() ? 1:0); }
int getVoltageSourceCount() { return 2; }
void execute() {
if (!pins[1].value && lastClock) {
boolean q = pins[3].value;
if (pins[0].value) {
if (pins[2].value)
q = !q;
else
q = true;
} else if (pins[2].value)
q = false;
pins[3].value = q;
pins[4].value = !q;
}
lastClock = pins[1].value;
if(hasReset()){
if(pins[5].value){
pins[3].value = false;
pins[4].value = true;
}
}
}
int getDumpType() { return 156; }
public EditInfo getEditInfo(int n){
if (n == 2){
EditInfo ei = new EditInfo("", 0, -1, -1);
ei.checkbox = new Checkbox("Reset Pin", hasReset());
return ei;
}
return super.getEditInfo(n);
}
public void setEditValue(int n, EditInfo ei){
if (n == 2){
if(ei.checkbox.getState()){
flags |= FLAG_RESET;
} else {
flags &= ~FLAG_RESET;
}
setupPins();
allocNodes();
setPoints();
}
super.setEditValue(n, ei);
}
}

View File

@@ -0,0 +1,93 @@
/*
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 JfetElm extends MosfetElm {
JfetElm(int xx, int yy, boolean pnpflag) {
super(xx, yy, pnpflag);
noDiagonal = true;
}
public JfetElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f, st);
noDiagonal = true;
}
Polygon gatePoly;
Polygon arrowPoly;
Point gatePt;
void draw(Graphics g) {
setBbox(point1, point2, hs);
setVoltageColor(g, volts[1]);
drawThickLine(g, src[0], src[1]);
drawThickLine(g, src[1], src[2]);
setVoltageColor(g, volts[2]);
drawThickLine(g, drn[0], drn[1]);
drawThickLine(g, drn[1], drn[2]);
setVoltageColor(g, volts[0]);
drawThickLine(g, point1, gatePt);
g.fillPolygon(arrowPoly);
setPowerColor(g, true);
g.fillPolygon(gatePoly);
curcount = updateDotCount(-ids, curcount);
if (curcount != 0) {
drawDots(g, src[0], src[1], curcount);
drawDots(g, src[1], src[2], curcount+8);
drawDots(g, drn[0], drn[1], -curcount);
drawDots(g, drn[1], drn[2], -(curcount+8));
}
drawPosts(g);
}
void setPoints() {
super.setPoints();
// find the coordinates of the various points we need to draw
// the JFET.
int hs2 = hs*dsign;
src = newPointArray(3);
drn = newPointArray(3);
interpPoint2(point1, point2, src[0], drn[0], 1, hs2);
interpPoint2(point1, point2, src[1], drn[1], 1, hs2/2);
interpPoint2(point1, point2, src[2], drn[2], 1-10/dn, hs2/2);
gatePt = interpPoint(point1, point2, 1-14/dn);
Point ra[] = newPointArray(4);
interpPoint2(point1, point2, ra[0], ra[1], 1-13/dn, hs);
interpPoint2(point1, point2, ra[2], ra[3], 1-10/dn, hs);
gatePoly = createPolygon(ra[0], ra[1], ra[3], ra[2]);
if (pnp == -1) {
Point x = interpPoint(gatePt, point1, 18/dn);
arrowPoly = calcArrow(gatePt, x, 8, 3);
} else
arrowPoly = calcArrow(point1, gatePt, 8, 3);
}
int getDumpType() { return 'j'; }
// these values are taken from Hayes+Horowitz p155
double getDefaultThreshold() { return -4; }
double getBeta() { return .00125; }
void getInfo(String arr[]) {
getFetInfo(arr, "JFET");
}
}

View File

@@ -0,0 +1,115 @@
/*
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 LEDElm extends DiodeElm {
double colorR, colorG, colorB;
public LEDElm(int xx, int yy) {
super(xx, yy);
fwdrop = 2.1024259;
setup();
colorR = 1; colorG = colorB = 0;
}
public LEDElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f, st);
if ((f & FLAG_FWDROP) == 0)
fwdrop = 2.1024259;
setup();
colorR = new Double(st.nextToken()).doubleValue();
colorG = new Double(st.nextToken()).doubleValue();
colorB = new Double(st.nextToken()).doubleValue();
}
int getDumpType() { return 162; }
String dump() {
return super.dump() + " " + colorR + " " + colorG + " " + colorB;
}
Point ledLead1, ledLead2, ledCenter;
void setPoints() {
super.setPoints();
int cr = 12;
ledLead1 = interpPoint(point1, point2, .5-cr/dn);
ledLead2 = interpPoint(point1, point2, .5+cr/dn);
ledCenter = interpPoint(point1, point2, .5);
}
void draw(Graphics g) {
if (needsHighlight() || this == sim.dragElm) {
super.draw(g);
return;
}
setVoltageColor(g, volts[0]);
drawThickLine(g, point1, ledLead1);
setVoltageColor(g, volts[1]);
drawThickLine(g, ledLead2, point2);
g.setColor(Color.gray);
int cr = 12;
drawThickCircle(g, ledCenter.x, ledCenter.y, cr);
cr -= 4;
double w = 255*current/.01;
if (w > 255)
w = 255;
Color cc = new Color((int) (colorR*w), (int) (colorG*w),
(int) (colorB*w));
g.setColor(cc);
g.fillOval(ledCenter.x-cr, ledCenter.y-cr, cr*2, cr*2);
setBbox(point1, point2, cr);
updateDotCount();
drawDots(g, point1, ledLead1, curcount);
drawDots(g, point2, ledLead2, -curcount);
drawPosts(g);
}
void getInfo(String arr[]) {
super.getInfo(arr);
arr[0] = "LED";
}
public EditInfo getEditInfo(int n) {
if (n == 0)
return super.getEditInfo(n);
if (n == 1)
return new EditInfo("Red Value (0-1)", colorR, 0, 1).
setDimensionless();
if (n == 2)
return new EditInfo("Green Value (0-1)", colorG, 0, 1).
setDimensionless();
if (n == 3)
return new EditInfo("Blue Value (0-1)", colorB, 0, 1).
setDimensionless();
return null;
}
public void setEditValue(int n, EditInfo ei) {
if (n == 0)
super.setEditValue(0, ei);
if (n == 1)
colorR = ei.value;
if (n == 2)
colorG = ei.value;
if (n == 3)
colorB = ei.value;
}
int getShortcut() { return 'l'; }
}

View File

@@ -0,0 +1,189 @@
/*
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 LampElm extends CircuitElm {
double resistance;
final double roomTemp = 300;
double temp, nom_pow, nom_v, warmTime, coolTime;
public LampElm(int xx, int yy) {
super(xx, yy);
temp = roomTemp;
nom_pow = 100;
nom_v = 120;
warmTime = .4;
coolTime = .4;
}
public LampElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f);
temp = new Double(st.nextToken()).doubleValue();
nom_pow = new Double(st.nextToken()).doubleValue();
nom_v = new Double(st.nextToken()).doubleValue();
warmTime = new Double(st.nextToken()).doubleValue();
coolTime = new Double(st.nextToken()).doubleValue();
}
String dump() {
return super.dump() + " " + temp + " " + nom_pow + " " + nom_v +
" " + warmTime + " " + coolTime;
}
int getDumpType() { return 181; }
Point bulbLead[], filament[], bulb;
int bulbR;
void reset() {
super.reset();
temp = roomTemp;
}
final int filament_len = 24;
void setPoints() {
super.setPoints();
int llen = 16;
calcLeads(llen);
bulbLead = newPointArray(2);
filament = newPointArray(2);
bulbR = 20;
filament[0] = interpPoint(lead1, lead2, 0, filament_len);
filament[1] = interpPoint(lead1, lead2, 1, filament_len);
double br = filament_len-Math.sqrt(bulbR*bulbR-llen*llen);
bulbLead[0] = interpPoint(lead1, lead2, 0, br);
bulbLead[1] = interpPoint(lead1, lead2, 1, br);
bulb = interpPoint(filament[0], filament[1], .5);
}
Color getTempColor() {
if (temp < 1200) {
int x = (int) (255*(temp-800)/400);
if (x < 0)
x = 0;
return new Color(x, 0, 0);
}
if (temp < 1700) {
int x = (int) (255*(temp-1200)/500);
if (x < 0)
x = 0;
return new Color(255, x, 0);
}
if (temp < 2400) {
int x = (int) (255*(temp-1700)/700);
if (x < 0)
x = 0;
return new Color(255, 255, x);
}
return Color.white;
}
void draw(Graphics g) {
double v1 = volts[0];
double v2 = volts[1];
setBbox(point1, point2, 4);
adjustBbox(bulb.x-bulbR, bulb.y-bulbR,
bulb.x+bulbR, bulb.y+bulbR);
// adjustbbox
draw2Leads(g);
setPowerColor(g, true);
g.setColor(getTempColor());
g.fillOval(bulb.x-bulbR, bulb.y-bulbR, bulbR*2, bulbR*2);
g.setColor(Color.white);
drawThickCircle(g, bulb.x, bulb.y, bulbR);
setVoltageColor(g, v1);
drawThickLine(g, lead1, filament[0]);
setVoltageColor(g, v2);
drawThickLine(g, lead2, filament[1]);
setVoltageColor(g, (v1+v2)*.5);
drawThickLine(g, filament[0], filament[1]);
updateDotCount();
if (sim.dragElm != this) {
drawDots(g, point1, lead1, curcount);
double cc = curcount+(dn-16)/2;
drawDots(g, lead1, filament[0], cc);
cc += filament_len;
drawDots(g, filament[0], filament[1], cc);
cc += 16;
drawDots(g, filament[1], lead2, cc);
cc += filament_len;
drawDots(g, lead2, point2, curcount);
}
drawPosts(g);
}
void calculateCurrent() {
current = (volts[0]-volts[1])/resistance;
//System.out.print(this + " res current set to " + current + "\n");
}
void stamp() {
sim.stampNonLinear(nodes[0]);
sim.stampNonLinear(nodes[1]);
}
boolean nonLinear() { return true; }
void startIteration() {
// based on http://www.intusoft.com/nlpdf/nl11.pdf
double nom_r = nom_v*nom_v/nom_pow;
// this formula doesn't work for values over 5390
double tp = (temp > 5390) ? 5390 : temp;
resistance = nom_r*(1.26104 -
4.90662*Math.sqrt(17.1839/tp - 0.00318794) -
7.8569/(tp - 187.56));
double cap = 1.57e-4*nom_pow;
double capw = cap * warmTime/.4;
double capc = cap * coolTime/.4;
//System.out.println(nom_r + " " + (resistance/nom_r));
temp += getPower()*sim.timeStep/capw;
double cr = 2600/nom_pow;
temp -= sim.timeStep*(temp-roomTemp)/(capc*cr);
//System.out.println(capw + " " + capc + " " + temp + " " +resistance);
}
void doStep() {
sim.stampResistor(nodes[0], nodes[1], resistance);
}
void getInfo(String arr[]) {
arr[0] = "lamp";
getBasicInfo(arr);
arr[3] = "R = " + getUnitText(resistance, sim.ohmString);
arr[4] = "P = " + getUnitText(getPower(), "W");
arr[5] = "T = " + ((int) temp) + " K";
}
public EditInfo getEditInfo(int n) {
// ohmString doesn't work here on linux
if (n == 0)
return new EditInfo("Nominal Power", nom_pow, 0, 0);
if (n == 1)
return new EditInfo("Nominal Voltage", nom_v, 0, 0);
if (n == 2)
return new EditInfo("Warmup Time (s)", warmTime, 0, 0);
if (n == 3)
return new EditInfo("Cooldown Time (s)", coolTime, 0, 0);
return null;
}
public void setEditValue(int n, EditInfo ei) {
if (n == 0 && ei.value > 0)
nom_pow = ei.value;
if (n == 1 && ei.value > 0)
nom_v = ei.value;
if (n == 2 && ei.value > 0)
warmTime = ei.value;
if (n == 3 && ei.value > 0)
coolTime = ei.value;
}
}

View File

@@ -0,0 +1,60 @@
/*
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 LatchElm extends ChipElm {
public LatchElm(int xx, int yy) { super(xx, yy); }
public LatchElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f, st);
}
String getChipName() { return "Latch"; }
boolean needsBits() { return true; }
int loadPin;
void setupPins() {
sizeX = 2;
sizeY = bits+1;
pins = new Pin[getPostCount()];
int i;
for (i = 0; i != bits; i++)
pins[i] = new Pin(bits-1-i, SIDE_W, "I" + i);
for (i = 0; i != bits; i++) {
pins[i+bits] = new Pin(bits-1-i, SIDE_E, "O");
pins[i+bits].output = true;
}
pins[loadPin = bits*2] = new Pin(bits, SIDE_W, "Ld");
allocNodes();
}
boolean lastLoad = false;
void execute() {
int i;
if (pins[loadPin].value && !lastLoad)
for (i = 0; i != bits; i++)
pins[i+bits].value = pins[i].value;
lastLoad = pins[loadPin].value;
}
int getVoltageSourceCount() { return bits; }
int getPostCount() { return bits*2+1; }
int getDumpType() { return 168; }
}

View File

@@ -0,0 +1,82 @@
/*
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 com.google.gwt.user.client.ui.FileUpload;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ContextMenuEvent;
public class LoadFile extends FileUpload implements ChangeHandler {
static CirSim sim;
static public final native boolean isSupported()
/*-{
return !!($wnd.File && $wnd.FileReader);
}-*/;
static public void doLoadCallback(String s) {
sim.readSetup(s, false);
sim.createNewLoadFile();
}
LoadFile(CirSim s) {
super();
sim=s;
this.setName("Import");
this.getElement().setId("LoadFileElement");
this.addChangeHandler(this);
this.addStyleName("offScreen");
}
public void onChange(ChangeEvent e) {
doLoad();
}
public final native void click()
/*-{
$doc.getElementById("LoadFileElement").click();
}-*/;
static public final native void doLoad()
/*-{
var oFiles = $doc.getElementById("LoadFileElement").files,
nFiles = oFiles.length;
if (nFiles>=1 && oFiles[0].size<32000) {
var reader = new FileReader();
reader.onload = function(e) {
var text = reader.result;
@com.lushprojects.circuitjs1.client.LoadFile::doLoadCallback(Ljava/lang/String;)(text);
};
reader.readAsText(oFiles[0]);
}
}-*/;
}

View File

@@ -0,0 +1,120 @@
/*
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 LogicInputElm extends SwitchElm {
final int FLAG_TERNARY = 1;
final int FLAG_NUMERIC = 2;
double hiV, loV;
public LogicInputElm(int xx, int yy) {
super(xx, yy, false);
hiV = 5;
loV = 0;
}
public LogicInputElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f, st);
try {
hiV = new Double(st.nextToken()).doubleValue();
loV = new Double(st.nextToken()).doubleValue();
} catch (Exception e) {
hiV = 5;
loV = 0;
}
if (isTernary())
posCount = 3;
}
boolean isTernary() { return (flags & FLAG_TERNARY) != 0; }
boolean isNumeric() { return (flags & (FLAG_TERNARY|FLAG_NUMERIC)) != 0; }
int getDumpType() { return 'L'; }
String dump() {
return super.dump() + " " + hiV + " " + loV;
}
int getPostCount() { return 1; }
void setPoints() {
super.setPoints();
lead1 = interpPoint(point1, point2, 1-12/dn);
}
void draw(Graphics g) {
Font oldf=g.getFont();
Font f = new Font("SansSerif", Font.BOLD, 20);
g.setFont(f);
g.setColor(needsHighlight() ? selectColor : whiteColor);
String s = position == 0 ? "L" : "H";
if (isNumeric())
s = "" + position;
setBbox(point1, lead1, 0);
drawCenteredText(g, s, x2, y2, true);
setVoltageColor(g, volts[0]);
drawThickLine(g, point1, lead1);
updateDotCount();
drawDots(g, point1, lead1, curcount);
drawPosts(g);
g.setFont(oldf);
}
void setCurrent(int vs, double c) { current = -c; }
void stamp() {
double v = (position == 0) ? loV : hiV;
if (isTernary())
v = position * 2.5;
sim.stampVoltageSource(0, nodes[0], voltSource, v);
}
int getVoltageSourceCount() { return 1; }
double getVoltageDiff() { return volts[0]; }
void getInfo(String arr[]) {
arr[0] = "logic input";
arr[1] = (position == 0) ? "low" : "high";
if (isNumeric())
arr[1] = "" + position;
arr[1] += " (" + getVoltageText(volts[0]) + ")";
arr[2] = "I = " + getCurrentText(getCurrent());
}
boolean hasGroundConnection(int n1) { return true; }
public EditInfo getEditInfo(int n) {
if (n == 0) {
EditInfo ei = new EditInfo("", 0, 0, 0);
ei.checkbox = new Checkbox("Momentary Switch", momentary);
return ei;
}
if (n == 1)
return new EditInfo("High Voltage", hiV, 10, -10);
if (n == 2)
return new EditInfo("Low Voltage", loV, 10, -10);
return null;
}
public void setEditValue(int n, EditInfo ei) {
if (n == 0)
momentary = ei.checkbox.getState();
if (n == 1)
hiV = ei.value;
if (n == 2)
loV = ei.value;
}
int getShortcut() { return 'i'; }
void drawHandles(Graphics g, Color c) {
g.setColor(c);
g.fillRect(x-3, y-3, 7, 7);
}
}

View File

@@ -0,0 +1,119 @@
/*
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 LogicOutputElm extends CircuitElm {
final int FLAG_TERNARY = 1;
final int FLAG_NUMERIC = 2;
final int FLAG_PULLDOWN = 4;
double threshold;
String value;
public LogicOutputElm(int xx, int yy) {
super(xx, yy);
threshold = 2.5;
}
public LogicOutputElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f);
try {
threshold = new Double(st.nextToken()).doubleValue();
} catch (Exception e) {
threshold = 2.5;
}
}
String dump() {
return super.dump() + " " + threshold;
}
int getDumpType() { return 'M'; }
int getPostCount() { return 1; }
boolean isTernary() { return (flags & FLAG_TERNARY) != 0; }
boolean isNumeric() { return (flags & (FLAG_TERNARY|FLAG_NUMERIC)) != 0; }
boolean needsPullDown() { return (flags & FLAG_PULLDOWN) != 0; }
void setPoints() {
super.setPoints();
lead1 = interpPoint(point1, point2, 1-12/dn);
}
void draw(Graphics g) {
Font oldf=g.getFont();
Font f = new Font("SansSerif", Font.BOLD, 20);
g.setFont(f);
//g.setColor(needsHighlight() ? selectColor : lightGrayColor);
g.setColor(lightGrayColor);
String s = (volts[0] < threshold) ? "L" : "H";
if (isTernary()) {
if (volts[0] > 3.75)
s = "2";
else if (volts[0] > 1.25)
s = "1";
else
s = "0";
} else if (isNumeric())
s = (volts[0] < threshold) ? "0" : "1";
value = s;
setBbox(point1, lead1, 0);
drawCenteredText(g, s, x2, y2, true);
setVoltageColor(g, volts[0]);
drawThickLine(g, point1, lead1);
drawPosts(g);
g.setFont(oldf);
}
void stamp() {
if (needsPullDown())
sim.stampResistor(nodes[0], 0, 1e6);
}
double getVoltageDiff() { return volts[0]; }
void getInfo(String arr[]) {
arr[0] = "logic output";
arr[1] = (volts[0] < threshold) ? "low" : "high";
if (isNumeric())
arr[1] = value;
arr[2] = "V = " + getVoltageText(volts[0]);
}
public EditInfo getEditInfo(int n) {
if (n == 0)
return new EditInfo("Threshold", threshold, 10, -10);
if (n == 1) {
EditInfo ei = new EditInfo("", 0, -1, -1);
ei.checkbox = new Checkbox("Current Required", needsPullDown());
return ei;
}
return null;
}
public void setEditValue(int n, EditInfo ei) {
if (n == 0)
threshold = ei.value;
if (n == 1) {
if (ei.checkbox.getState())
flags = FLAG_PULLDOWN;
else
flags &= ~FLAG_PULLDOWN;
}
}
int getShortcut() { return 'o'; }
void drawHandles(Graphics g, Color c) {
g.setColor(c);
g.fillRect(x-3, y-3, 7, 7);
}
}

View File

@@ -0,0 +1,154 @@
/*
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 MemristorElm extends CircuitElm {
double r_on, r_off, dopeWidth, totalWidth, mobility, resistance;
public MemristorElm(int xx, int yy) {
super(xx, yy);
r_on = 100;
r_off = 160*r_on;
dopeWidth = 0;
totalWidth = 10e-9; // meters
mobility = 1e-10; // m^2/sV
resistance = 100;
}
public MemristorElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f);
r_on = new Double(st.nextToken()).doubleValue();
r_off = new Double(st.nextToken()).doubleValue();
dopeWidth = new Double(st.nextToken()).doubleValue();
totalWidth = new Double(st.nextToken()).doubleValue();
mobility = new Double(st.nextToken()).doubleValue();
resistance = 100;
}
int getDumpType() { return 'm'; }
String dump() {
return super.dump() + " " + r_on + " " + r_off + " " + dopeWidth + " " +
totalWidth + " " + mobility;
}
Point ps3, ps4;
void setPoints() {
super.setPoints();
calcLeads(32);
ps3 = new Point();
ps4 = new Point();
}
void draw(Graphics g) {
int segments = 6;
int i;
int ox = 0;
double v1 = volts[0];
double v2 = volts[1];
int hs = 2+(int) (8*(1-dopeWidth/totalWidth));
setBbox(point1, point2, hs);
draw2Leads(g);
setPowerColor(g, true);
double segf = 1./segments;
// draw zigzag
for (i = 0; i <= segments; i++) {
int nx = (i & 1) == 0 ? 1 : -1;
if (i == segments)
nx = 0;
double v = v1+(v2-v1)*i/segments;
setVoltageColor(g, v);
interpPoint(lead1, lead2, ps1, i*segf, hs*ox);
interpPoint(lead1, lead2, ps2, i*segf, hs*nx);
drawThickLine(g, ps1, ps2);
if (i == segments)
break;
interpPoint(lead1, lead2, ps1, (i+1)*segf, hs*nx);
drawThickLine(g, ps1, ps2);
ox = nx;
}
doDots(g);
drawPosts(g);
}
boolean nonLinear() { return true; }
void calculateCurrent() {
current = (volts[0]-volts[1])/resistance;
}
void reset() {
dopeWidth = 0;
}
void startIteration() {
double wd = dopeWidth/totalWidth;
dopeWidth += sim.timeStep*mobility*r_on*current/totalWidth;
if (dopeWidth < 0)
dopeWidth = 0;
if (dopeWidth > totalWidth)
dopeWidth = totalWidth;
resistance = r_on * wd + r_off * (1-wd);
}
void stamp() {
sim.stampNonLinear(nodes[0]);
sim.stampNonLinear(nodes[1]);
}
void doStep() {
sim.stampResistor(nodes[0], nodes[1], resistance);
}
void getInfo(String arr[]) {
arr[0] = "memristor";
getBasicInfo(arr);
arr[3] = "R = " + getUnitText(resistance, sim.ohmString);
arr[4] = "P = " + getUnitText(getPower(), "W");
}
double getScopeValue(int x) {
return (x == 2) ? resistance : (x == 1) ? getPower() : getVoltageDiff();
}
String getScopeUnits(int x) {
return (x == 2) ? sim.ohmString : (x == 1) ? "W" : "V";
}
public EditInfo getEditInfo(int n) {
if (n == 0)
return new EditInfo("Max Resistance (ohms)", r_on, 0, 0);
if (n == 1)
return new EditInfo("Min Resistance (ohms)", r_off, 0, 0);
if (n == 2)
return new EditInfo("Width of Doped Region (nm)", dopeWidth*1e9, 0, 0);
if (n == 3)
return new EditInfo("Total Width (nm)", totalWidth*1e9, 0, 0);
if (n == 4)
return new EditInfo("Mobility (um^2/(s*V))", mobility*1e12, 0, 0);
return null;
}
public void setEditValue(int n, EditInfo ei) {
if (n == 0)
r_on = ei.value;
if (n == 1)
r_off = ei.value;
if (n == 2)
dopeWidth = ei.value*1e-9;
if (n == 3)
totalWidth = ei.value*1e-9;
if (n == 4)
mobility = ei.value*1e-12;
}
}

View File

@@ -0,0 +1,101 @@
/*
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 MonostableElm extends ChipElm {
//Used to detect rising edge
private boolean prevInputValue=false;
private boolean retriggerable=false;
private boolean triggered=false;
private double lastRisingEdge=0;
private double delay=0.01;
public MonostableElm(int xx, int yy) { super(xx, yy); }
public MonostableElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f, st);
retriggerable=new Boolean(st.nextToken()).booleanValue();
delay=new Double(st.nextToken()).doubleValue();
}
String getChipName() { return "Monostable"; }
void setupPins() {
sizeX = 2;
sizeY = 2;
pins = new Pin[getPostCount()];
pins[0] = new Pin(0, SIDE_W, "");
pins[0].clock = true;
pins[1] = new Pin(0, SIDE_E, "Q");
pins[1].output=true;
pins[2] = new Pin(1, SIDE_E, "Q");
pins[2].output=true;
pins[2].lineOver=true;
}
int getPostCount() {
return 3;
}
int getVoltageSourceCount() { return 2; }
void execute() {
if(pins[0].value&&prevInputValue!=pins[0].value&&(retriggerable||!triggered)){
lastRisingEdge=sim.t;
pins[1].value=true;
pins[2].value=false;
triggered=true;
}
if(triggered&&sim.t>lastRisingEdge+delay)
{
pins[1].value=false;
pins[2].value=true;
triggered=false;
}
prevInputValue=pins[0].value;
}
String dump(){
return super.dump() + " " + retriggerable + " " + delay;
}
int getDumpType() { return 194; }
public EditInfo getEditInfo(int n) {
if (n == 2) {
EditInfo ei = new EditInfo("", 0, -1, -1);
ei.checkbox=new Checkbox("Retriggerable",retriggerable);
return ei;
}
if (n == 3) {
EditInfo ei = new EditInfo("Period (s)",delay, 0.001,0.1);
return ei;
}
return super.getEditInfo(n);
}
public void setEditValue(int n, EditInfo ei) {
if (n == 2) {
retriggerable=ei.checkbox.getState();
}
if (n == 3) {
delay=ei.value;
}
super.setEditValue(n, ei);
}
}

View File

@@ -0,0 +1,275 @@
/*
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 MosfetElm extends CircuitElm {
int pnp;
int FLAG_PNP = 1;
int FLAG_SHOWVT = 2;
int FLAG_DIGITAL = 4;
double vt;
MosfetElm(int xx, int yy, boolean pnpflag) {
super(xx, yy);
pnp = (pnpflag) ? -1 : 1;
flags = (pnpflag) ? FLAG_PNP : 0;
noDiagonal = true;
vt = getDefaultThreshold();
}
public MosfetElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f);
pnp = ((f & FLAG_PNP) != 0) ? -1 : 1;
noDiagonal = true;
vt = getDefaultThreshold();
try {
vt = new Double(st.nextToken()).doubleValue();
} catch (Exception e) {}
}
double getDefaultThreshold() { return 1.5; }
double getBeta() { return .02; }
boolean nonLinear() { return true; }
boolean drawDigital() { return (flags & FLAG_DIGITAL) != 0; }
void reset() {
lastv1 = lastv2 = volts[0] = volts[1] = volts[2] = curcount = 0;
}
String dump() {
return super.dump() + " " + vt;
}
int getDumpType() { return 'f'; }
final int hs = 16;
void draw(Graphics g) {
setBbox(point1, point2, hs);
setVoltageColor(g, volts[1]);
drawThickLine(g, src[0], src[1]);
setVoltageColor(g, volts[2]);
drawThickLine(g, drn[0], drn[1]);
int segments = 6;
int i;
setPowerColor(g, true);
double segf = 1./segments;
for (i = 0; i != segments; i++) {
double v = volts[1]+(volts[2]-volts[1])*i/segments;
setVoltageColor(g, v);
interpPoint(src[1], drn[1], ps1, i*segf);
interpPoint(src[1], drn[1], ps2, (i+1)*segf);
drawThickLine(g, ps1, ps2);
}
setVoltageColor(g, volts[1]);
drawThickLine(g, src[1], src[2]);
setVoltageColor(g, volts[2]);
drawThickLine(g, drn[1], drn[2]);
if (!drawDigital()) {
setVoltageColor(g, pnp == 1 ? volts[1] : volts[2]);
g.fillPolygon(arrowPoly);
}
if (sim.powerCheckItem.getState())
g.setColor(Color.gray);
setVoltageColor(g, volts[0]);
drawThickLine(g, point1, gate[1]);
drawThickLine(g, gate[0], gate[2]);
if (drawDigital() && pnp == -1)
drawThickCircle(g, pcircle.x, pcircle.y, pcircler);
if ((flags & FLAG_SHOWVT) != 0) {
String s = "" + (vt*pnp);
g.setColor(whiteColor);
g.setFont(unitsFont);
drawCenteredText(g, s, x2+2, y2, false);
}
if ((needsHighlight() || sim.dragElm == this) && dy == 0) {
g.setColor(Color.white);
g.setFont(unitsFont);
int ds = sign(dx);
g.drawString("G", gate[1].x-10*ds, gate[1].y-5);
g.drawString(pnp == -1 ? "D" : "S", src[0].x-3+9*ds, src[0].y+4); // x+6 if ds=1, -12 if -1
g.drawString(pnp == -1 ? "S" : "D", drn[0].x-3+9*ds, drn[0].y+4);
}
curcount = updateDotCount(-ids, curcount);
drawDots(g, src[0], src[1], curcount);
drawDots(g, src[1], drn[1], curcount);
drawDots(g, drn[1], drn[0], curcount);
drawPosts(g);
}
Point getPost(int n) {
return (n == 0) ? point1 : (n == 1) ? src[0] : drn[0];
}
double getCurrent() { return ids; }
double getPower() { return ids*(volts[2]-volts[1]); }
int getPostCount() { return 3; }
int pcircler;
Point src[], drn[], gate[], pcircle;
Polygon arrowPoly;
void setPoints() {
super.setPoints();
// find the coordinates of the various points we need to draw
// the MOSFET.
int hs2 = hs*dsign;
src = newPointArray(3);
drn = newPointArray(3);
interpPoint2(point1, point2, src[0], drn[0], 1, -hs2);
interpPoint2(point1, point2, src[1], drn[1], 1-22/dn, -hs2);
interpPoint2(point1, point2, src[2], drn[2], 1-22/dn, -hs2*4/3);
gate = newPointArray(3);
interpPoint2(point1, point2, gate[0], gate[2], 1-28/dn, hs2/2); // was 1-20/dn
interpPoint(gate[0], gate[2], gate[1], .5);
if (!drawDigital()) {
if (pnp == 1)
arrowPoly = calcArrow(src[1], src[0], 10, 4);
else
arrowPoly = calcArrow(drn[0], drn[1], 12, 5);
} else if (pnp == -1) {
interpPoint(point1, point2, gate[1], 1-36/dn);
int dist = (dsign < 0) ? 32 : 31;
pcircle = interpPoint(point1, point2, 1-dist/dn);
pcircler = 3;
}
}
double lastv1, lastv2;
double ids;
int mode = 0;
double gm = 0;
void stamp() {
sim.stampNonLinear(nodes[1]);
sim.stampNonLinear(nodes[2]);
}
void doStep() {
double vs[] = new double[3];
vs[0] = volts[0];
vs[1] = volts[1];
vs[2] = volts[2];
if (vs[1] > lastv1 + .5)
vs[1] = lastv1 + .5;
if (vs[1] < lastv1 - .5)
vs[1] = lastv1 - .5;
if (vs[2] > lastv2 + .5)
vs[2] = lastv2 + .5;
if (vs[2] < lastv2 - .5)
vs[2] = lastv2 - .5;
int source = 1;
int drain = 2;
if (pnp*vs[1] > pnp*vs[2]) {
source = 2;
drain = 1;
}
int gate = 0;
double vgs = vs[gate ]-vs[source];
double vds = vs[drain]-vs[source];
if (Math.abs(lastv1-vs[1]) > .01 ||
Math.abs(lastv2-vs[2]) > .01)
sim.converged = false;
lastv1 = vs[1];
lastv2 = vs[2];
double realvgs = vgs;
double realvds = vds;
vgs *= pnp;
vds *= pnp;
ids = 0;
gm = 0;
double Gds = 0;
double beta = getBeta();
if (vgs > .5 && this instanceof JfetElm) {
sim.stop("JFET is reverse biased!", this);
return;
}
if (vgs < vt) {
// should be all zero, but that causes a singular matrix,
// so instead we treat it as a large resistor
Gds = 1e-8;
ids = vds*Gds;
mode = 0;
} else if (vds < vgs-vt) {
// linear
ids = beta*((vgs-vt)*vds - vds*vds*.5);
gm = beta*vds;
Gds = beta*(vgs-vds-vt);
mode = 1;
} else {
// saturation; Gds = 0
gm = beta*(vgs-vt);
// use very small Gds to avoid nonconvergence
Gds = 1e-8;
ids = .5*beta*(vgs-vt)*(vgs-vt) + (vds-(vgs-vt))*Gds;
mode = 2;
}
double rs = -pnp*ids + Gds*realvds + gm*realvgs;
//System.out.println("M " + vds + " " + vgs + " " + ids + " " + gm + " "+ Gds + " " + volts[0] + " " + volts[1] + " " + volts[2] + " " + source + " " + rs + " " + this);
sim.stampMatrix(nodes[drain], nodes[drain], Gds);
sim.stampMatrix(nodes[drain], nodes[source], -Gds-gm);
sim.stampMatrix(nodes[drain], nodes[gate], gm);
sim.stampMatrix(nodes[source], nodes[drain], -Gds);
sim.stampMatrix(nodes[source], nodes[source], Gds+gm);
sim.stampMatrix(nodes[source], nodes[gate], -gm);
sim.stampRightSide(nodes[drain], rs);
sim.stampRightSide(nodes[source], -rs);
if (source == 2 && pnp == 1 ||
source == 1 && pnp == -1)
ids = -ids;
}
void getFetInfo(String arr[], String n) {
arr[0] = ((pnp == -1) ? "p-" : "n-") + n;
arr[0] += " (Vt = " + getVoltageText(pnp*vt) + ")";
arr[1] = ((pnp == 1) ? "Ids = " : "Isd = ") + getCurrentText(ids);
arr[2] = "Vgs = " + getVoltageText(volts[0]-volts[pnp == -1 ? 2 : 1]);
arr[3] = ((pnp == 1) ? "Vds = " : "Vsd = ") + getVoltageText(volts[2]-volts[1]);
arr[4] = (mode == 0) ? "off" :
(mode == 1) ? "linear" : "saturation";
arr[5] = "gm = " + getUnitText(gm, "A/V");
}
void getInfo(String arr[]) {
getFetInfo(arr, "MOSFET");
}
boolean canViewInScope() { return true; }
double getVoltageDiff() { return volts[2] - volts[1]; }
boolean getConnection(int n1, int n2) {
return !(n1 == 0 || n2 == 0);
}
public EditInfo getEditInfo(int n) {
if (n == 0)
return new EditInfo("Threshold Voltage", pnp*vt, .01, 5);
if (n == 1) {
EditInfo ei = new EditInfo("", 0, -1, -1);
ei.checkbox = new Checkbox("Digital Symbol", drawDigital());
return ei;
}
return null;
}
public void setEditValue(int n, EditInfo ei) {
if (n == 0)
vt = pnp*ei.value;
if (n == 1) {
flags = (ei.checkbox.getState()) ? (flags | FLAG_DIGITAL) :
(flags & ~FLAG_DIGITAL);
setPoints();
}
}
}

View File

@@ -0,0 +1,68 @@
/*
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;
// contributed by Edward Calver
class MultiplexerElm extends ChipElm {
boolean hasReset() {return false;}
public MultiplexerElm(int xx, int yy) { super(xx, yy); }
public MultiplexerElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f, st);
}
String getChipName() { return "Multiplexer"; }
void setupPins() {
sizeX = 3;
sizeY = 5;
pins = new Pin[getPostCount()];
pins[0] = new Pin(0, SIDE_W, "I0");
pins[1] = new Pin(1, SIDE_W, "I1");
pins[2] = new Pin(2, SIDE_W, "I2");
pins[3] = new Pin(3, SIDE_W, "I3");
pins[4] = new Pin(1, SIDE_S, "S0");
pins[5] = new Pin(2, SIDE_S, "S1");
pins[6] = new Pin(0, SIDE_E, "Q");
pins[6].output=true;
}
int getPostCount() {
return 7;
}
int getVoltageSourceCount() {return 1;}
void execute() {
int selectedvalue=0;
if(pins[4].value)selectedvalue++;
if(pins[5].value)selectedvalue+=2;
pins[6].value=pins[selectedvalue].value;
}
int getDumpType() { return 184; }
}

View File

@@ -0,0 +1,37 @@
/*
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 com.google.gwt.user.client.Command;
public class MyCommand implements Command {
private final String menuName;
private final String itemName;
public MyCommand(String name, String item){
menuName=name;
itemName=item;
}
public void execute() {
circuitjs1.mysim.menuPerformed(menuName, itemName);
}
}

View File

@@ -0,0 +1,31 @@
/*
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;
class NJfetElm extends JfetElm {
public NJfetElm(int xx, int yy) { super(xx, yy, false); }
Class getDumpClass() { return JfetElm.class; }
}
class PJfetElm extends JfetElm {
public PJfetElm(int xx, int yy) { super(xx, yy, true); }
Class getDumpClass() { return JfetElm.class; }
}

View File

@@ -0,0 +1,26 @@
/*
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;
class NMosfetElm extends MosfetElm {
public NMosfetElm(int xx, int yy) { super(xx, yy, false); }
Class getDumpClass() { return MosfetElm.class; }
int getShortcut() { return 'N'; }
}

View File

@@ -0,0 +1,28 @@
/*
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;
class NTransistorElm extends TransistorElm {
public NTransistorElm(int xx, int yy) { super(xx, yy, false); }
Class getDumpClass() { return TransistorElm.class; }
int getShortcut() { return 'n'; }
}

View File

@@ -0,0 +1,35 @@
/*
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 NandGateElm extends AndGateElm {
public NandGateElm(int xx, int yy) { super(xx, yy); }
public NandGateElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f, st);
}
boolean isInverting() { return true; }
String getGateName() { return "NAND gate"; }
int getDumpType() { return 151; }
int getShortcut() { return '@'; }
}

View File

@@ -0,0 +1,35 @@
/*
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 NorGateElm extends OrGateElm {
public NorGateElm(int xx, int yy) { super(xx, yy); }
public NorGateElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f, st);
}
String getGateName() { return "NOR gate"; }
boolean isInverting() { return true; }
int getDumpType() { return 153; }
int getShortcut() { return '#'; }
}

View File

@@ -0,0 +1,195 @@
/*
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 OpAmpElm extends CircuitElm {
int opsize, opheight, opwidth, opaddtext;
double maxOut, minOut, gain, gbw;
boolean reset;
final int FLAG_SWAP = 1;
final int FLAG_SMALL = 2;
final int FLAG_LOWGAIN = 4;
public OpAmpElm(int xx, int yy) {
super(xx, yy);
noDiagonal = true;
maxOut = 15;
minOut = -15;
gbw = 1e6;
setSize(sim.smallGridCheckItem.getState() ? 1 : 2);
setGain();
}
public OpAmpElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f);
maxOut = 15;
minOut = -15;
// GBW has no effect in this version of the simulator, but we
// retain it to keep the file format the same
gbw = 1e6;
try {
maxOut = new Double(st.nextToken()).doubleValue();
minOut = new Double(st.nextToken()).doubleValue();
gbw = new Double(st.nextToken()).doubleValue();
} catch (Exception e) {
}
noDiagonal = true;
setSize((f & FLAG_SMALL) != 0 ? 1 : 2);
setGain();
}
void setGain() {
// gain of 100000 breaks e-amp-dfdx.txt
// gain was 1000, but it broke amp-schmitt.txt
gain = ((flags & FLAG_LOWGAIN) != 0) ? 1000 : 100000;
}
String dump() {
return super.dump() + " " + maxOut + " " + minOut + " " + gbw;
}
boolean nonLinear() { return true; }
void draw(Graphics g) {
setBbox(point1, point2, opheight*2);
setVoltageColor(g, volts[0]);
drawThickLine(g, in1p[0], in1p[1]);
setVoltageColor(g, volts[1]);
drawThickLine(g, in2p[0], in2p[1]);
g.setColor(needsHighlight() ? selectColor : lightGrayColor);
setPowerColor(g, true);
drawThickPolygon(g, triangle);
g.setFont(plusFont);
drawCenteredText(g, "-", textp[0].x, textp[0].y-2, true);
drawCenteredText(g, "+", textp[1].x, textp[1].y , true);
setVoltageColor(g, volts[2]);
drawThickLine(g, lead2, point2);
curcount = updateDotCount(current, curcount);
drawDots(g, point2, lead2, curcount);
drawPosts(g);
}
double getPower() { return volts[2]*current; }
Point in1p[], in2p[], textp[];
Polygon triangle;
Font plusFont;
void setSize(int s) {
opsize = s;
opheight = 8*s;
opwidth = 13*s;
flags = (flags & ~FLAG_SMALL) | ((s == 1) ? FLAG_SMALL : 0);
}
void setPoints() {
super.setPoints();
if (dn > 150 && this == sim.dragElm)
setSize(2);
int ww = opwidth;
if (ww > dn/2)
ww = (int) (dn/2);
calcLeads(ww*2);
int hs = opheight*dsign;
if ((flags & FLAG_SWAP) != 0)
hs = -hs;
in1p = newPointArray(2);
in2p = newPointArray(2);
textp = newPointArray(2);
interpPoint2(point1, point2, in1p[0], in2p[0], 0, hs);
interpPoint2(lead1 , lead2, in1p[1], in2p[1], 0, hs);
interpPoint2(lead1 , lead2, textp[0], textp[1], .2, hs);
Point tris[] = newPointArray(2);
interpPoint2(lead1, lead2, tris[0], tris[1], 0, hs*2);
triangle = createPolygon(tris[0], tris[1], lead2);
plusFont = new Font("SansSerif", 0, opsize == 2 ? 14 : 10);
}
int getPostCount() { return 3; }
Point getPost(int n) {
return (n == 0) ? in1p[0] : (n == 1) ? in2p[0] : point2;
}
int getVoltageSourceCount() { return 1; }
void getInfo(String arr[]) {
arr[0] = "op-amp";
arr[1] = "V+ = " + getVoltageText(volts[1]);
arr[2] = "V- = " + getVoltageText(volts[0]);
// sometimes the voltage goes slightly outside range, to make
// convergence easier. so we hide that here.
double vo = Math.max(Math.min(volts[2], maxOut), minOut);
arr[3] = "Vout = " + getVoltageText(vo);
arr[4] = "Iout = " + getCurrentText(getCurrent());
arr[5] = "range = " + getVoltageText(minOut) + " to " +
getVoltageText(maxOut);
}
double lastvd;
void stamp() {
int vn = sim.nodeList.size()+voltSource;
sim.stampNonLinear(vn);
sim.stampMatrix(nodes[2], vn, 1);
}
void doStep() {
double vd = volts[1] - volts[0];
if (Math.abs(lastvd-vd) > .1)
sim.converged = false;
else if (volts[2] > maxOut+.1 || volts[2] < minOut-.1)
sim.converged = false;
double x = 0;
int vn = sim.nodeList.size()+voltSource;
double dx = 0;
if (vd >= maxOut/gain && (lastvd >= 0 || sim.getrand(4) == 1)) {
dx = 1e-4;
x = maxOut - dx*maxOut/gain;
} else if (vd <= minOut/gain && (lastvd <= 0 || sim.getrand(4) == 1)) {
dx = 1e-4;
x = minOut - dx*minOut/gain;
} else
dx = gain;
//System.out.println("opamp " + vd + " " + volts[2] + " " + dx + " " + x + " " + lastvd + " " + sim.converged);
// newton-raphson
sim.stampMatrix(vn, nodes[0], dx);
sim.stampMatrix(vn, nodes[1], -dx);
sim.stampMatrix(vn, nodes[2], 1);
sim.stampRightSide(vn, x);
lastvd = vd;
/*if (sim.converged)
System.out.println((volts[1]-volts[0]) + " " + volts[2] + " " + initvd);*/
}
// there is no current path through the op-amp inputs, but there
// is an indirect path through the output to ground.
boolean getConnection(int n1, int n2) { return false; }
boolean hasGroundConnection(int n1) {
return (n1 == 2);
}
double getVoltageDiff() { return volts[2] - volts[1]; }
int getDumpType() { return 'a'; }
public EditInfo getEditInfo(int n) {
if (n == 0)
return new EditInfo("Max Output (V)", maxOut, 1, 20);
if (n == 1)
return new EditInfo("Min Output (V)", minOut, -20, 0);
return null;
}
public void setEditValue(int n, EditInfo ei) {
if (n == 0)
maxOut = ei.value;
if (n == 1)
minOut = ei.value;
}
int getShortcut() { return 'a'; }
}

View File

@@ -0,0 +1,29 @@
/*
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;
class OpAmpSwapElm extends OpAmpElm {
public OpAmpSwapElm(int xx, int yy) {
super(xx, yy);
flags |= FLAG_SWAP;
}
Class getDumpClass() { return OpAmpElm.class; }
int getShortcut() { return 'A'; }
}

View File

@@ -0,0 +1,74 @@
/*
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 OrGateElm extends GateElm {
public OrGateElm(int xx, int yy) { super(xx, yy); }
public OrGateElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f, st);
}
String getGateName() { return "OR gate"; }
void setPoints() {
super.setPoints();
// 0-15 = top curve, 16 = right, 17-32=bottom curve,
// 33-37 = left curve
Point triPoints[] = newPointArray(38);
if (this instanceof XorGateElm)
linePoints = new Point[5];
int i;
for (i = 0; i != 16; i++) {
double a = i/16.;
double b = 1-a*a;
interpPoint2(lead1, lead2,
triPoints[i], triPoints[32-i],
.5+a/2, b*hs2);
}
double ww2 = (ww == 0) ? dn*2 : ww*2;
for (i = 0; i != 5; i++) {
double a = (i-2)/2.;
double b = 4*(1-a*a)-2;
interpPoint(lead1, lead2,
triPoints[33+i], b/(ww2), a*hs2);
if (this instanceof XorGateElm)
linePoints[i] = interpPoint(lead1, lead2,
(b-5)/(ww2), a*hs2);
}
triPoints[16] = new Point(lead2);
if (isInverting()) {
pcircle = interpPoint(point1, point2, .5+(ww+4)/dn);
lead2 = interpPoint(point1, point2, .5+(ww+8)/dn);
}
gatePoly = createPolygon(triPoints);
}
boolean calcFunction() {
int i;
boolean f = false;
for (i = 0; i != inputCount; i++)
f |= getInput(i);
return f;
}
int getDumpType() { return 152; }
int getShortcut() { return '3'; }
}

View File

@@ -0,0 +1,84 @@
/*
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 OutputElm extends CircuitElm {
final int FLAG_VALUE = 1;
public OutputElm(int xx, int yy) { super(xx, yy); }
public OutputElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f);
}
int getDumpType() { return 'O'; }
int getPostCount() { return 1; }
void setPoints() {
super.setPoints();
lead1 = new Point();
}
void draw(Graphics g) {
boolean selected = (needsHighlight() || sim.plotYElm == this);
Font f = new Font("SansSerif", selected ? Font.BOLD : 0, 14);
g.setFont(f);
g.setColor(selected ? selectColor : whiteColor);
String s = (flags & FLAG_VALUE) != 0 ? getVoltageText(volts[0]) : "out";
// FontMetrics fm = g.getFontMetrics();
if (this == sim.plotXElm)
s = "X";
if (this == sim.plotYElm)
s = "Y";
interpPoint(point1, point2, lead1, 1-((int)g.context.measureText(s).getWidth()/2+8)/dn);
setBbox(point1, lead1, 0);
drawCenteredText(g, s, x2, y2, true);
setVoltageColor(g, volts[0]);
if (selected)
g.setColor(selectColor);
drawThickLine(g, point1, lead1);
drawPosts(g);
}
double getVoltageDiff() { return volts[0]; }
void getInfo(String arr[]) {
arr[0] = "output";
arr[1] = "V = " + getVoltageText(volts[0]);
}
public EditInfo getEditInfo(int n) {
if (n == 0) {
EditInfo ei = new EditInfo("", 0, -1, -1);
ei.checkbox = new Checkbox("Show Voltage",
(flags & FLAG_VALUE) != 0);
return ei;
}
return null;
}
public void setEditValue(int n, EditInfo ei) {
if (n == 0)
flags = (ei.checkbox.getState()) ?
(flags | FLAG_VALUE) :
(flags & ~FLAG_VALUE);
}
void drawHandles(Graphics g, Color c) {
g.setColor(c);
g.fillRect(x-3, y-3, 7, 7);
}
}

View File

@@ -0,0 +1,26 @@
/*
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;
class PMosfetElm extends MosfetElm {
public PMosfetElm(int xx, int yy) { super(xx, yy, true); }
Class getDumpClass() { return MosfetElm.class; }
int getShortcut() { return 'P'; }
}

View File

@@ -0,0 +1,28 @@
/*
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;
class PTransistorElm extends TransistorElm {
public PTransistorElm(int xx, int yy) { super(xx, yy, true); }
Class getDumpClass() { return TransistorElm.class; }
int getShortcut() { return 'p'; }
}

View File

@@ -0,0 +1,75 @@
/*
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 PhaseCompElm extends ChipElm {
public PhaseCompElm(int xx, int yy) { super(xx, yy); }
public PhaseCompElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f, st);
}
String getChipName() { return "phase comparator"; }
void setupPins() {
sizeX = 2;
sizeY = 2;
pins = new Pin[3];
pins[0] = new Pin(0, SIDE_W, "I1");
pins[1] = new Pin(1, SIDE_W, "I2");
pins[2] = new Pin(0, SIDE_E, "O");
pins[2].output = true;
}
boolean nonLinear() { return true; }
void stamp() {
int vn = sim.nodeList.size()+pins[2].voltSource;
sim.stampNonLinear(vn);
sim.stampNonLinear(0);
sim.stampNonLinear(nodes[2]);
}
boolean ff1, ff2;
void doStep() {
boolean v1 = volts[0] > 2.5;
boolean v2 = volts[1] > 2.5;
if (v1 && !pins[0].value)
ff1 = true;
if (v2 && !pins[1].value)
ff2 = true;
if (ff1 && ff2)
ff1 = ff2 = false;
double out = (ff1) ? 5 : (ff2) ? 0 : -1;
//System.out.println(out + " " + v1 + " " + v2);
if (out != -1)
sim.stampVoltageSource(0, nodes[2], pins[2].voltSource, out);
else {
// tie current through output pin to 0
int vn = sim.nodeList.size()+pins[2].voltSource;
sim.stampMatrix(vn, vn, 1);
}
pins[0].value = v1;
pins[1].value = v2;
}
int getPostCount() { return 3; }
int getVoltageSourceCount() { return 1; }
int getDumpType() { return 161; }
}

View File

@@ -0,0 +1,93 @@
/*
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;
// contributed by Edward Calver
class PisoShiftElm extends ChipElm {
boolean hasReset() {return false;}
public PisoShiftElm(int xx, int yy) { super(xx, yy); }
public PisoShiftElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f, st);
}
short data=0;//Lack of unsigned types sucks
boolean clockstate=false;
boolean modestate=false;
String getChipName() { return "PISO shift register"; }
void setupPins() {
sizeX = 10;
sizeY = 3;
pins = new Pin[getPostCount()];
pins[0] = new Pin(1, SIDE_W, "L");
pins[1] = new Pin(2, SIDE_W, "");
pins[1].clock=true;
pins[2] = new Pin(1, SIDE_N, "I7");
pins[3] = new Pin(2, SIDE_N, "I6");
pins[4] = new Pin(3, SIDE_N, "I5");
pins[5] = new Pin(4, SIDE_N, "I4");
pins[6] = new Pin(5, SIDE_N, "I3");
pins[7] = new Pin(6, SIDE_N, "I2");
pins[8] = new Pin(7, SIDE_N, "I1");
pins[9] = new Pin(8, SIDE_N, "I0");
pins[10] = new Pin(1, SIDE_E, "Q");
pins[10].output=true;
}
int getPostCount() {
return 11;
}
int getVoltageSourceCount() {return 1;}
void execute() {
if(pins[0].value&&!modestate)
{
modestate=true;
data=0;
if(pins[2].value)data+=128;
if(pins[3].value)data+=64;
if(pins[4].value)data+=32;
if(pins[5].value)data+=16;
if(pins[6].value)data+=8;
if(pins[7].value)data+=4;
if(pins[8].value)data+=2;
if(pins[9].value)data+=1;
}
else if(pins[1].value&&!clockstate)
{
clockstate=true;
if((data&1)==0)pins[10].value=false;
else pins[10].value=true;
data=(byte)(data>>>1);
}
if(!pins[0].value)modestate=false;
if(!pins[1].value)clockstate=false;
}
int getDumpType() { return 186; }
}

View File

@@ -0,0 +1,45 @@
/*
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;
public class Point {
public int x;
public int y;
public Point(int i, int j) {
x=i;
y=j;
}
public Point(Point p) {
x=p.x;
y=p.y;
}
public Point() {
x=0;
y=0;
}
public void setLocation(Point p) {
x=p.x;
y=p.y;
}
}

View File

@@ -0,0 +1,71 @@
// Extracted from file
// Copyright 1995-2006 Sun Microsystems, Inc. All Rights Reserved
//
// This program 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.
//
// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
package com.lushprojects.circuitjs1.client;
// via http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/awt/Polygon.java
//import java.util.ArrayList;
class Polygon {
// ArrayList<Point> poly;
private static final int MIN_LENGTH = 4;
public int npoints;
public int xpoints[];
public int ypoints[];
public Polygon(){
// poly = new ArrayList<Point>();
xpoints = new int[MIN_LENGTH];
ypoints = new int[MIN_LENGTH];
}
// public void addPoint(int x, int y){
// poly.add(new Point(x,y));
// }
public void addPoint(int x, int y) {
if (npoints >= xpoints.length || npoints >= ypoints.length) {
int newLength = npoints * 2;
// Make sure that newLength will be greater than MIN_LENGTH and
// aligned to the power of 2
if (newLength < MIN_LENGTH) {
newLength = MIN_LENGTH;
} else if ((newLength & (newLength - 1)) != 0) {
newLength = Integer.highestOneBit(newLength);
}
xpoints = expand(xpoints, newLength);
ypoints = expand(ypoints, newLength);
}
xpoints[npoints] = x;
ypoints[npoints] = y;
npoints++;
// if (bounds != null) {
// updateBounds(x, y);
// }
}
private int[] expand(int[] in, int newlen) {
int[] out=new int[newlen];
for(int i=0; i<in.length; i++)
out[i]=in[i];
return out;
}
}

View File

@@ -0,0 +1,243 @@
/*
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.awt.event.*;
//import java.util.StringTokenizer;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.Command;
import com.google.gwt.event.dom.client.MouseWheelEvent;
import com.google.gwt.event.dom.client.MouseWheelHandler;
class PotElm extends CircuitElm implements Command, MouseWheelHandler {
double position, maxResistance, resistance1, resistance2;
double current1, current2, current3;
double curcount1, curcount2, curcount3;
Scrollbar slider;
Label label;
String sliderText;
public PotElm(int xx, int yy) {
super(xx, yy);
setup();
maxResistance = 1000;
position = .5;
sliderText = "Resistance";
createSlider();
}
public PotElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f);
maxResistance = new Double(st.nextToken()).doubleValue();
position = new Double(st.nextToken()).doubleValue();
sliderText = st.nextToken();
while (st.hasMoreTokens())
sliderText += ' ' + st.nextToken();
createSlider();
}
void setup() {
}
int getPostCount() { return 3; }
int getDumpType() { return 174; }
Point getPost(int n) {
return (n == 0) ? point1 : (n == 1) ? point2 : post3;
}
String dump() { return super.dump() + " " + maxResistance + " " +
position + " " + sliderText; }
void createSlider() {
sim.addWidgetToVerticalPanel(label = new Label(sliderText));
label.addStyleName("topSpace");
int value = (int) (position*100);
sim.addWidgetToVerticalPanel(slider = new Scrollbar(Scrollbar.HORIZONTAL, value, 1, 0, 101, this, this));
// sim.verticalPanel.validate();
// slider.addAdjustmentListener(this);
}
public void execute() {
sim.analyzeFlag = true;
setPoints();
}
void delete() {
sim.removeWidgetFromVerticalPanel(label);
sim.removeWidgetFromVerticalPanel(slider);
}
Point post3, corner2, arrowPoint, midpoint, arrow1, arrow2;
Point ps3, ps4;
int bodyLen;
void setPoints() {
super.setPoints();
int offset = 0;
if (abs(dx) > abs(dy)) {
dx = sim.snapGrid(dx/2)*2;
point2.x = x2 = point1.x + dx;
offset = (dx < 0) ? dy : -dy;
point2.y = point1.y;
} else {
dy = sim.snapGrid(dy/2)*2;
point2.y = y2 = point1.y + dy;
offset = (dy > 0) ? dx : -dx;
point2.x = point1.x;
}
if (offset == 0)
offset = sim.gridSize;
dn = distance(point1, point2);
int bodyLen = 32;
calcLeads(bodyLen);
position = slider.getValue()*.0099+.005;
int soff = (int) ((position-.5)*bodyLen);
//int offset2 = offset - sign(offset)*4;
post3 = interpPoint(point1, point2, .5, offset);
corner2 = interpPoint(point1, point2, soff/dn+.5, offset);
arrowPoint = interpPoint(point1, point2, soff/dn+.5,
8*sign(offset));
midpoint = interpPoint(point1, point2, soff/dn+.5);
arrow1 = new Point();
arrow2 = new Point();
double clen = abs(offset)-8;
interpPoint2(corner2, arrowPoint, arrow1, arrow2, (clen-8)/clen, 8);
ps3 = new Point();
ps4 = new Point();
}
void draw(Graphics g) {
int segments = 16;
int i;
int ox = 0;
int hs = sim.euroResistorCheckItem.getState() ? 6 : 8;
double v1 = volts[0];
double v2 = volts[1];
double v3 = volts[2];
setBbox(point1, point2, hs);
draw2Leads(g);
setPowerColor(g, true);
double segf = 1./segments;
int divide = (int) (segments*position);
if (!sim.euroResistorCheckItem.getState()) {
// draw zigzag
for (i = 0; i != segments; i++) {
int nx = 0;
switch (i & 3) {
case 0: nx = 1; break;
case 2: nx = -1; break;
default: nx = 0; break;
}
double v = v1+(v3-v1)*i/divide;
if (i >= divide)
v = v3+(v2-v3)*(i-divide)/(segments-divide);
setVoltageColor(g, v);
interpPoint(lead1, lead2, ps1, i*segf, hs*ox);
interpPoint(lead1, lead2, ps2, (i+1)*segf, hs*nx);
drawThickLine(g, ps1, ps2);
ox = nx;
}
} else {
// draw rectangle
setVoltageColor(g, v1);
interpPoint2(lead1, lead2, ps1, ps2, 0, hs);
drawThickLine(g, ps1, ps2);
for (i = 0; i != segments; i++) {
double v = v1+(v3-v1)*i/divide;
if (i >= divide)
v = v3+(v2-v3)*(i-divide)/(segments-divide);
setVoltageColor(g, v);
interpPoint2(lead1, lead2, ps1, ps2, i*segf, hs);
interpPoint2(lead1, lead2, ps3, ps4, (i+1)*segf, hs);
drawThickLine(g, ps1, ps3);
drawThickLine(g, ps2, ps4);
}
interpPoint2(lead1, lead2, ps1, ps2, 1, hs);
drawThickLine(g, ps1, ps2);
}
setVoltageColor(g, v3);
drawThickLine(g, post3, corner2);
drawThickLine(g, corner2, arrowPoint);
drawThickLine(g, arrow1, arrowPoint);
drawThickLine(g, arrow2, arrowPoint);
curcount1 = updateDotCount(current1, curcount1);
curcount2 = updateDotCount(current2, curcount2);
curcount3 = updateDotCount(current3, curcount3);
if (sim.dragElm != this) {
drawDots(g, point1, midpoint, curcount1);
drawDots(g, point2, midpoint, curcount2);
drawDots(g, post3, corner2, curcount3);
drawDots(g, corner2, midpoint,
curcount3+distance(post3, corner2));
}
drawPosts(g);
}
void calculateCurrent() {
current1 = (volts[0]-volts[2])/resistance1;
current2 = (volts[1]-volts[2])/resistance2;
current3 = -current1-current2;
}
void stamp() {
resistance1 = maxResistance*position;
resistance2 = maxResistance*(1-position);
sim.stampResistor(nodes[0], nodes[2], resistance1);
sim.stampResistor(nodes[2], nodes[1], resistance2);
}
void getInfo(String arr[]) {
arr[0] = "potentiometer";
arr[1] = "Vd = " + getVoltageDText(getVoltageDiff());
arr[2] = "R1 = " + getUnitText(resistance1, sim.ohmString);
arr[3] = "R2 = " + getUnitText(resistance2, sim.ohmString);
arr[4] = "I1 = " + getCurrentDText(current1);
arr[5] = "I2 = " + getCurrentDText(current2);
}
public EditInfo getEditInfo(int n) {
// ohmString doesn't work here on linux
if (n == 0)
return new EditInfo("Resistance (ohms)", maxResistance, 0, 0);
if (n == 1) {
EditInfo ei = new EditInfo("Slider Text", 0, -1, -1);
ei.text = sliderText;
return ei;
}
return null;
}
public void setEditValue(int n, EditInfo ei) {
if (n == 0)
maxResistance = ei.value;
if (n == 1) {
sliderText = ei.textf.getText();
label.setText(sliderText);
sim.setiFrameHeight();
}
}
void setMouseElm(boolean v) {
super.setMouseElm(v);
if (slider!=null)
slider.draw();
}
public void onMouseWheel(MouseWheelEvent e) {
if (slider!=null)
slider.onMouseWheel(e);
}
}

View File

@@ -0,0 +1,99 @@
/*
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 ProbeElm extends CircuitElm {
static final int FLAG_SHOWVOLTAGE = 1;
public ProbeElm(int xx, int yy) { super(xx, yy); }
public ProbeElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f);
}
int getDumpType() { return 'p'; }
Point center;
void setPoints() {
super.setPoints();
// swap points so that we subtract higher from lower
if (point2.y < point1.y) {
Point x = point1;
point1 = point2;
point2 = x;
}
center = interpPoint(point1, point2, .5);
}
void draw(Graphics g) {
int hs = 8;
setBbox(point1, point2, hs);
boolean selected = (needsHighlight() || sim.plotYElm == this);
double len = (selected || sim.dragElm == this) ? 16 : dn-32;
calcLeads((int) len);
setVoltageColor(g, volts[0]);
if (selected)
g.setColor(selectColor);
drawThickLine(g, point1, lead1);
setVoltageColor(g, volts[1]);
if (selected)
g.setColor(selectColor);
drawThickLine(g, lead2, point2);
Font f = new Font("SansSerif", Font.BOLD, 14);
g.setFont(f);
if (this == sim.plotXElm)
drawCenteredText(g, "X", center.x, center.y, true);
if (this == sim.plotYElm)
drawCenteredText(g, "Y", center.x, center.y, true);
if (mustShowVoltage()) {
String s = getShortUnitText(volts[0], "V");
drawValues(g, s, 4);
}
drawPosts(g);
}
boolean mustShowVoltage() {
return (flags & FLAG_SHOWVOLTAGE) != 0;
}
void getInfo(String arr[]) {
arr[0] = "scope probe";
arr[1] = "Vd = " + getVoltageText(getVoltageDiff());
}
boolean getConnection(int n1, int n2) { return false; }
public EditInfo getEditInfo(int n) {
if (n == 0) {
EditInfo ei = new EditInfo("", 0, -1, -1);
ei.checkbox = new Checkbox("Show Voltage", mustShowVoltage());
return ei;
}
return null;
}
public void setEditValue(int n, EditInfo ei) {
if (n == 0) {
if (ei.checkbox.getState())
flags = FLAG_SHOWVOLTAGE;
else
flags &= ~FLAG_SHOWVOLTAGE;
}
}
}

View File

@@ -0,0 +1,26 @@
/*
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;
class PushSwitchElm extends SwitchElm {
public PushSwitchElm(int xx, int yy) { super(xx, yy, true); }
Class getDumpClass() { return SwitchElm.class; }
int getShortcut() { return 0; }
}

View File

@@ -0,0 +1,64 @@
/*
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.util.HashMap;
import java.util.Map;
import com.google.gwt.http.client.URL;
public class QueryParameters
{
private Map map = new HashMap();
public QueryParameters()
{
String search = getQueryString();
if ((search != null) && (search.length() > 0))
{
String[] nameValues = search.substring(1).split("&");
for (int i = 0; i < nameValues.length; i++)
{
String[] pair = nameValues[i].split("=");
map.put(pair[0], URL.decode(pair[1]));
}
}
}
public String getValue(String key)
{
return (String) map.get(key);
}
public boolean getBooleanValue(String key, boolean def){
String val=getValue(key);
if (val==null)
return def;
else
return (val=="1" || val.equalsIgnoreCase("true"));
}
private native String getQueryString()
/*-{
return $wnd.location.search;
}-*/;
}

View File

@@ -0,0 +1,91 @@
/*
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 com.google.gwt.i18n.client.NumberFormat;
class RailElm extends VoltageElm {
public RailElm(int xx, int yy) { super(xx, yy, WF_DC); }
RailElm(int xx, int yy, int wf) { super(xx, yy, wf); }
public RailElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f, st);
}
final int FLAG_CLOCK = 1;
int getDumpType() { return 'R'; }
int getPostCount() { return 1; }
void setPoints() {
super.setPoints();
lead1 = interpPoint(point1, point2, 1-circleSize/dn);
}
void draw(Graphics g) {
String s;
setBbox(point1, point2, circleSize);
setVoltageColor(g, volts[0]);
drawThickLine(g, point1, lead1);
boolean clock = waveform == WF_SQUARE && (flags & FLAG_CLOCK) != 0;
if (waveform == WF_DC || waveform == WF_VAR || clock) {
// IES
// Font f = new Font("SansSerif", 0, 12);
// g.setFont(f);
g.setColor(needsHighlight() ? selectColor : whiteColor);
setPowerColor(g, false);
double v = getVoltage();
// String s = getShortUnitText(v, "V");
if (Math.abs(v) < 1)
s = showFormat.format(v)+" V";
else
s = getShortUnitText(v, "V");
if (getVoltage() > 0)
s = "+" + s;
// ies
if (this instanceof AntennaElm)
s = "Ant";
if (clock)
s = "CLK";
drawCenteredText(g, s, x2, y2, true);
} else {
drawWaveform(g, point2);
}
drawPosts(g);
curcount = updateDotCount(-current, curcount);
if (sim.dragElm != this)
drawDots(g, point1, lead1, curcount);
}
double getVoltageDiff() { return volts[0]; }
void stamp() {
if (waveform == WF_DC)
sim.stampVoltageSource(0, nodes[0], voltSource, getVoltage());
else
sim.stampVoltageSource(0, nodes[0], voltSource);
}
void doStep() {
if (waveform != WF_DC)
sim.updateVoltageSource(0, nodes[0], voltSource, getVoltage());
}
boolean hasGroundConnection(int n1) { return true; }
int getShortcut() { return 'V'; }
void drawHandles(Graphics g, Color c) {
g.setColor(c);
g.fillRect(x-3, y-3, 7, 7);
}
}

View File

@@ -0,0 +1,151 @@
// Extracted from file
// Copyright 1995-2006 Sun Microsystems, Inc. All Rights Reserved
//
// This program 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.
//
// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
package com.lushprojects.circuitjs1.client;
// Via http://grepcode.com/file_/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/awt/Rectangle.java/?v=source
public class Rectangle {
int x;
int y;
int width;
int height;
public Rectangle(){
x=0;
y=0;
width=0;
height=0;
}
public Rectangle(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public Rectangle(Rectangle r) {
this(r.x, r.y, r.width, r.height);
}
public void setBounds(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public boolean contains(int X, int Y) {
int w = this.width;
int h = this.height;
if ((w | h) < 0) {
// At least one of the dimensions is negative...
return false;
}
// Note: if either dimension is zero, tests below must return false...
int x = this.x;
int y = this.y;
if (X < x || Y < y) {
return false;
}
w += x;
h += y;
// overflow || intersect
return ((w < x || w > X) &&
(h < y || h > Y));
}
public void move(int x, int y) {
this.x = x;
this.y = y;
}
public boolean intersects(Rectangle r) {
int tw = this.width;
int th = this.height;
int rw = r.width;
int rh = r.height;
if (rw <= 0 || rh <= 0 || tw <= 0 || th <= 0) {
return false;
}
int tx = this.x;
int ty = this.y;
int rx = r.x;
int ry = r.y;
rw += rx;
rh += ry;
tw += tx;
th += ty;
// overflow || intersect
return ((rw < rx || rw > tx) &&
(rh < ry || rh > ty) &&
(tw < tx || tw > rx) &&
(th < ty || th > ry));
}
public Rectangle union(Rectangle r) {
long tx2 = this.width;
long ty2 = this.height;
if ((tx2 | ty2) < 0) {
// This rectangle has negative dimensions...
// If r has non-negative dimensions then it is the answer.
// If r is non-existant (has a negative dimension), then both
// are non-existant and we can return any non-existant rectangle
// as an answer. Thus, returning r meets that criterion.
// Either way, r is our answer.
return new Rectangle(r);
}
long rx2 = r.width;
long ry2 = r.height;
if ((rx2 | ry2) < 0) {
return new Rectangle(this);
}
int tx1 = this.x;
int ty1 = this.y;
tx2 += tx1;
ty2 += ty1;
int rx1 = r.x;
int ry1 = r.y;
rx2 += rx1;
ry2 += ry1;
if (tx1 > rx1) tx1 = rx1;
if (ty1 > ry1) ty1 = ry1;
if (tx2 < rx2) tx2 = rx2;
if (ty2 < ry2) ty2 = ry2;
tx2 -= tx1;
ty2 -= ty1;
// tx2,ty2 will never underflow since both original rectangles
// were already proven to be non-empty
// they might overflow, though...
if (tx2 > Integer.MAX_VALUE) tx2 = Integer.MAX_VALUE;
if (ty2 > Integer.MAX_VALUE) ty2 = Integer.MAX_VALUE;
return new Rectangle(tx1, ty1, (int) tx2, (int) ty2);
}
public boolean equals(Object obj) {
if (obj instanceof Rectangle) {
Rectangle r = (Rectangle)obj;
return ((x == r.x) &&
(y == r.y) &&
(width == r.width) &&
(height == r.height));
}
return super.equals(obj);
}
}

View File

@@ -0,0 +1,331 @@
/*
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;
// 0 = switch
// 1 = switch end 1
// 2 = switch end 2
// ...
// 3n = coil
// 3n+1 = coil
// 3n+2 = end of coil resistor
class RelayElm extends CircuitElm {
double inductance;
Inductor ind;
double r_on, r_off, onCurrent;
Point coilPosts[], coilLeads[], swposts[][], swpoles[][], ptSwitch[];
Point lines[];
double coilCurrent, switchCurrent[], coilCurCount, switchCurCount[];
double d_position, coilR;
int i_position;
int poleCount;
int openhs;
final int nSwitch0 = 0;
final int nSwitch1 = 1;
final int nSwitch2 = 2;
int nCoil1, nCoil2, nCoil3;
final int FLAG_SWAP_COIL = 1;
public RelayElm(int xx, int yy) {
super(xx, yy);
ind = new Inductor(sim);
inductance = .2;
ind.setup(inductance, 0, Inductor.FLAG_BACK_EULER);
noDiagonal = true;
onCurrent = .02;
r_on = .05;
r_off = 1e6;
coilR = 20;
coilCurrent = coilCurCount = 0;
poleCount = 1;
setupPoles();
}
public RelayElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f);
poleCount = new Integer(st.nextToken()).intValue();
inductance = new Double(st.nextToken()).doubleValue();
coilCurrent = new Double(st.nextToken()).doubleValue();
r_on = new Double(st.nextToken()).doubleValue();
r_off = new Double(st.nextToken()).doubleValue();
onCurrent = new Double(st.nextToken()).doubleValue();
coilR = new Double(st.nextToken()).doubleValue();
noDiagonal = true;
ind = new Inductor(sim);
ind.setup(inductance, coilCurrent, Inductor.FLAG_BACK_EULER);
setupPoles();
}
void setupPoles() {
nCoil1 = 3*poleCount;
nCoil2 = nCoil1+1;
nCoil3 = nCoil1+2;
if (switchCurrent == null || switchCurrent.length != poleCount) {
switchCurrent = new double[poleCount];
switchCurCount = new double[poleCount];
}
}
int getDumpType() { return 178; }
String dump() {
return super.dump() + " " + poleCount + " " +
inductance + " " + coilCurrent + " " +
r_on + " " + r_off + " " + onCurrent + " " + coilR;
}
void draw(Graphics g) {
int i, p;
for (i = 0; i != 2; i++) {
setVoltageColor(g, volts[nCoil1+i]);
drawThickLine(g, coilLeads[i], coilPosts[i]);
}
int x = ((flags & FLAG_SWAP_COIL) != 0) ? 1 : 0;
drawCoil(g, dsign*6, coilLeads[x], coilLeads[1-x],
volts[nCoil1+x], volts[nCoil2-x]);
// draw lines
g.setColor(Color.darkGray);
for (i = 0; i != poleCount; i++) {
if (i == 0)
interpPoint(point1, point2, lines[i*2 ], .5,
openhs*2+5*dsign-i*openhs*3);
else
interpPoint(point1, point2, lines[i*2], .5,
(int) (openhs*(-i*3+3-.5+d_position))+5*dsign);
interpPoint(point1, point2, lines[i*2+1], .5,
(int) (openhs*(-i*3-.5+d_position))-5*dsign);
g.drawLine(lines[i*2].x, lines[i*2].y, lines[i*2+1].x, lines[i*2+1].y);
}
for (p = 0; p != poleCount; p++) {
int po = p*3;
for (i = 0; i != 3; i++) {
// draw lead
setVoltageColor(g, volts[nSwitch0+po+i]);
drawThickLine(g, swposts[p][i], swpoles[p][i]);
}
interpPoint(swpoles[p][1], swpoles[p][2], ptSwitch[p], d_position);
//setVoltageColor(g, volts[nSwitch0]);
g.setColor(Color.lightGray);
drawThickLine(g, swpoles[p][0], ptSwitch[p]);
switchCurCount[p] = updateDotCount(switchCurrent[p],
switchCurCount[p]);
drawDots(g, swposts[p][0], swpoles[p][0], switchCurCount[p]);
if (i_position != 2)
drawDots(g, swpoles[p][i_position+1], swposts[p][i_position+1],
switchCurCount[p]);
}
coilCurCount = updateDotCount(coilCurrent, coilCurCount);
drawDots(g, coilPosts[0], coilLeads[0], coilCurCount);
drawDots(g, coilLeads[0], coilLeads[1], coilCurCount);
drawDots(g, coilLeads[1], coilPosts[1], coilCurCount);
drawPosts(g);
setBbox(coilPosts[0], coilLeads[1], 0);
adjustBbox(swpoles[poleCount-1][0], swposts[poleCount-1][1]); // XXX
}
void setPoints() {
super.setPoints();
setupPoles();
allocNodes();
openhs = -dsign*16;
// switch
calcLeads(32);
swposts = new Point[poleCount][3];
swpoles = new Point[poleCount][3];
int i, j;
for (i = 0; i != poleCount; i++) {
for (j = 0; j != 3; j++) {
swposts[i][j] = new Point();
swpoles[i][j] = new Point();
}
interpPoint(lead1, lead2, swpoles[i][0], 0, -openhs*3*i);
interpPoint(lead1, lead2, swpoles[i][1], 1, -openhs*3*i-openhs);
interpPoint(lead1, lead2, swpoles[i][2], 1, -openhs*3*i+openhs);
interpPoint(point1, point2, swposts[i][0], 0, -openhs*3*i);
interpPoint(point1, point2, swposts[i][1], 1, -openhs*3*i-openhs);
interpPoint(point1, point2, swposts[i][2], 1, -openhs*3*i+openhs);
}
// coil
coilPosts = newPointArray(2);
coilLeads = newPointArray(2);
ptSwitch = newPointArray(poleCount);
int x = ((flags & FLAG_SWAP_COIL) != 0) ? 1 : 0;
interpPoint(point1, point2, coilPosts[0], x, openhs*2);
interpPoint(point1, point2, coilPosts[1], x, openhs*3);
interpPoint(point1, point2, coilLeads[0], .5, openhs*2);
interpPoint(point1, point2, coilLeads[1], .5, openhs*3);
// lines
lines = newPointArray(poleCount*2);
}
Point getPost(int n) {
if (n < 3*poleCount)
return swposts[n / 3][n % 3];
return coilPosts[n-3*poleCount];
}
int getPostCount() { return 2+poleCount*3; }
int getInternalNodeCount() { return 1; }
void reset() {
super.reset();
ind.reset();
coilCurrent = coilCurCount = 0;
int i;
for (i = 0; i != poleCount; i++)
switchCurrent[i] = switchCurCount[i] = 0;
}
double a1, a2, a3, a4;
void stamp() {
// inductor from coil post 1 to internal node
ind.stamp(nodes[nCoil1], nodes[nCoil3]);
// resistor from internal node to coil post 2
sim.stampResistor(nodes[nCoil3], nodes[nCoil2], coilR);
int i;
for (i = 0; i != poleCount*3; i++)
sim.stampNonLinear(nodes[nSwitch0+i]);
}
void startIteration() {
ind.startIteration(volts[nCoil1]-volts[nCoil3]);
// magic value to balance operate speed with reset speed semi-realistically
double magic = 1.3;
double pmult = Math.sqrt(magic+1);
double p = coilCurrent*pmult/onCurrent;
d_position = Math.abs(p*p) - 1.3;
if (d_position < 0)
d_position = 0;
if (d_position > 1)
d_position = 1;
if (d_position < .1)
i_position = 0;
else if (d_position > .9)
i_position = 1;
else
i_position = 2;
//System.out.println("ind " + this + " " + current + " " + voltdiff);
}
// we need this to be able to change the matrix for each step
boolean nonLinear() { return true; }
void doStep() {
double voltdiff = volts[nCoil1]-volts[nCoil3];
ind.doStep(voltdiff);
int p;
for (p = 0; p != poleCount*3; p += 3) {
sim.stampResistor(nodes[nSwitch0+p], nodes[nSwitch1+p],
i_position == 0 ? r_on : r_off);
sim.stampResistor(nodes[nSwitch0+p], nodes[nSwitch2+p],
i_position == 1 ? r_on : r_off);
}
}
void calculateCurrent() {
double voltdiff = volts[nCoil1]-volts[nCoil3];
coilCurrent = ind.calculateCurrent(voltdiff);
// actually this isn't correct, since there is a small amount
// of current through the switch when off
int p;
for (p = 0; p != poleCount; p++) {
if (i_position == 2)
switchCurrent[p] = 0;
else
switchCurrent[p] =
(volts[nSwitch0+p*3]-volts[nSwitch1+p*3+i_position])/r_on;
}
}
void getInfo(String arr[]) {
arr[0] = i_position == 0 ? "relay (off)" :
i_position == 1 ? "relay (on)" : "relay";
int i;
int ln = 1;
for (i = 0; i != poleCount; i++)
arr[ln++] = "I" + (i+1) + " = " + getCurrentDText(switchCurrent[i]);
arr[ln++] = "coil I = " + getCurrentDText(coilCurrent);
arr[ln++] = "coil Vd = " +
getVoltageDText(volts[nCoil1] - volts[nCoil2]);
}
public EditInfo getEditInfo(int n) {
if (n == 0)
return new EditInfo("Inductance (H)", inductance, 0, 0);
if (n == 1)
return new EditInfo("On Resistance (ohms)", r_on, 0, 0);
if (n == 2)
return new EditInfo("Off Resistance (ohms)", r_off, 0, 0);
if (n == 3)
return new EditInfo("On Current (A)", onCurrent, 0, 0);
if (n == 4)
return new EditInfo("Number of Poles", poleCount, 1, 4).
setDimensionless();
if (n == 5)
return new EditInfo("Coil Resistance (ohms)", coilR, 0, 0);
if (n == 6) {
EditInfo ei = new EditInfo("", 0, -1, -1);
ei.checkbox = new Checkbox("Swap Coil Direction",
(flags & FLAG_SWAP_COIL) != 0);
return ei;
}
return null;
}
public void setEditValue(int n, EditInfo ei) {
if (n == 0 && ei.value > 0) {
inductance = ei.value;
ind.setup(inductance, coilCurrent, Inductor.FLAG_BACK_EULER);
}
if (n == 1 && ei.value > 0)
r_on = ei.value;
if (n == 2 && ei.value > 0)
r_off = ei.value;
if (n == 3 && ei.value > 0)
onCurrent = ei.value;
if (n == 4 && ei.value >= 1) {
poleCount = (int) ei.value;
setPoints();
}
if (n == 5 && ei.value > 0)
coilR = ei.value;
if (n == 6) {
if (ei.checkbox.getState())
flags |= FLAG_SWAP_COIL;
else
flags &= ~FLAG_SWAP_COIL;
setPoints();
}
}
boolean getConnection(int n1, int n2) {
return (n1 / 3 == n2 / 3);
}
int getShortcut() { return 'R'; }
}

View File

@@ -0,0 +1,144 @@
/*
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 com.google.gwt.canvas.dom.client.CanvasGradient;
//import java.awt.*;
//import java.util.StringTokenizer;
class ResistorElm extends CircuitElm {
double resistance;
public ResistorElm(int xx, int yy) { super(xx, yy); resistance = 100; }
public ResistorElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f);
resistance = new Double(st.nextToken()).doubleValue();
}
int getDumpType() { return 'r'; }
String dump() {
return super.dump() + " " + resistance;
}
Point ps3, ps4;
void setPoints() {
super.setPoints();
calcLeads(32);
ps3 = new Point();
ps4 = new Point();
}
void draw(Graphics g) {
int segments = 16;
int i;
int ox = 0;
//int hs = sim.euroResistorCheckItem.getState() ? 6 : 8;
int hs=6;
double v1 = volts[0];
double v2 = volts[1];
setBbox(point1, point2, hs);
draw2Leads(g);
setPowerColor(g, true);
// double segf = 1./segments;
double len = distance(lead1, lead2);
g.context.save();
g.context.setLineWidth(3.0);
g.context.setTransform(((double)(lead2.x-lead1.x))/len, ((double)(lead2.y-lead1.y))/len, -((double)(lead2.y-lead1.y))/len,((double)(lead2.x-lead1.x))/len,lead1.x,lead1.y);
CanvasGradient grad = g.context.createLinearGradient(0,0,len,0);
grad.addColorStop(0, getVoltageColor(g,v1).getHexValue());
grad.addColorStop(1.0, getVoltageColor(g,v2).getHexValue());
g.context.setStrokeStyle(grad);
if (!sim.euroResistorCheckItem.getState()) {
// // draw zigzag
// for (i = 0; i != segments; i++) {
// int nx = 0;
// switch (i & 3) {
// case 0: nx = 1; break;
// case 2: nx = -1; break;
// default: nx = 0; break;
// }
// double v = v1+(v2-v1)*i/segments;
// setVoltageColor(g, v);
// interpPoint(lead1, lead2, ps1, i*segf, hs*ox);
// interpPoint(lead1, lead2, ps2, (i+1)*segf, hs*nx);
// drawThickLine(g, ps1, ps2);
// ox = nx;
// }
g.context.beginPath();
g.context.moveTo(0,0);
for (i=0;i<4;i++){
g.context.lineTo((1+4*i)*len/16, hs);
g.context.lineTo((3+4*i)*len/16, -hs);
}
g.context.lineTo(len, 0);
g.context.stroke();
} else {
// draw rectangle
// setVoltageColor(g, v1);
// interpPoint2(lead1, lead2, ps1, ps2, 0, hs);
// drawThickLine(g, ps1, ps2);
// for (i = 0; i != segments; i++) {
// double v = v1+(v2-v1)*i/segments;
// setVoltageColor(g, v);
// interpPoint2(lead1, lead2, ps1, ps2, i*segf, hs);
// interpPoint2(lead1, lead2, ps3, ps4, (i+1)*segf, hs);
// drawThickLine(g, ps1, ps3);
// drawThickLine(g, ps2, ps4);
// }
// interpPoint2(lead1, lead2, ps1, ps2, 1, hs);
// drawThickLine(g, ps1, ps2);
g.context.strokeRect(0, -hs, len, 2.0*hs);
}
g.context.restore();
if (sim.showValuesCheckItem.getState()) {
String s = getShortUnitText(resistance, "");
drawValues(g, s, hs);
}
doDots(g);
drawPosts(g);
}
void calculateCurrent() {
current = (volts[0]-volts[1])/resistance;
//System.out.print(this + " res current set to " + current + "\n");
}
void stamp() {
sim.stampResistor(nodes[0], nodes[1], resistance);
}
void getInfo(String arr[]) {
arr[0] = "resistor";
getBasicInfo(arr);
arr[3] = "R = " + getUnitText(resistance, sim.ohmString);
arr[4] = "P = " + getUnitText(getPower(), "W");
}
public EditInfo getEditInfo(int n) {
// ohmString doesn't work here on linux
if (n == 0)
return new EditInfo("Resistance (ohms)", resistance, 0, 0);
return null;
}
public void setEditValue(int n, EditInfo ei) {
if (ei.value > 0)
resistance = ei.value;
}
int getShortcut() { return 'r'; }
}

View File

@@ -0,0 +1,33 @@
/*
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;
// info about each row/column of the matrix for simplification purposes
class RowInfo {
static final int ROW_NORMAL = 0; // ordinary value
static final int ROW_CONST = 1; // value is constant
static final int ROW_EQUAL = 2; // value is equal to another value
int nodeEq, type, mapCol, mapRow;
double value;
boolean rsChanges; // row's right side changes
boolean lsChanges; // row's left side changes
boolean dropRow; // row is not needed in matrix
RowInfo() { type = ROW_NORMAL; }
}

Some files were not shown because too many files have changed in this diff Show More