Question

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.

Was it helpful?

Solution

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!

OTHER TIPS

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); `
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top