HTML5 - Render simple electrical circuits
Asked Answered
R

2

6

I have a set of relatively simple electrical circuits. Small ones involving just resistors, capacitors, inductors, and trimmers/trimpots (ie: three-terminal variable resistors).

I am trying to find a simple way to render these circuits from the matrix of node-voltage equations. I don't need to calculate current/voltage values (I am already capable of doing that).

I have a basic understanding of how to render 2D shapes in HTML5. At this point, I just need a simple way to place and connect the shapes via lines. I could always do a simple placement, but any suggestions on how to avoid re-inventing the wheel would be great.

Thank you.

Regeniaregensburg answered 26/6, 2012 at 23:30 Comment(4)
So what you need is a quick intro on drawing shapes and lines dynamically with javascript? Also, are they to be animated?Otalgia
@mndoftea That is correct. Animations would be nice, but they are not necessary. I didn't realize that I would need to use JavaScript. My background is C/assembler/embedded. I have a decent knownledge of HTML on it's own (ie: HTML4), but not HTML5 nor JavaScript.Regeniaregensburg
Yes, as far as I know, the only way to use the html5 canvas is with javascript. If you aren't animating, you won't need to do very much that's dynamic, just enter the lines you want between the script tags. I will write tomorrow with what lines those should be.Otalgia
Sorry for not responding sooner. So, there are two ways of doing this: manually and by using a library. Doing it manually would require drawing each line in each symbol every time you want to draw one, using a library would let you just say things like "draw wire, draw resistor, draw capacitor, etc." You probably want a lightweight library to make it easy to draw these things. Since you're not familiar with Javascript, I'll write one for you. It'll be ready soon.Otalgia
O
15

Sorry it's been a while, but I've finished the library I promised you. Using it, I can create circuits like these:

circuits

I've created a simplified drawing system in javascript for you to use by building a short library.Copy and paste the code for it into your page, and then leave it be. If you want to change it, either ask me (or someone else who know Javascript), or learn it at a website like W3Schools or the Mozilla MDN. The code requires a canvas element with the id "canvas". The code:

        "use strict"

        var wW=window.innerWidth;
        var wH=window.innerHeight;
        var canvasHTML=document.getElementById("canvas");
        canvasHTML.width=wW;
        canvasHTML.height=wH;
        var ctx=canvasHTML.getContext("2d");
        var ix;
        var iy;
        var x;
        var y;
        var d;
        var dx;
        var dy;

        function beginCircuit(a,b)
        {
            ctx.lineWidth=1.5;
            ctx.strokeStyle="#000";
            ctx.beginPath();
            x=a;
            y=b;
            d=0;
            dx=1;
            dy=0;
            ix=x;
            iy=y;
            ctx.moveTo(x,y);
            drawWire(50);
            drawPower();
        }

        function endCircuit()
        {
            ctx.lineTo(ix,iy);
            ctx.stroke();
        }

        function drawWire(l)
        {
            x+=dx*l;
            y+=dy*l;
            ctx.lineTo(x,y);
        }       

        function drawPower()
        {
            var n;
            drawWire(10);
            n=3;
            ctx.moveTo(x+10*dy,y+10*dx);
            ctx.lineTo(x-10*dy,y-10*dx);
            x+=dx*5;
            y+=dy*5;
            while(n--)
            {
                ctx.moveTo(x+15*dy,y+15*dx);
                ctx.lineTo(x-15*dy,y-15*dx);
                x+=dx*5;
                y+=dy*5;
                ctx.moveTo(x+10*dy,y+10*dx);
                ctx.lineTo(x-10*dy,y-10*dx);
                if(n!=0)
                {
                    x+=dx*5;
                    y+=dy*5;
                }
            }
            ctx.moveTo(x,y);
            drawWire(10);
        }

        function drawCapacitor()
        {
            drawWire(22.5);
            ctx.moveTo(x+10*dy,y+10*dx);
            ctx.lineTo(x-10*dy,y-10*dx);
            x+=dx*5;
            y+=dy*5;
            ctx.moveTo(x+10*dy,y+10*dx);
            ctx.lineTo(x-10*dy,y-10*dx);
            ctx.moveTo(x,y);
            drawWire(22.5);
        }

        function drawInductor()
        {
            var n,xs,ys;
            drawWire(9);
            n=4;
            xs=1+Math.abs(dy);
            ys=1+Math.abs(dx);
            x+=dx*6;
            y+=dy*6;
            ctx.scale(xs,ys);
            while(n--)
            {
                ctx.moveTo(x/xs+5*Math.abs(dx),y/ys+5*dy);
                ctx.arc(x/xs,y/ys,5,Math.PI/2*dy,Math.PI+Math.PI/2*dy,1);
                x+=6.5*dx;
                y+=6.5*dy;
                if(n!=0)
                {
                    if(dx>=0)
                    {
                        ctx.moveTo(x/xs-5*dx,y/ys-5*dy);
                    }
                    
                    ctx.moveTo(x/xs-5*dx,y/ys-5*dy);
                    ctx.arc(x/xs-6.5/2*dx,y/ys-6.5/2*dy,1.5,Math.PI+Math.PI/2*dy,Math.PI/2*dy,1);
                }
            }
            ctx.moveTo(x/xs-1.75*dx,y/ys-1.75*dy);
            ctx.scale(1/xs,1/ys);
            ctx.lineTo(x,y);
            drawWire(9);
        }

        function drawTrimmer()
        {
            ctx.moveTo(x+35*dx-7*dy,y+35*dy-7*dx);
            ctx.lineTo(x+15*dx+7*dy,y+15*dy+7*dx);
            ctx.moveTo(x+13*dx+4*dy,y+13*dy+4*dx);
            ctx.lineTo(x+17*dx+10*dy,y+17*dy+10*dx);
            ctx.moveTo(x,y);
            drawCapacitor();
        }

        function drawResistor()
        {
            var n;
            drawWire(10);
            n=5;
            x+=dx*5;
            y+=dy*5;
            while(n--)
            {
                ctx.lineTo(x-5*dy,y-5*dx);
                ctx.lineTo(x+5*dy,y+5*dx);
                x+=5*dx;
                y+=5*dy;
            }
            ctx.lineTo(x,y);
            drawWire(10);
        }

        function turnClockwise()
        {
            d++;
            dx=Math.cos(1.570796*d);
            dy=Math.sin(1.570796*d);
        }

        function turnCounterClockwise()
        {
            d--;
            dx=Math.cos(1.570796*d);
            dy=Math.sin(1.570796*d);
        }

Then create a new <script type="text/javascript">....</script> tag and put between the tags your drawing code. Drawing code works like this:

You start by calling the function beginCircuit(x,y). Inside the parenthesis, put the x and y coordinates you want to start your circuit at, like so: beginCircuit(200,100). This will draw a wire, and a battery at the coordinates you specified (in pixels). The battery and wire together take up 100 pixels of space on the screen.

Then, you can call any of the following functions:

drawWire(length)

Draws a wire of the length you specify at the end of the circuit. Takes up length amount of space.

turnClockwise(length)

Turns the direction in which your next command will draw 90° clockwise. Takes up no space.

turnCounterClockwise(length)

Turns the direction in which your next command will draw 90° counter-clockwise. Takes up no space.

drawCapacitor(length)

Draws a capacitor at the end of the circuit. Takes up 50px.

drawInductor(length)

Draws an inductor at the end of the circuit. Takes up 50px.

drawResistor(length)

Draws a resistor at the end of the circuit. Takes up 50px.

drawTrimmer(length)

Draws a resistor at the end of the circuit. Takes up 50px.

When you're done drawing circuitry, use the function endCircuit() to close and then draw the circuit. It will automatically draw a wire from the point where you stopped to the beginning of the circuit.

I know it's a lot to do, but it really is a very easy and flexible way to do this once you understand it. If you want to see this in action, go here: http://jsfiddle.net/mindoftea/ZajVE/. Please give it a shot, and if you have problems, comment about it, please.

Thanks and hope this helps!

Otalgia answered 1/7, 2012 at 4:33 Comment(4)
@ThinkingStiff, Thanks, I only just remembered to do this and put it together desperately in a few hours; glad it worked out.Otalgia
Wow! Thank you! I wish I could do more than +1 and Accept the answer.Regeniaregensburg
I know it's been 9 years, but have you put this code on GitHub/GitLab or applied any specific license to it?Momentous
@Otalgia is there any way to draw other electric element like switch open/closed, ground and change direction of element left right, and the get click action of each elementBoson
L
0

Nice works! I'm also in need for teaching purpose which includes Circuits (and Mechanics). packed it into a class if anybody favor OO style. also added some flexibility to customize symbols, e.g. label etc. http://jsfiddle.net/michael_chnc/q01f2htb/

` /*Basic Circuit symbol toolset, still alot missing credit to: https://stackoverflow.com/users/434421/mindoftea*/

class Circuit {   constructor(name = "canvas", ix = 50, iy = 50) {
    this.canvas = document.getElementById(name);
    this.ctx = canvas.getContext("2d");
    this.d = 0; ... }

var cc = new Circuit("canvas", 100, 100); cc.ctx.lineWidth = 2; cc.drawPower(60, 1, "E"); cc.drawCapacitor(60, "C=50 \u03bc"); cc.drawSwitch(40, 1, "S1"); cc.drawInductor(50, 4, "I=40"); cc.turnClockwise(); cc.drawTrimmer(60, "T"); cc.drawResistor(60, 3, 1, "R"); cc.turnClockwise(); cc.drawResistor(160, 3, 2, "R"); cc.save(); cc.turnCounterClockwise(); cc.drawWire(20); cc.turnClockwise(); cc.drawResistor(); cc.turnClockwise(); cc.drawWire(20); cc.restore(); cc.turnClockwise(); cc.drawWire(20); cc.turnCounterClockwise(); cc.drawResistor(50, 5, 2, "R2"); cc.turnCounterClockwise(); cc.drawWire(20); cc.turnClockwise(); cc.drawWire(80); cc.turnClockwise(); cc.drawWire(30); cc.drawSwitch(50, false, "S3");


cc.finish(true); `
Lourielouse answered 22/10, 2019 at 13:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.