Some Curves

Select Type:

Rose only: N: D:

More information for these curves can be found at

HTML Code
<html>
<head>
   <script type="text/javascript" src="circleCanvas.js"> </script>
</head>
<body>

<h1>Some Curves</h1>

<script>
// create a default canvas.
var canvas1 = new CircleCanvas(400,400);

canvas1.SetClearColor("white");
canvas1.Redisplay();
</script>

<p>
Select Type: 
<select id="ShapeType" name "Type" onchange="canvas1.SetShape('ShapeType')">
    <option value="0">circle</option>
    <option value="1">rose</option>
    <option value="2">butterfly</option>
    <option value="3">cardioid</option>
</select>
<p>
Rose only: 
N:
<select id="numerator" name "Type" onchange="canvas1.SetV('numerator','n')">
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3" selected="selected">3</option>
    <option value="4">4</option>
    <option value="5">5</option>
    <option value="6">6</option>
    <option value="7">7</option>
    <option value="8">8</option>
</select>
D:
<select id="denominator" name "Type" onchange="canvas1.SetV('denominator','d')">
    <option value="1" selected="selected">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    <option value="4">4</option>
    <option value="5">5</option>
    <option value="6">6</option>
    <option value="7">7</option>
    <option value="8">8</option>
</select>

<p>
More information for these curves can be found at
<ul>
    <li> <a href="https://en.wikipedia.org/wiki/Rose_(mathematics)">rose</a>
    <lI> <a href="https://en.wikipedia.org/wiki/Cardioid">cardioid</a>
    <lI> <a href="https://en.wikipedia.org/wiki/Butterfly_curve_(transcendental)">butterfly</a>
    <li> <a href="https://en.wikipedia.org/wiki/Parametric_equation">Parametric Equations in General</a>
</ul>
</body>

circleCanvas.js

function CircleCanvas(width, height) { 
  
    // make sure that widht and height are good.
    if (width == undefined || width < 0) {
       width = 300;
    }

    if (height == undefined || height < 0) {
       height = 300;
    }

    // create the canvas
    var canvas = document.createElement('canvas')
        canvas.height = height;
        canvas.width = width;

    // add it to the document 
    document.body.appendChild(canvas);

    // save some infor as local values
    this.width = width;
    this.height = height;
    this.clearColor = "#000000";

    // for shape see comments by SetShape
    this.shape = 0;
    // for rose, see comments by SetV
    this.n = 3;
    this.d = 1;

    this.ctx =  canvas.getContext("2d");

    return this;
}

CircleCanvas.prototype = {

    SetClearColor: function(color) {
       this.clearColor = color; 

       return;
    },

    Clear: function() {
        this.ctx.fillStyle=this.clearColor;
        this.ctx.fillRect(0,0,this.width,this.height);

	return;
    },

    // corresponds to shapes built into html document.
    // circle = 0
    // rose = 1
    // butterfly = 2
    SetShape: function(shapeSelector) {
         var shapeChoice  = document.getElementById(shapeSelector);
	 var shapeID = parseInt(shapeChoice.value);

	 if (shapeID >= 0 && shapeID <= 3) {
	     this.shape = shapeID;
	 }
	 this.Redisplay();
    },

    // wikipedia has a cool chart, I'd keyed off of n and d.
    SetV: function(selection, which) {
         var choice  = document.getElementById(selection);
	 var value = parseInt(choice.value);

         switch(which) {
	    case 'n': this.n = value; break;
	    case 'd': this.d = value; break;
	 }

	 this.Redisplay();
	 return;
    },

    // strictly for deciding which shape function to call
    CalculatePoint: function(point, center, polarPoint) {
        switch(this.shape) {
	  case 3: 
	      Cardioid(point, center, polarPoint);
	      break;
	  case 2: 
	      Butterfly(point, center, polarPoint);
	      break;
	  case 1: 
	      Rose(point, center, polarPoint, this.n/this.d);
	      break;
          case 0:
	  default:
              Circle(point, center, polarPoint);
	}

	return;
    },

    Redisplay: function() {

        var polarPoint = {"r":0, "theta":0};
	var point = {"x":0, "y": 0};
	var center = {"x": this.width/2, "y":this.height/2};

	var start = 0, end = 360;

        // adjust the shape for fractional k in a rose
        if (this.shape == 1) {
	     end = 360 * this.d;
	}

	polarPoint.r = 0.9* Math.min(center.x, center.y);

        this.Clear();

	this.ctx.beginPath();
        this.ctx.strokeStyle="red"; 

        this.CalculatePoint(point, center, polarPoint);
        this.ctx.moveTo(point.x, point.y);

	for(polarPoint.theta=start; polarPoint.theta<end; polarPoint.theta++) {

            this.CalculatePoint(point, center, polarPoint);
	    this.ctx.lineTo(point.x, point.y);
	}

	this.ctx.closePath();
	this.ctx.stroke();

	return;
    }

}

// aux shape functions for redisplay

function Circle(p, c, polar ) {
    var phi = polar.theta/180.0*Math.PI; 

    p.x = c.x + polar.r * Math.cos(phi);
    p.y = c.y + polar.r * Math.sin(phi);

    return;
}

function Rose(p, c, polar, k){
    var phi = polar.theta/180.0*Math.PI; 

    p.x = c.x + polar.r * Math.cos(k*phi)*Math.cos(phi);
    p.y = c.y + polar.r * Math.cos(k*phi)*Math.sin(phi);

    return;
}

function Butterfly(p, c, polar){
    var phi = polar.theta/180.0*Math.PI; 

    p.x = c.x + polar.r/3*(Math.sin(phi)
              * (Math.exp(Math.cos(phi))
	      - 2 * Math.cos(4*phi)
	      - Math.pow(Math.sin(phi/12),5)));
    p.y = c.y - polar.r/3*( Math.cos(phi) 
              * (Math.exp(Math.cos(phi))
	      - 2 * Math.cos(4*phi)
	      - Math.pow(Math.sin(phi/12),5)));
    return;
}

function Cardioid(p, c, polar) {
    var phi = polar.theta/180.0*Math.PI; 

    var a = .25*polar.r;

    p.x = c.x + a*(2*Math.cos(phi)-Math.cos(2*phi));
    p.y = c.y + a*(2*Math.sin(phi)-Math.sin(2*phi));

    return;
     
}