I'm trying to make a circle from a radius and x,y coordinate. I have it all done except the array is not the correct format for my use.
I get:
[
"X_PROPS:40,Y_PROPS:0",
"X_PROPS:39.99390780625565,Y_PROPS:0.6980962574913405",
"X_PROPS:39.97563308076383,Y_PROPS:1.3959798681000388",
"X_PROPS:39.94518139018295,Y_PROPS:2.093438249717753"
]
but I need:
[
{X_PROPS:40,Y_PROPS:0},
{X_PROPS:39.99390780625565,Y_PROPS:0.6980962574913405},
{X_PROPS:39.97563308076383,Y_PROPS:1.3959798681000388},
{X_PROPS:39.94518139018295,Y_PROPS:2.093438249717753}
]
I tried this:
function spec(radius, steps, centerX, centerY){
var xValues = [centerX];
var yValues = [centerY];
var result = [];
for (var i = 0; i < steps; i++) {
xValues[i] = (centerX + radius * Math.cos(2 * Math.PI * i / steps));
yValues[i] = (centerY + radius * Math.sin(2 * Math.PI * i / steps));
result.push('X_PROPS:'+ xValues[i]+','+'Y_PROPS:'+ yValues[i]);
}
return result;
}
console.log(spec(40,360,0,0))
This expression 'X_PROPS:'+ xValues[i]+','+'Y_PROPS:'+ yValues[i] creates a string. Create an object literal instead:
function spec(radius, steps, centerX, centerY) {
var result = [];
for (var i = 0; i < steps; i++) {
result.push({
X_PROPS: (centerX + radius * Math.cos(2 * Math.PI * i / steps)),
Y_PROPS: (centerY + radius * Math.sin(2 * Math.PI * i / steps))
});
}
return result;
}
console.log(spec(40, 360, 0, 0))
Related
I tried using this:
function getRandomInRange(from, to, fixed) {
return parseFloat((Math.random() * (to - from) + from).toFixed(fixed));
}
var latLongPairs = 4;
for(var i =0; i<latLongPairs; i++) {
console.log(`${getRandomInRange(-180, 180, 3)}, ${getRandomInRange(-180, 180, 3)}`);
}
That's ok for random numbers like 39.21988,9.124741 but they might end up not valid coordinates. And I need 100 of them.
Your latitude range is incorrect - it should be ±90.
function getRandomInRange(from, to) {
return Math.random() * (to - from) + from;
}
const latLongPairs = 4;
for (let i = 0; i < latLongPairs; ++i) {
let lat = getRandomInRange(-90, 90);
let lon = getRandomInRange(-180, 180);
console.log(`${lat.toFixed(3)}, ${lon.toFixed(3)}`);
}
You might need to provide some initial Latitude and longitude with some radius (in meters)
var getRandomLocation = function(latitude, longitude, radiusInMeters) {
var getRandomCoordinates = function(radius, uniform) {
// Generate two random numbers
var a = Math.random(),
b = Math.random();
// Flip for more uniformity.
if (uniform) {
if (b < a) {
var c = b;
b = a;
a = c;
}
}
// It's all triangles.
return [
b * radius * Math.cos(2 * Math.PI * a / b),
b * radius * Math.sin(2 * Math.PI * a / b)
];
};
var randomCoordinates = getRandomCoordinates(radiusInMeters, true);
// Earths radius in meters via WGS 84 model.
var earth = 6378137;
// Offsets in meters.
var northOffset = randomCoordinates[0],
eastOffset = randomCoordinates[1];
// Offset coordinates in radians.
var offsetLatitude = northOffset / earth,
offsetLongitude = eastOffset / (earth * Math.cos(Math.PI * (latitude / 180)));
return `${latitude + (offsetLatitude * (180 / Math.PI))}, ${longitude + (offsetLongitude * (180 / Math.PI))}`
};
for (i = 0; i < 182; i++) {
console.log(getRandomLocation(41.8819, -87.6278, 50))
}
I've created a script to calculate coordinates of a circle in JS. I'm using p5.js to draw the circle but when I run the script nothing happens. I assume it has to do with the way I'm plotting the vertices?
var xValues = [];
var yValues = [];
function setup() {
createCanvas(400, 400);
background(220);
crookedCircle(10, 10, 10, 10);
}
function draw() {}
function crookedCircle(radius, steps, centerX, centerY) {
for (var i = 0; i < steps; i++) {
xValues[i] = (centerX + radius * Math.cos(2 * Math.PI * i / steps));
yValues[i] = (centerY + radius * Math.sin(2 * Math.PI * i / steps));
for (let x = 0; x < xValues.length; x++) {
for (let y = 0; y < yValues.length; y++) {
//console.log("x: "+xValues[x] + " y: "+yValues[y])
beginShape();
vertex(xValues[x] + random(-10, 10), yValues[y]) + random(-10, 10);
endShape(CLOSE);
}
}
}
}
Here I cleaned what was written, I can annotate it to explain if you wish so. Also instead of random, I recommend you explore the noise() function here, which would make the circle look smoother.
function setup() {
createCanvas(400, 400);
background(220);
crookedCircle(10, 10, width / 2, height / 2);
}
function draw() {}
function crookedCircle(radius, steps, centerX, centerY) {
var xValues = [];
var yValues = [];
for (var i = 0; i < steps; i++) {
let rad = radius + random(-radius / 10,radius / 10) // you can change the 10 here to how intense you want the change to be;
xValues[i] = (centerX + rad * cos(2 * PI * i / steps));
yValues[i] = (centerY + rad * sin(2 * PI * i / steps));
}
beginShape();
for(let i = 0; i < xValues.length; i ++){
curveVertex(xValues[i], yValues[i]);
}
endShape(CLOSE);
}
You draw many many shapes with just 1 point. beginShape and endShape encloses the vertices of a shape. Therefore you have to call beginShape before the loop and endShape after the loop:
function crookedCircle(radius, steps, centerX, centerY) {
beginShape();
for (var i = 0; i < steps; i++) {
// [...]
}
endShape(CLOSE);
}
One loop is enough if you want to draw 1 circle:
var xValues = [];
var yValues = [];
function setup() {
createCanvas(400, 400);
}
function draw() {
background(220);
fill(255)
crookedCircle(100, 90, 120, 120);
}
function crookedCircle(radius, steps, centerX, centerY) {
for (var i = 0; i < steps; i++) {
xValues[i] = centerX + radius * Math.cos(2 * Math.PI * i / steps);
yValues[i] = centerY + radius * Math.sin(2 * Math.PI * i / steps);
}
beginShape();
for(let i = 0; i < steps; i ++) {
vertex(xValues[i] + random(-2, 2), yValues[i] + random(-2, 2));
}
endShape(CLOSE);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.3.1/p5.min.js"></script>
I would like to get random colors for each object in canvas how can i do that, I have tried this:
for (var i = 0; i < 100; i++) {
var raza = (Math.random() - 0.001) * 30;
var x = Math.random() * (innerWidth - raza * 2) + raza;
var y = Math.random() * (innerHeight - raza * 2) + raza;
var dx = (Math.random() - 0.5) * 4; //calcul viteza X
var dy = (Math.random() - 0.5) * 4; //calcul viteza Y
var color = c.strokeStyle = "#" + ((1 << 24) * Math.random() | 0).toString(12);
cercArray.push(new Circle(x, y, dx, dy, raza, color));
}
Lots of different ways to do this, here is an example using HSL.
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
let lastDate = Date.now() - 500;
function draw() {
requestAnimationFrame(draw);
const color = {
h: Math.floor(Math.random() * 360),
s: Math.floor(Math.random() * 100),
v: Math.floor(Math.random() * 100)
};
if (lastDate + 500 < Date.now()) {
lastDate = Date.now();
ctx.fillStyle = `hsl(${color.h},${color.s}% ,${color.v}%)`;
ctx.fillRect(0, 0, 100, 100);
}
}
draw();
<canvas></canvas>
My question is based on this question.
The code of the post is fantastic.
It creates a ring of satellite circles tangent to a base circle (Out of the base circle).
This part calculates the radius external to the circle:
var angle = Math.PI / n;
var s = Math.sin(angle);
var r = baseRadius * s / (1-s);
How to calculate the radius of the circles if I want the circle ring to be tangent inside the base circle?
I would greatly appreciate your help.
Modify your sub circles by Sine and Cosine and PI.
You can use this as a baseline:
//Classes
var Coord = (function() {
function Coord(x, y) {
this.x = x;
this.y = y;
}
return Coord;
}());
var Circle = (function() {
function Circle(origo, radius) {
this.origo = origo;
this.radius = radius;
}
Circle.prototype.circumference = function() {
return this.radius * 2 * Math.PI;
};
return Circle;
}());
//functions
function innerTangentCircles(master, count) {
if (count === void 0) {
count = 4;
}
var result = [];
for (var index = 0; index < count; index++) {
var cos = Math.cos(((Math.PI * 2) / count) * index);
var sin = Math.sin(((Math.PI * 2) / count) * index);
var circle = new Circle(new Coord(master.origo.x + (master.radius * cos) - (master.radius / (count / 2)) * cos, master.origo.y + (master.radius * sin) - (master.radius / (count / 2)) * sin), master.radius / (count / 2));
result.push(circle);
}
return result;
}
//>>Test<<
//Create circles
var bigC = new Circle(new Coord(200, 200), 200);
//Create DOM
var c = document.createElement("canvas").getContext("2d");
c.canvas.width = 500;
c.canvas.height = 500;
document.body.appendChild(c.canvas);
//Run loop
function draw(i) {
var circles = innerTangentCircles(bigC, i);
c.fillStyle = "red";
c.beginPath();
c.arc(bigC.origo.x, bigC.origo.y, bigC.radius, 0, Math.PI * 2);
c.fill();
c.closePath();
c.fillStyle = "yellow";
for (var index = 0; index < circles.length; index++) {
var circle = circles[index];
c.beginPath();
c.arc(circle.origo.x, circle.origo.y, circle.radius, 0, Math.PI * 2);
c.fill();
c.closePath();
}
if (i > 500) {
i = 4;
}
i = i * 2;
setTimeout(function() {
draw(i);
}, 1000);
}
draw(8);
/**
* Coord
*/
var Coord = (function() {
function Coord(x, y) {
this.x = x;
this.y = y;
}
return Coord;
}());
/**
* Circle
*/
var Circle = (function() {
function Circle(origo, radius) {
this.origo = origo;
this.radius = radius;
}
Circle.radiusFromCircumference = function(circumference) {
return circumference / Math.PI / 2;
};
Circle.circumference = function(radius) {
return 2 * Math.PI * radius;
};
Circle.prototype.circumference = function() {
return Circle.circumference(this.radius);
};
return Circle;
}());
//Functions
function distance(x1, y1, x2, y2) {
return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
}
function getRadian(count, index) {
return ((Math.PI * 2) / count) * index;
}
function circlesFromCircumference(master, count) {
var circles = [];
var masterCircumference = master.circumference();
var innerRadius = Circle.radiusFromCircumference(masterCircumference);
//var innerCircumference = Circle.circumference(innerRadius);
var circleRadius = 0;
var radian = getRadian(count, 1);
var maxCalc = 1000;
while (maxCalc--) {
var dist = distance(Math.cos(0) * innerRadius + master.origo.x, Math.sin(0) * innerRadius + master.origo.y, Math.cos(radian) * innerRadius + master.origo.x, Math.sin(radian) * innerRadius + master.origo.y);
if (Math.abs(dist / 2 - circleRadius) < 0.5) {
break;
}
circleRadius = dist / 2;
innerRadius = master.radius - circleRadius;
}
for (var index = 0; index < count; index++) {
var radian = getRadian(count, index);
var cos = Math.cos(radian);
var sin = Math.sin(radian);
var c = new Circle(new Coord(cos * innerRadius + master.origo.x, sin * innerRadius + master.origo.y), circleRadius);
circles.push(c);
}
return circles;
}
//>>TEST<<
var c = document.createElement("canvas").getContext("2d");
c.canvas.height = 200;
c.canvas.width = c.canvas.height;
document.body.appendChild(c.canvas);
var bigC = new Circle(new Coord(c.canvas.height / 2, c.canvas.height / 2), c.canvas.height / 2.1);
function draw(size) {
size++;
c.fillStyle = "red";
c.beginPath();
c.arc(bigC.origo.x, bigC.origo.y, bigC.radius, 0, Math.PI * 2);
c.fill();
c.closePath();
var circles = circlesFromCircumference(bigC, size);
c.fillStyle = "yellow";
for (var index = 0; index < circles.length; index++) {
var circle = circles[index];
c.beginPath();
c.arc(circle.origo.x, circle.origo.y, circle.radius, 0, Math.PI * 2);
c.fill();
c.closePath();
}
setTimeout(function() {
if (size > 32) {
size = 2;
}
draw(size);
}, 1000 / 4);
}
draw(1);
Im currently trying to figure out how to change the radious of arcs in canvas in every row and then back.
lets say i have have arcs like this
* * * *
* * * *
* * * *
what i want to do is do animation which will do as following
* * * * * * * * * * * * * * * * o o o o * * * *
* * * * * * * * * * * * o o o o * * * * * * * *
* * * * * * * * o o o o * * * * * * * * * * * *
* * * * o o o o * * * * * * * * * * * * * * * *
so far i have just drawn arcs on the canvas using
var canvas = document.getElementsByTagName("canvas")[0];
var ctx = canvas.getContext("2d");
canvas.width = 280;
canvas.height = 100;
var x = 18;
var y = 15;
var rows_x=1;
var rows_y=9;
for (var i = 1; i < 37; i++) {
ctx.beginPath();
ctx.arc(x, y, 5, 0, 2 * Math.PI);
ctx.stroke();
x += 30;
if (i % 9 === 0) {
x = 18;
y += 25;
}
}
x = 18;
y = 15;
function large() {
ctx.clearRect(0, 0, 280, 100);
for (var i = 1; i < 37; i++) {
ctx.beginPath();
if (i >rows_x&& i <= 9) {
ctx.arc(x, y, 10, 0, 2 * Math.PI);
ctx.fillStyle = 'green';
ctx.fill();
rows_x += 9;
rows_y += 10;
}
else {
ctx.arc(x, y, 5, 0, 2 * Math.PI);
ctx.stroke();
}
x += 30;
if (i % 9 == 0) {
x = 18;
y += 25
}
}}
setInterval(large,1000)
this my code has some glitch but thats not important. the change between the size of arcs is instant which mean it isnt animated or atleast doesnt look like that, how can i achieve the animation effect in this case?
You can perform your animation by using setTimout() function and recursive call.
EDIT
To perform some animation transition, you can use the window.requestAnimationFrame() method, which is a useful method to update animation before next repaint.
So, i have made a generic code which can handle any number of line.
//Retrieve context
var context = document.querySelector('#canvas').getContext('2d');
var count = 0;
var toRadius = 0;
var line_drawn = 0;
//Enter a number of line
var number_line = 5;
//Init function to buil our grid
function init(a){
var x = 10;
var y = 10;
//Calculate size of the grid
var size = Math.pow(number_line,2);
//Build our grid 4x4
for (var i = 0; i < size; ++i){
context.beginPath();
context.arc(x, y, 5, 0, 2 * Math.PI);
context.stroke();
x += 30;
++count;
count === number_line
? (count = 0, y += 25, x = 10)
: y;
}
//Call our draw function, start to fill bottom lane
draw(10, 10 + 25 * a)
}
function change(iterator){
setTimeout(function(){
//Reset our canvas
context.clearRect(0,0,600,600);
//Calculate the index of the new line that must be filled
var index = number_line - 1 - iterator;
//Re-build our grid and fill the new line
init(index);
}, 500);
}
function circle(x, y, radius){
context.arc(x, y, radius, 0, 2 * Math.PI);
context.fillStyle = 'green';
context.fill();
radius++;
if (radius < 11){
window.requestAnimationFrame(function(){
circle(x, y, radius);
});
}
}
function draw(x, y) {
context.beginPath();
//Use requestAnimationFrame
window.requestAnimationFrame(function(){
circle(x, y, toRadius);
});
++count;
//If we haven't draw all the line
if (count < number_line) {
//draw the next circle
draw(x+30, y);
} else {
count = 0;
++line_drawn;
line_drawn < number_line + 1
? change(line_drawn)
: ( line_drawn = 0, change(line_drawn) );
}
}
//Start to build the grid
init(number_line - 1);
And in your HTML :
<canvas id="canvas" width="600px" height="600px"></canvas>
You can see here the Working Plunker