Plot points within an ellipse using p5.js - javascript

I have a need to add a bunch of dots within the confines of an ellipse. I'm trying to modify the code from the accepted solution to this question, which is set up to use a circle (same width and height) rather than an ellipse. It is also implementing via a HTML <canvas> element, and I need to get it working using p5.js.
Here is my code for the <canvas> element. It seems to be working great. i can size and position the ellipse any which way and the dots are all displayed within it no matter what.
function ellipse(context, cx, cy, rx, ry){
context.save(); // save state
context.beginPath();
context.translate(cx-rx, cy-ry);
context.scale(rx, ry);
context.arc(1, 1, 1, 0, 2 * Math.PI, false);
context.restore(); // restore to original state
context.stroke();
}
var canvas = document.getElementById("thecanvas");
var ctx = canvas.getContext('2d'),
count = 1000, // number of random points
cx = 300,
cy = 200,
w = 50,
h = 49,
radius = w;
ctx.fillStyle = '#CCCCCC';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ellipse(ctx, cx, cy, w, h);
// create random points
ctx.fillStyle = '#ffffff';
function dots() {
while (count) {
var pt_angle = Math.random() * 2 * Math.PI;
var pt_radius_sq = Math.random() * radius * radius;
var pt_x = Math.sqrt(pt_radius_sq) * Math.cos(pt_angle);
var pt_y = Math.sqrt(pt_radius_sq) * Math.sin(pt_angle);
ctx.fillRect( ((Math.sqrt(pt_radius_sq) * Math.cos(pt_angle) ) + cx), (((Math.sqrt(pt_radius_sq) * Math.sin(pt_angle))/(w/h)) + cy), 2, 2);
count--;
}
}
dots();
<canvas id="thecanvas" width="800" height="800"></canvas>
For some reason, what I believe to be a pretty straight forward to port to p5.js is not working. The dots seem to be contained within the same shaped ellipse as what is defined, but the scale seems to be off and I can't really tell what is causing it. You can see this in action at https://editor.p5js.org/dpassudetti/sketches/YRbLuwoM2 - p5.js code pasted below as well:
var count = 1000, // number of random points
cx = 300,
cy = 200,
w = 50,
h = 49,
radius = w;
function setup() {
createCanvas(800, 800);
function dots() {
fill('green');
stroke('green');
while (count) {
var pt_angle = Math.random() * 2 * Math.PI;
var pt_radius_sq = Math.random() * radius * radius;
var pt_x = Math.sqrt(pt_radius_sq) * Math.cos(pt_angle);
var pt_y = Math.sqrt(pt_radius_sq) * Math.sin(pt_angle);
square(
Math.sqrt(pt_radius_sq) * Math.cos(pt_angle) + cx,
(Math.sqrt(pt_radius_sq) * Math.sin(pt_angle)) / (w / h) + cy,
2,
2
);
count--;
}
}
fill("#CCCCCC");
ellipse(cx, cy, w, h);
dots();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>
If anyone can see what's throwing the scale off for the p5.js version and wouldn't mind pointing me in the right direction, I'd be most appreciative.

The function you are using to draw the ellipse takes different parameters in the 1st and 2nd case. In one case it's taking the radiuses, and in the other the diameters, so you're off by a factor of 0.5.
I've simplified your code to consider just circles and kept just the w variable, but you can use the code below and add back the h variable if you wish to.
var count = 300, // number of random points
cx = 300,
cy = 200,
w = 50,
radius = w / 2;
function setup() {
createCanvas(800, 800);
function dots() {
fill('green');
stroke('green');
while (count) {
const pt_angle = Math.random() * 2 * Math.PI;
const px = Math.random() * radius * cos(pt_angle);
const py = Math.random() * radius * sin(pt_angle);
square(
px + cx,
py + cy,
2,
2
);
count--;
}
}
fill("#CCCCCC");
ellipse(cx, cy, w, w);
dots();
}

Related

How to create a rounded hexagon with javascript andCANVAS

I created this codepen to show what I got.
I managed to generate a hexagon avatar with progressbar around it using the awesome open source Hexagon Progress jQuery Plugin from Max Lawrence.
He also helped me to improve his own code a little but I don't want to bother him again.
Maybe someone here can help me to round the corners of this hexagon.
I want it to looks something like this (from the awesome Vikinger Html template) but need to be open source because my software is all open source. I can't use the Vikinger code.
So far I read that I have to stop the line before the end and add a quadratic curve to the next line start but I could not managed to do that.
His code do something like this on line 505:
ctx.moveTo(this.coordBack[0].x + offset, this.coordBack[0].y + offset);
for(var i = 0; i < this.coordBack.length; i++) {
ctx.lineTo(this.coordBack[i].x + offset, this.coordBack[i].y + offset);
}
Unfortunatelly, I am not that good in javascript or math.
Two ways to do this. The easy way, and the long winded, lots of math way.
Easy rounded corners
To create simple rounded polygons you can use ctx.arcTo. It will do all the math for the corners.
To create the polygon the following functions create a point and a path (array of points)
const Point = (x,y) => ({x, y});
function polygon(sides, rad, rot = 0) {
var i = 0, step = Math.PI * 2 / sides, path = [];
while (i < sides) {
path.push(Point(Math.cos(i * step + rot) * rad, Math.sin((i++) * step + rot) * rad));
}
return path;
}
To create a hexagon. Note that the polygon is centered over its local origin 0,0
const hexagon = polygon(6, 100);
To render the rounded polygon you need to work from the line segment centers. The following function will stroke the path with the rounded corners.
function strokeRoundedPath(cx, cy, path, radius, style, width) {
ctx.setTransform(1,0,0,1,cx,cy);
var i = 0;
const len = path.length
var p1 = path[i++], p2 = path[i];
ctx.lineWidth = width;
ctx.lineCap = "round";
ctx.strokeStyle = style;
ctx.beginPath();
ctx.lineTo((p1.x + p2.x) / 2, (p1.y + p2.y) / 2);
while (i <= len) {
p1 = p2;
p2 = path[(++i) % len];
ctx.arcTo(p1.x, p1.y, (p1.x + p2.x) / 2, (p1.y + p2.y) / 2, radius);
}
ctx.closePath();
ctx.stroke();
ctx.setTransform(1,0,0,1,0,0);
}
strokeRoundedPath(200, 200, hexagon, 20, "#000", 18);
Progress bar
Creating a progress bar is not as simple as the starting point can not be on a rounded corner, and moving over the rounded corners will need a lot of math to get the correct coordinates. This will negate the point of using easy arcToand need us to write the equivalent in JS (Way to slack for that today)
Using line dash for progress
There is however a hack that uses the line dash to create the effect you may be happy with. The snippet demonstrates this
const barWidth = 10;
const cornerRadius = barWidth * 2 + 8;
const polyRadius = 100;
const inset = 1;
const barRadius = polyRadius - barWidth * inset;
var progress = 0.0;
const approxLineLen = barRadius * Math.PI * 2;
const hexBar = polygon(6, barRadius);
const hexPoly = polygon(6, polyRadius);
const hexPolyInner = polygon(6, polyRadius - barWidth * 2 * inset);
const ctx = canvas.getContext("2d");
ctx.setLineDash([approxLineLen]);
loop()
function point(x,y) { return {x, y} }
function polygon(sides, radius, rot = 0) {
var i = 0;
const step = Math.PI * 2 / sides, path = [];
while (i < sides) {
path.push(point(Math.cos(i * step + rot) * radius, Math.sin((i++) * step + rot) * radius));
}
return path;
}
function roundedPath(path, radius) {
var i = 0, p1 = path[i++], p2 = path[i];
const len = path.length
ctx.moveTo((p1.x + p2.x) / 2, (p1.y + p2.y) / 2);
while (i <= len) {
p1 = p2;
p2 = path[(++i) % len];
ctx.arcTo(p1.x, p1.y, (p1.x + p2.x) / 2, (p1.y + p2.y) / 2, radius);
}
}
function strokeRoundedPath(cx, cy, path, radius, style, width) {
ctx.setTransform(1,0,0,1,cx,cy);
ctx.lineWidth = width;
ctx.lineCap = "round";
ctx.strokeStyle = style;
ctx.beginPath();
roundedPath(path, radius);
ctx.closePath();
ctx.stroke();
}
function fillRoundedPath(cx, cy, path, radius, style) {
ctx.setTransform(1,0,0,1,cx,cy);
ctx.fillStyle = style;
ctx.beginPath();
roundedPath(path, radius);
ctx.fill();
}
function loop() {
ctx.setTransform(1,0,0,1,0,0);
ctx.clearRect(0,0,canvas.width,canvas.height);
fillRoundedPath(polyRadius, polyRadius, hexPoly, cornerRadius, "#000");
fillRoundedPath(polyRadius, polyRadius, hexPolyInner, cornerRadius - barWidth * inset * 2, "#F80");
ctx.lineDashOffset = approxLineLen - (progress % 1) * approxLineLen;
strokeRoundedPath(polyRadius, polyRadius, hexBar, cornerRadius - barWidth * inset, "#09C", barWidth);
progress += 0.005;
requestAnimationFrame(loop);
}
<canvas id="canvas" width = "210" height="210"></canvas>

Rotating Rectangles Around Circle Perimeter on Canvas

I'm trying to create a little circular "equalizer" effect using JavaScript and HTML canvas for a little project I'm working on, and it works great, except one little thing. It's just a series of rectangular bars moving in time to an mp3 - nothing overly fancy, but at the moment all the bars point in one direction (i.e. 0 radians, or 90 degrees).
I want each respective rectangle around the edge of the circle to point directly away from the center point, rather than to the right. I have 360 bars, so naturally, each one should be 1 degree more rotated than the previous.
I thought that doing angle = i*Math.PI/180 would fix that, but it doesn't seem to matter what I do with the rotate function - they always end up pointing in weird and wonderful directions, and being translated a million miles from where they were. And I can't see why. Can anyone see where I'm going wrong?
My frame code, for reference, is as follows:
function frames() {
// Clear the canvas and get the mp3 array
window.webkitRequestAnimationFrame(frames);
musicArray = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(musicArray);
ctx.clearRect(0, 0, canvas.width, canvas.height);
bars = 360;
for (var i = 0; i < bars; i++) {
// Find the rectangle's position on circle edge
distance = 100;
var angle = i * ((Math.PI * 2) / bars);
var x = Math.cos(angle) * distance + (canvas.width / 2);
var y = Math.sin(angle) * distance + (canvas.height / 2);
barWidth = 5;
barHeight = (musicArray[i] / 4);
// Fill with a blue-green gradient
var grd = ctx.createLinearGradient(x, 0, x + 40, 0);
grd.addColorStop(0, "#00CCFF");
grd.addColorStop(1, "#00FF7F");
ctx.fillStyle = grd;
// Rotate the rectangle according to position
// ctx.rotate(i*Math.PI/180); - DOESN'T WORK
// Draw the rectangle
ctx.fillRect(x, y, barHeight, barWidth);
}
For clarity I've removed part of your code. I'm using rotate as you intended. Also I'm using barHeight = (Math.random()* 50); instead your (musicArray[i]/4); because I wanted to have something to show.
Also I've changed your bars to 180. It's very probable that you won't have 360 bars but 32 or 64 or 128 or 256 . . . Now you can change the numbers of bare to one of these numbers to see the result.
I'm drawing everything around the origin of the canvas and translating the context in the center.
I hope it helps.
const canvas = document.getElementById("c");
const ctx = canvas.getContext("2d");
let cw = canvas.width = 400;
let ch = canvas.height = 400;
let bars = 180;
let r = 100;
ctx.translate(cw / 2, ch / 2)
for (var i = 0; i < 360; i += (360 / bars)) {
// Find the rectangle's position on circle edge
var angle = i * ((Math.PI * 2) / bars);
//var x = Math.cos(angle)*r+(canvas.width/2);
//var y = Math.sin(angle)*r+(canvas.height/2);
barWidth = 2 * Math.PI * r / bars;
barHeight = (Math.random() * 50);
ctx.fillStyle = "green";
// Rotate the rectangle according to position
// ctx.rotate(i*Math.PI/180); - DOESN'T WORK
// Draw the rectangle
ctx.save();
ctx.rotate(i * Math.PI / 180);
ctx.fillRect(r, -barWidth / 2, barHeight, barWidth);
//ctx.fillRect(r ,0, barHeight, barWidth);
ctx.restore();
}
canvas {
border: 1px solid
}
<canvas id="c"></canvas>
Here is another solution, I'm preserving your initial trigonometry approach.
But instead of rectangles I used lines, I don't think it makes a difference for you, if what you need is bars moving in time to an mp3 all you need to do is change the var v = Math.random() + 1; to a reading from the Amplitude, and those bars will be dancing.
const canvas = document.getElementById("c");
canvas.width = canvas.height = 170;
const ctx = canvas.getContext("2d");
ctx.translate(canvas.width / 2, canvas.height / 2)
ctx.lineWidth = 2;
let r = 40;
let bars = 180;
function draw() {
ctx.clearRect(-100, -100, 200, 200)
for (var i = 0; i < 360; i += (360 / bars)) {
var angle = i * ((Math.PI * 2) / bars);
var x = Math.cos(angle) * r;
var y = Math.sin(angle) * r;
ctx.beginPath();
var v = Math.random() + 1;
ctx.moveTo(x, y);
ctx.lineTo(x * v, y * v)
grd = ctx.createLinearGradient(x, y, x*2, y*2);
grd.addColorStop(0, "blue");
grd.addColorStop(1, "red");
ctx.strokeStyle = grd;
ctx.stroke();
}
}
setInterval(draw, 100)
<canvas id="c"></canvas>

Rotating a line around a circle

I have two arcs with strokes and i want to have a line animate between them. The line should animate perpendicular to the points of the inner circle.
Here's something that I hacked together that is almost what I want.
things that are wrong with it are:
the length of the line is not the length between the 2 circle as it revolves around the inner circle.
sometimes the line is not perpendicular to the points of the inner circle. for example when it goes to the corner of the circle it tilts at an angle a little.
I had problem understanding how to use the trig function for lineTo. maybe because that changes the length of the line and I didn't know how to get the x and y coordinates of the outer circle to get the end point of the line. I'm used to doing math.cos * length and this gives me a line at an angle. I don't what a line I just wanted the coords of the outer circle.
window.onload = function(){
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
function lineAtAngle(startX, startY, angleDeg, length, startX2, startY2, angleDeg2, length2){
var angle = angleDeg * (Math.PI / 180);
var angle2 = angleDeg2 * (Math.PI / 180);
// context.moveTo(startX, startY);
context.beginPath();
context.moveTo(
Math.cos(angle) * length + startX,
Math.sin(angle) * length + startY
)
context.lineTo(
Math.cos(angle2) *(length2 )+ startX2,
Math.sin(angle2) *(length2) + startY2
)
// context.lineTo(canvas.width / 2 + 60, canvas.height / 2, angle2, length2)
context.lineWidth = 10;
context.stroke();
context.closePath();
console.log("startX2: " + startX2 + " startY2: " + startY2 )
console.log(Math.sin(angle2) + startY2)
console.log(length)
}
function myLineTo(startX, startY, angleDeg, length){
}
var length1 = canvas.width / 2 + 60 - canvas.width / 2 -30
var length2 = canvas.width / 2 ;
// var length2 = 1;
console.log(length2)
var angle1 = 0;
var angle2 = 0;
(function animate(){
context.clearRect(0,0, canvas.width, canvas.height);
window.requestAnimationFrame(animate);
context.beginPath()
context.arc(canvas.width / 2, canvas.height / 2, 30, 0, 2 * Math.PI, true)
context.lineWidth = 1;
context.stroke()
context.beginPath();
context.arc(canvas.width / 2, canvas.height / 2, 60, 0, 2 * Math.PI, true);
context.stroke();
context.closePath()
context.beginPath();
context.arc(canvas.width / 2, canvas.height / 2, 3, 0, 2 * Math.PI, true)
context.fill()
context.closePath();
angle1++
angle2++
// lineAtAngle(canvas.width / 2 , canvas.height / 2 , angle1, length1, canvas.width / 2 + 60, canvas.height / 2, angle2, length2 )
lineAtAngle(canvas.width / 2 , canvas.height / 2 , angle1, length1, canvas.width / 2 + 60, canvas.height / 2, angle2, length2 )
}())
}
canvas{
background: #aaa;
}
<canvas id="canvas" width="400" height="400"></canvas>
I believe the below is what you're trying to achieve.
I've simplified the code somewhat by using the Canvas's built-in methods to translate the coordinate space to the center and by removing the extra function which had way too many parameters passed when all it needed was one angle and two radii.
window.onload = function(){
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var radius1 = 30;
var radius2 = 60;
var angle = 0;
(function animate(){
context.clearRect(0, 0, canvas.width, canvas.height);
// save state and adjust coordinate space
context.save();
context.translate(canvas.width / 2, canvas.height / 2);
context.lineWidth = 1;
context.beginPath()
context.arc(0, 0, radius1, 0, 2 * Math.PI, true)
context.stroke()
context.beginPath();
context.arc(0, 0, radius2, 0, 2 * Math.PI, true);
context.stroke();
context.beginPath();
context.arc(0, 0, 3, 0, 2 * Math.PI, true);
context.fill()
++angle;
var rads = angle * Math.PI / 180;
var x = Math.cos(rads);
var y = Math.sin(rads);
context.lineWidth = 10;
context.beginPath();
context.moveTo(radius1 * x, radius1 * y);
context.lineTo(radius2 * x, radius2 * y);
context.stroke();
// restore transformations for next pass
context.restore();
window.requestAnimationFrame(animate)
}())
}
canvas { background: #aaa; }
<canvas id="canvas" width="400" height="200"></canvas>
The idea for drawing a line is that you need to supply a start point (moveTo), and an end point (lineTo). Your current code is complicating the whole thing with multiple angles and lengths. What you want to imagine you are doing is starting at the center of your circle, then adding an offset which places the start point at the edge of the inner circle. Using trig is perfectly fine here. The length of your line will simply be outer radius minus inner radius, in the same direction as your offset (only one angle was needed).
Without fundamentally changing your approach, the code below shows the changes you could use to try this. Have your line function take a starting point (x, y) and an offset, as well as the angle and length. The starting point is your circle center, and the offset is the radius of the inner circle. The length (again) is simply the outer radius minus the inner radius.
window.onload = function(){
var innerCircleRadius = 30;
var outerCircleRadius = 60;
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var angle1 = 0;
function lineAtAngle(startX, startY, angleDeg, offset, length) {
var angle = angleDeg * (Math.PI / 180); // Convert to radians.
var cosAngle = Math.cos(angle); // Only need cos(angle) once.
var sinAngle = Math.sin(angle); // Only need sin(angle) once.
var startXPos = cosAngle * offset + startX;
var startYPos = sinAngle * offset + startY;
var endXPos = cosAngle * length + startXPos;
var endYPos = sinAngle * length + startYPos;
context.beginPath();
context.moveTo(startXPos, startYPos);
context.lineTo(endXPos, endYPos);
context.lineWidth = 10;
context.stroke();
context.closePath();
}
(function animate() {
context.clearRect(0,0, canvas.width, canvas.height);
window.requestAnimationFrame(animate);
context.beginPath()
context.arc(canvas.width / 2, canvas.height / 2, innerCircleRadius, 0, 2 * Math.PI, true)
context.lineWidth = 1;
context.stroke()
context.beginPath();
context.arc(canvas.width / 2, canvas.height / 2, outerCircleRadius, 0, 2 * Math.PI, true);
context.stroke();
context.closePath()
context.beginPath();
context.arc(canvas.width / 2, canvas.height / 2, 3, 0, 2 * Math.PI, true)
context.fill()
context.closePath();
angle1++
lineAtAngle(canvas.width / 2 , canvas.height / 2 , angle1, innerCircleRadius, outerCircleRadius - innerCircleRadius);
}())
}
canvas {
background: #aaa;
}
<canvas id="canvas" width="400" height="400"></canvas>

animating an angle of a triangle

I have two lines that make a 90 degree angle, I hope. I want to make it so that the vertical line moves down to the horizontal line. The angle is the pivot point. so the angle should decrease to 0 I guess. 45 would be half way.
the length of the lines should be the same during the animation.
the animation should be looping. It should go from 90 degree angle to
0 degree angle and back.
1 way I was thinking to figure this out was to change the context.moveTo(50,50) the parameters numbers so the line should begin to be drawn at the new coordinates during the animation. I had problems keeping the line the same size as the horizontal.
another way I was thinking was to change the Math.atan2. I don't know have it start at 90 degrees then go to 0 and have that reflect on the moveto parameters I don't know how to put this together.
I would prefer to use a solution with trigonometry because that is what I'm trying to get good at
for extra help if you could attach a hypotenuse so I could see the angle change the size of the triangle that would be great. That was my original problem. Thanks
window.onload = function(){
var canvas =document.getElementById("canvas");
var context = canvas.getContext("2d");
var length = 50
context.beginPath();
context.moveTo(50,50)
context.lineTo(50,200);
context.stroke();
context.closePath();
context.beginPath();
context.moveTo(50, 200);
context.lineTo(200, 200)
context.stroke();
context.closePath();
var p1 = {
x: 50,
y : 50
}
var p2 = {
x: 50,
y: 200
}
var angleDeg = Math.atan2(p2.y - p1.y, p2.x - p1.x) * 180 / Math.PI;
console.log(angleDeg)
}
<canvas id="canvas" width="400" height="400"></canvas>
This might help.
window.onload = function() {
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var length = 150;
var angle = 270;
var maxAngle = 360;
var minAngle = 270;
var direction = 0;
var p1 = {
x: 50,
y: 200
};
var p2 = {
x: 200,
y: 200
};
context.fillStyle = "rgba( 255, 0, 0, 0.5)";
function draw() {
context.clearRect(0, 0, 400, 400);
context.beginPath();
context.moveTo(p1.x, p1.y);
context.lineTo(p2.x, p2.y)
if (angle >= maxAngle) {
direction = 1;
} else if (angle <= minAngle) {
direction = 0;
}
if (direction == 0) {
angle++;
} else {
angle--;
}
var x = p1.x + length * Math.cos(angle * Math.PI / 180);
var y = p1.y + length * Math.sin(angle * Math.PI / 180);
context.moveTo(p1.x, p1.y);
context.lineTo(x, y);
context.lineTo(p2.x, p2.y);
context.stroke();
context.fill()
context.closePath();
}
setInterval(draw, 50);
}
<canvas id="canvas" width="400" height="400"></canvas>
To get angle sequence (in degrees) like 90-45-0-45-90-45..., you can use this simple algo (pseudocode):
i = 0
while (drawingNeeded) do
angle = Math.Abs(90 - (i % 180)) * Math.PI / 180;
endPoint.x = centerPoint.x + lineLength * Math.Cos(angle);
endPoint.y = centerPoint.y + lineLength * Math.Sin(angle);
//redraw canvas, draw static objects
drawLine(centerPoint, endPoint);
i++;

How can I bisect the circle?

I'm trying to bisect a circle with JavaScript and a <canvas> element. I used the formula given in the accepted answer to this question to find points on the edge of the circle, but for some reason when I give two opposite points on the circle (0 and 180, or 90 and 270, for example) I'm not getting a line that goes through the center of the circle.
My code, which you can see on JSFiddle, makes a nice Spirograph pattern, which is cool except that that's not what I'm trying to do.
How do I fix this so the lines go through the center?
(Ultimately I'm trying to draw a circle of fifths, but all I'm asking how to do now is get the lines to go through the center. Once that works I'll get on with the other steps to do the circle of fifths, which will obviously include drawing fewer lines and losing the Spirograph torus.)
Degrees in Javascript are specified in radians. Instead of checking for greater than or less than 180, and adding or subtracting 180, do the same with Math.PI radians.
http://jsfiddle.net/7w29h/1/
Drawing function and trigonometry function in Math expects angle to be specified in radian, not degree.
Demo
Diff with your current code:
function bisect(context, degrees, radius, cx, cy) {
// calculate the point on the edge of the circle
var x1 = cx + radius * Math.cos(degrees / 180 * Math.PI);
var y1 = cy + radius * Math.sin(degrees / 180 * Math.PI);
/* Trimmed */
// and calculate the point on the opposite side
var x2 = cx + radius * Math.cos(degrees2 / 180 * Math.PI);
var y2 = cy + radius * Math.sin(degrees2 / 180 * Math.PI);
/* Trimmed */
}
function draw(theCanvas) {
/* Trimmed */
// 2 * PI, which is 360 degree
context.arc(250, 250, 220, 0, Math.PI * 2, false);
/* Trimmed */
context.arc(250, 250, 110, 0, Math.PI * 2, false);
/* Trimmed */
// No need to go up to 360 degree, unless the increment does
// not divides 180
for (j = 2; j < 180; j = j + 3) {
bisect(context, j, 220, 250, 250);
}
/* Trimmed */
}
Appendix
This is the full source code from JSFiddle, keep the full copy here just in case.
HTML
<canvas id="the_canvas" width="500" height="500"></canvas>
CSS
canvas {
border:1px solid black;
}
JavaScript
function bisect(context, degrees, radius, cx, cy) {
// calculate the point on the edge of the circle
var x1 = cx + radius * Math.cos(degrees / 180 * Math.PI);
var y1 = cy + radius * Math.sin(degrees / 180 * Math.PI);
// get the point on the opposite side of the circle
// e.g. if 90, get 270, and vice versa
// (super verbose but easily readable)
if (degrees > 180) {
var degrees2 = degrees - 180;
} else {
var degrees2 = degrees + 180;
}
// and calculate the point on the opposite side
var x2 = cx + radius * Math.cos(degrees2 / 180 * Math.PI);
var y2 = cy + radius * Math.sin(degrees2 / 180 * Math.PI);
// now actually draw the line
context.beginPath();
context.moveTo(x1, y1)
context.lineTo(x2, y2)
context.stroke();
}
function draw(theCanvas) {
var context = theCanvas.getContext('2d');
// draw the big outer circle
context.beginPath();
context.strokeStyle = "#222222";
context.lineWidth = 2;
context.arc(250, 250, 220, 0, Math.PI * 2, false);
context.stroke();
context.closePath();
// smaller inner circle
context.beginPath();
context.strokeStyle = "#222222";
context.lineWidth = 1;
context.arc(250, 250, 110, 0, Math.PI * 2, false);
context.stroke();
context.closePath();
for (j=2; j < 180; j = j + 3) {
bisect(context, j, 220, 250, 250);
}
}
$(function () {
var theCanvas = document.getElementById('the_canvas');
console.log(theCanvas);
draw(theCanvas, 50, 0, 270);
});

Categories