mirror of
https://github.com/pfalstad/circuitjs1.git
synced 2026-02-20 01:41:22 +01:00
CircuitJS1 First Version
This commit is contained in:
11
.classpath
Normal file
11
.classpath
Normal 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
6
.gitignore
vendored
@@ -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
34
.project
Normal 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>
|
||||
2
.settings/com.google.appengine.eclipse.core.prefs
Normal file
2
.settings/com.google.appengine.eclipse.core.prefs
Normal file
@@ -0,0 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
filesCopiedToWebInfLib=
|
||||
5
.settings/com.google.gdt.eclipse.core.prefs
Normal file
5
.settings/com.google.gdt.eclipse.core.prefs
Normal file
@@ -0,0 +1,5 @@
|
||||
eclipse.preferences.version=1
|
||||
jarsExcludedFromWebInfLib=
|
||||
launchConfigExternalUrlPrefix=
|
||||
warSrcDir=war
|
||||
warSrcDirIsOutput=true
|
||||
3
.settings/com.google.gwt.eclipse.core.prefs
Normal file
3
.settings/com.google.gwt.eclipse.core.prefs
Normal file
@@ -0,0 +1,3 @@
|
||||
eclipse.preferences.version=1
|
||||
filesCopiedToWebInfLib=gwt-servlet.jar
|
||||
gwtCompileSettings=PGd3dC1jb21waWxlLXNldHRpbmdzPjxsb2ctbGV2ZWw+SU5GTzwvbG9nLWxldmVsPjxvdXRwdXQtc3R5bGU+T0JGVVNDQVRFRDwvb3V0cHV0LXN0eWxlPjxleHRyYS1hcmdzPjwhW0NEQVRBW11dPjwvZXh0cmEtYXJncz48dm0tYXJncz48IVtDREFUQVstWG14NTEybV1dPjwvdm0tYXJncz48ZW50cnktcG9pbnQtbW9kdWxlPmNvbS5sdXNocHJvamVjdHMuY2lyY3VpdGpzMS5jaXJjdWl0anMxPC9lbnRyeS1wb2ludC1tb2R1bGU+PC9nd3QtY29tcGlsZS1zZXR0aW5ncz4\=
|
||||
11
.settings/org.eclipse.jdt.core.prefs
Normal file
11
.settings/org.eclipse.jdt.core.prefs
Normal 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
|
||||
4
.settings/org.eclipse.wst.common.project.facet.core.xml
Normal file
4
.settings/org.eclipse.wst.common.project.facet.core.xml
Normal 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
339
COPYING.txt
Normal 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
77
README.md
Normal 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.
|
||||
7
src/com/lushprojects/circuitjs1/circuitjs1.gwt.xml
Normal file
7
src/com/lushprojects/circuitjs1/circuitjs1.gwt.xml
Normal 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>
|
||||
26
src/com/lushprojects/circuitjs1/client/ACRailElm.java
Normal file
26
src/com/lushprojects/circuitjs1/client/ACRailElm.java
Normal 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; }
|
||||
}
|
||||
25
src/com/lushprojects/circuitjs1/client/ACVoltageElm.java
Normal file
25
src/com/lushprojects/circuitjs1/client/ACVoltageElm.java
Normal 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; }
|
||||
}
|
||||
60
src/com/lushprojects/circuitjs1/client/ADCElm.java
Normal file
60
src/com/lushprojects/circuitjs1/client/ADCElm.java
Normal 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; }
|
||||
}
|
||||
|
||||
146
src/com/lushprojects/circuitjs1/client/AMElm.java
Normal file
146
src/com/lushprojects/circuitjs1/client/AMElm.java
Normal 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;
|
||||
}
|
||||
}
|
||||
76
src/com/lushprojects/circuitjs1/client/AboutBox.java
Normal file
76
src/com/lushprojects/circuitjs1/client/AboutBox.java
Normal 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();
|
||||
}
|
||||
}
|
||||
113
src/com/lushprojects/circuitjs1/client/AnalogSwitch2Elm.java
Normal file
113
src/com/lushprojects/circuitjs1/client/AnalogSwitch2Elm.java
Normal 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());
|
||||
}
|
||||
}
|
||||
|
||||
153
src/com/lushprojects/circuitjs1/client/AnalogSwitchElm.java
Normal file
153
src/com/lushprojects/circuitjs1/client/AnalogSwitchElm.java
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
63
src/com/lushprojects/circuitjs1/client/AndGateElm.java
Normal file
63
src/com/lushprojects/circuitjs1/client/AndGateElm.java
Normal 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'; }
|
||||
}
|
||||
48
src/com/lushprojects/circuitjs1/client/AntennaElm.java
Normal file
48
src/com/lushprojects/circuitjs1/client/AntennaElm.java
Normal 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; }
|
||||
}
|
||||
89
src/com/lushprojects/circuitjs1/client/BoxElm.java
Normal file
89
src/com/lushprojects/circuitjs1/client/BoxElm.java
Normal 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; }
|
||||
}
|
||||
|
||||
73
src/com/lushprojects/circuitjs1/client/CC2Elm.java
Normal file
73
src/com/lushprojects/circuitjs1/client/CC2Elm.java
Normal 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; }
|
||||
}
|
||||
160
src/com/lushprojects/circuitjs1/client/CapacitorElm.java
Normal file
160
src/com/lushprojects/circuitjs1/client/CapacitorElm.java
Normal 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'; }
|
||||
}
|
||||
42
src/com/lushprojects/circuitjs1/client/Checkbox.java
Normal file
42
src/com/lushprojects/circuitjs1/client/Checkbox.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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+" </div>"+s), cmd);
|
||||
}
|
||||
|
||||
}
|
||||
92
src/com/lushprojects/circuitjs1/client/CheckboxMenuItem.java
Normal file
92
src/com/lushprojects/circuitjs1/client/CheckboxMenuItem.java
Normal 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("✔ "+name);
|
||||
s = checkBoxHtml+"✔</div>"+name;
|
||||
else
|
||||
// super.setHTML("  "+name);
|
||||
s = checkBoxHtml+" </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;
|
||||
}
|
||||
|
||||
}
|
||||
320
src/com/lushprojects/circuitjs1/client/ChipElm.java
Normal file
320
src/com/lushprojects/circuitjs1/client/ChipElm.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
37
src/com/lushprojects/circuitjs1/client/Choice.java
Normal file
37
src/com/lushprojects/circuitjs1/client/Choice.java
Normal 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);
|
||||
}
|
||||
}
|
||||
4436
src/com/lushprojects/circuitjs1/client/CirSim.java
Normal file
4436
src/com/lushprojects/circuitjs1/client/CirSim.java
Normal file
File diff suppressed because it is too large
Load Diff
750
src/com/lushprojects/circuitjs1/client/CircuitElm.java
Normal file
750
src/com/lushprojects/circuitjs1/client/CircuitElm.java
Normal 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; }
|
||||
}
|
||||
29
src/com/lushprojects/circuitjs1/client/CircuitNode.java
Normal file
29
src/com/lushprojects/circuitjs1/client/CircuitNode.java
Normal 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>(); }
|
||||
}
|
||||
25
src/com/lushprojects/circuitjs1/client/CircuitNodeLink.java
Normal file
25
src/com/lushprojects/circuitjs1/client/CircuitNodeLink.java
Normal 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;
|
||||
}
|
||||
32
src/com/lushprojects/circuitjs1/client/ClockElm.java
Normal file
32
src/com/lushprojects/circuitjs1/client/ClockElm.java
Normal 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; }
|
||||
}
|
||||
102
src/com/lushprojects/circuitjs1/client/Color.java
Normal file
102
src/com/lushprojects/circuitjs1/client/Color.java
Normal 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;
|
||||
}
|
||||
}
|
||||
138
src/com/lushprojects/circuitjs1/client/CounterElm.java
Normal file
138
src/com/lushprojects/circuitjs1/client/CounterElm.java
Normal 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; }
|
||||
}
|
||||
94
src/com/lushprojects/circuitjs1/client/CurrentElm.java
Normal file
94
src/com/lushprojects/circuitjs1/client/CurrentElm.java
Normal 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];
|
||||
}
|
||||
}
|
||||
59
src/com/lushprojects/circuitjs1/client/DACElm.java
Normal file
59
src/com/lushprojects/circuitjs1/client/DACElm.java
Normal 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; }
|
||||
}
|
||||
|
||||
27
src/com/lushprojects/circuitjs1/client/DCVoltageElm.java
Normal file
27
src/com/lushprojects/circuitjs1/client/DCVoltageElm.java
Normal 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'; }
|
||||
}
|
||||
118
src/com/lushprojects/circuitjs1/client/DFlipFlopElm.java
Normal file
118
src/com/lushprojects/circuitjs1/client/DFlipFlopElm.java
Normal 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);
|
||||
}
|
||||
}
|
||||
73
src/com/lushprojects/circuitjs1/client/DeMultiplexerElm.java
Normal file
73
src/com/lushprojects/circuitjs1/client/DeMultiplexerElm.java
Normal 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; }
|
||||
|
||||
}
|
||||
70
src/com/lushprojects/circuitjs1/client/DecadeElm.java
Normal file
70
src/com/lushprojects/circuitjs1/client/DecadeElm.java
Normal 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; }
|
||||
}
|
||||
130
src/com/lushprojects/circuitjs1/client/DiacElm.java
Normal file
130
src/com/lushprojects/circuitjs1/client/DiacElm.java
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
168
src/com/lushprojects/circuitjs1/client/Diode.java
Normal file
168
src/com/lushprojects/circuitjs1/client/Diode.java
Normal 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
|
||||
);
|
||||
}
|
||||
}
|
||||
132
src/com/lushprojects/circuitjs1/client/DiodeElm.java
Normal file
132
src/com/lushprojects/circuitjs1/client/DiodeElm.java
Normal 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'; }
|
||||
}
|
||||
327
src/com/lushprojects/circuitjs1/client/EditDialog.java
Normal file
327
src/com/lushprojects/circuitjs1/client/EditDialog.java
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
55
src/com/lushprojects/circuitjs1/client/EditInfo.java
Normal file
55
src/com/lushprojects/circuitjs1/client/EditInfo.java
Normal 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;
|
||||
}
|
||||
|
||||
43
src/com/lushprojects/circuitjs1/client/EditOptions.java
Normal file
43
src/com/lushprojects/circuitjs1/client/EditOptions.java
Normal 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;
|
||||
}
|
||||
};
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
159
src/com/lushprojects/circuitjs1/client/FMElm.java
Normal file
159
src/com/lushprojects/circuitjs1/client/FMElm.java
Normal 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;
|
||||
}
|
||||
}
|
||||
39
src/com/lushprojects/circuitjs1/client/Font.java
Normal file
39
src/com/lushprojects/circuitjs1/client/Font.java
Normal 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;
|
||||
}
|
||||
}
|
||||
61
src/com/lushprojects/circuitjs1/client/FullAdderElm.java
Normal file
61
src/com/lushprojects/circuitjs1/client/FullAdderElm.java
Normal 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; }
|
||||
|
||||
}
|
||||
151
src/com/lushprojects/circuitjs1/client/GateElm.java
Normal file
151
src/com/lushprojects/circuitjs1/client/GateElm.java
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
37
src/com/lushprojects/circuitjs1/client/GraphicElm.java
Normal file
37
src/com/lushprojects/circuitjs1/client/GraphicElm.java
Normal 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; }
|
||||
}
|
||||
|
||||
128
src/com/lushprojects/circuitjs1/client/Graphics.java
Normal file
128
src/com/lushprojects/circuitjs1/client/Graphics.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
57
src/com/lushprojects/circuitjs1/client/GroundElm.java
Normal file
57
src/com/lushprojects/circuitjs1/client/GroundElm.java
Normal 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'; }
|
||||
}
|
||||
59
src/com/lushprojects/circuitjs1/client/HalfAdderElm.java
Normal file
59
src/com/lushprojects/circuitjs1/client/HalfAdderElm.java
Normal 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; }
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
80
src/com/lushprojects/circuitjs1/client/Inductor.java
Normal file
80
src/com/lushprojects/circuitjs1/client/Inductor.java
Normal 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);
|
||||
}
|
||||
}
|
||||
115
src/com/lushprojects/circuitjs1/client/InductorElm.java
Normal file
115
src/com/lushprojects/circuitjs1/client/InductorElm.java
Normal 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'; }
|
||||
|
||||
}
|
||||
105
src/com/lushprojects/circuitjs1/client/InverterElm.java
Normal file
105
src/com/lushprojects/circuitjs1/client/InverterElm.java
Normal 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'; }
|
||||
}
|
||||
186
src/com/lushprojects/circuitjs1/client/InvertingSchmittElm.java
Normal file
186
src/com/lushprojects/circuitjs1/client/InvertingSchmittElm.java
Normal 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);
|
||||
}
|
||||
}
|
||||
105
src/com/lushprojects/circuitjs1/client/JKFlipFlopElm.java
Normal file
105
src/com/lushprojects/circuitjs1/client/JKFlipFlopElm.java
Normal 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);
|
||||
}
|
||||
}
|
||||
93
src/com/lushprojects/circuitjs1/client/JfetElm.java
Normal file
93
src/com/lushprojects/circuitjs1/client/JfetElm.java
Normal 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");
|
||||
}
|
||||
}
|
||||
115
src/com/lushprojects/circuitjs1/client/LEDElm.java
Normal file
115
src/com/lushprojects/circuitjs1/client/LEDElm.java
Normal 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'; }
|
||||
}
|
||||
189
src/com/lushprojects/circuitjs1/client/LampElm.java
Normal file
189
src/com/lushprojects/circuitjs1/client/LampElm.java
Normal 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;
|
||||
}
|
||||
}
|
||||
60
src/com/lushprojects/circuitjs1/client/LatchElm.java
Normal file
60
src/com/lushprojects/circuitjs1/client/LatchElm.java
Normal 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; }
|
||||
}
|
||||
|
||||
82
src/com/lushprojects/circuitjs1/client/LoadFile.java
Normal file
82
src/com/lushprojects/circuitjs1/client/LoadFile.java
Normal 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]);
|
||||
}
|
||||
}-*/;
|
||||
|
||||
}
|
||||
120
src/com/lushprojects/circuitjs1/client/LogicInputElm.java
Normal file
120
src/com/lushprojects/circuitjs1/client/LogicInputElm.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
119
src/com/lushprojects/circuitjs1/client/LogicOutputElm.java
Normal file
119
src/com/lushprojects/circuitjs1/client/LogicOutputElm.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
154
src/com/lushprojects/circuitjs1/client/MemristorElm.java
Normal file
154
src/com/lushprojects/circuitjs1/client/MemristorElm.java
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
101
src/com/lushprojects/circuitjs1/client/MonostableElm.java
Normal file
101
src/com/lushprojects/circuitjs1/client/MonostableElm.java
Normal 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);
|
||||
}
|
||||
}
|
||||
275
src/com/lushprojects/circuitjs1/client/MosfetElm.java
Normal file
275
src/com/lushprojects/circuitjs1/client/MosfetElm.java
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
68
src/com/lushprojects/circuitjs1/client/MultiplexerElm.java
Normal file
68
src/com/lushprojects/circuitjs1/client/MultiplexerElm.java
Normal 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; }
|
||||
|
||||
}
|
||||
37
src/com/lushprojects/circuitjs1/client/MyCommand.java
Normal file
37
src/com/lushprojects/circuitjs1/client/MyCommand.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
31
src/com/lushprojects/circuitjs1/client/NJfetElm.java
Normal file
31
src/com/lushprojects/circuitjs1/client/NJfetElm.java
Normal 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; }
|
||||
}
|
||||
|
||||
26
src/com/lushprojects/circuitjs1/client/NMosfetElm.java
Normal file
26
src/com/lushprojects/circuitjs1/client/NMosfetElm.java
Normal 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'; }
|
||||
}
|
||||
28
src/com/lushprojects/circuitjs1/client/NTransistorElm.java
Normal file
28
src/com/lushprojects/circuitjs1/client/NTransistorElm.java
Normal 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'; }
|
||||
|
||||
}
|
||||
35
src/com/lushprojects/circuitjs1/client/NandGateElm.java
Normal file
35
src/com/lushprojects/circuitjs1/client/NandGateElm.java
Normal 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 '@'; }
|
||||
}
|
||||
35
src/com/lushprojects/circuitjs1/client/NorGateElm.java
Normal file
35
src/com/lushprojects/circuitjs1/client/NorGateElm.java
Normal 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 '#'; }
|
||||
}
|
||||
195
src/com/lushprojects/circuitjs1/client/OpAmpElm.java
Normal file
195
src/com/lushprojects/circuitjs1/client/OpAmpElm.java
Normal 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'; }
|
||||
}
|
||||
29
src/com/lushprojects/circuitjs1/client/OpAmpSwapElm.java
Normal file
29
src/com/lushprojects/circuitjs1/client/OpAmpSwapElm.java
Normal 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'; }
|
||||
}
|
||||
74
src/com/lushprojects/circuitjs1/client/OrGateElm.java
Normal file
74
src/com/lushprojects/circuitjs1/client/OrGateElm.java
Normal 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'; }
|
||||
}
|
||||
84
src/com/lushprojects/circuitjs1/client/OutputElm.java
Normal file
84
src/com/lushprojects/circuitjs1/client/OutputElm.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
26
src/com/lushprojects/circuitjs1/client/PMosfetElm.java
Normal file
26
src/com/lushprojects/circuitjs1/client/PMosfetElm.java
Normal 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'; }
|
||||
}
|
||||
28
src/com/lushprojects/circuitjs1/client/PTransistorElm.java
Normal file
28
src/com/lushprojects/circuitjs1/client/PTransistorElm.java
Normal 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'; }
|
||||
|
||||
}
|
||||
75
src/com/lushprojects/circuitjs1/client/PhaseCompElm.java
Normal file
75
src/com/lushprojects/circuitjs1/client/PhaseCompElm.java
Normal 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; }
|
||||
}
|
||||
|
||||
93
src/com/lushprojects/circuitjs1/client/PisoShiftElm.java
Normal file
93
src/com/lushprojects/circuitjs1/client/PisoShiftElm.java
Normal 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; }
|
||||
|
||||
}
|
||||
45
src/com/lushprojects/circuitjs1/client/Point.java
Normal file
45
src/com/lushprojects/circuitjs1/client/Point.java
Normal 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;
|
||||
}
|
||||
}
|
||||
71
src/com/lushprojects/circuitjs1/client/Polygon.java
Normal file
71
src/com/lushprojects/circuitjs1/client/Polygon.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
243
src/com/lushprojects/circuitjs1/client/PotElm.java
Normal file
243
src/com/lushprojects/circuitjs1/client/PotElm.java
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
99
src/com/lushprojects/circuitjs1/client/ProbeElm.java
Normal file
99
src/com/lushprojects/circuitjs1/client/ProbeElm.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
26
src/com/lushprojects/circuitjs1/client/PushSwitchElm.java
Normal file
26
src/com/lushprojects/circuitjs1/client/PushSwitchElm.java
Normal 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; }
|
||||
}
|
||||
64
src/com/lushprojects/circuitjs1/client/QueryParameters.java
Normal file
64
src/com/lushprojects/circuitjs1/client/QueryParameters.java
Normal 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;
|
||||
}-*/;
|
||||
}
|
||||
91
src/com/lushprojects/circuitjs1/client/RailElm.java
Normal file
91
src/com/lushprojects/circuitjs1/client/RailElm.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
151
src/com/lushprojects/circuitjs1/client/Rectangle.java
Normal file
151
src/com/lushprojects/circuitjs1/client/Rectangle.java
Normal 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);
|
||||
}
|
||||
}
|
||||
331
src/com/lushprojects/circuitjs1/client/RelayElm.java
Normal file
331
src/com/lushprojects/circuitjs1/client/RelayElm.java
Normal 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'; }
|
||||
}
|
||||
|
||||
144
src/com/lushprojects/circuitjs1/client/ResistorElm.java
Normal file
144
src/com/lushprojects/circuitjs1/client/ResistorElm.java
Normal 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'; }
|
||||
}
|
||||
33
src/com/lushprojects/circuitjs1/client/RowInfo.java
Normal file
33
src/com/lushprojects/circuitjs1/client/RowInfo.java
Normal 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
Reference in New Issue
Block a user