aligning n-circels on a circle > no overlapping - javascript

for a data visualization im aligning n-circels on a circle.
That just works fine - but i dont't know how to stop the circles
overlapping each other. Anybody here knows howto?
The result should work like this sketch:
Link: http://www.xup.to/dl,79345003/sketch.jpg
So i dont know how to calculate the angle for the second node
- based on the radius an position of the first node - and the
radius of the second ...
JSFIDDLE to show what i mean: http://jsfiddle.net/0z9hyvxk/
var canvas = document.getElementById("canvas");
var stage = new createjs.Stage(canvas);
canvas.width = 500;
canvas.height = 500;
var midx = 250;
var midy = 250;
var radius = 200;
var angle = 0;
var count = 30;
var step = 2 * Math.PI / count;
var xpos;
var ypos;
var nodeSize;
var node = function(size){
var dot = new createjs.Shape();
dot.graphics.beginFill("#000").drawCircle(0, 0, size);
dot.x = dot.y = -5;
dot.alpha = .25;
return dot
};
for(var i = 0; i<count; i++)
{
xpos = radius * Math.cos(angle) + midx;
ypos = radius * Math.sin(angle) + midx;
nodeSize = i;
var n = new node(nodeSize);
n.x = xpos;
n.y = ypos;
stage.addChild(n)
angle += step;
}
stage.update();
thanks in advance
simon

Your program does not make corrections based on circle sizes and angle. Smaller circles are too far from each other, bigger ones are too close.
r1 = radius of the n-th small circle
r2 = radius of the (n+1)-th small circle.
r3 = radius of the (n+2)-th small circle
r1<r2<3, so angle between 1 and 2 is smaller than between 2 and 3.
Try to tangentially increase angle correction. I can't test code at work :(

Related

PlotlyJS rotate ellipse

Is there a way to rotate the ellipse in PlotlyJS? To draw a circle/ellipse in Plotly, you define the center and the radii in the positive and negative x and y directions. Is there a way to define an angle at which the ellipse is rotated around its center or perhaps defining the 4 outermost points of the ellipse instead perhaps rather than having plotly deducing them through the radii values?
You can "manually" construct the points of the ellipse:
var center_x = 0;
var center_y = 0;
var a = 3; // major radius
var b = 1; // minor radius
var alpha = Math.PI / 4; // angle of rotation;
var X = [];
var Y = [];
var npoints = 100;
for(var i = 0; i <= npoints; i++) {
var t = 2 * Math.PI * i / npoints;
var x = a * Math.cos(t);
var y = b * Math.sin(t);
X.push(center_x + Math.cos(alpha)*x - Math.sin(alpha)*y);
Y.push(center_y + Math.sin(alpha)*x + Math.cos(alpha)*y);
}
Then plot it with a line type.

Circle radius not being sized correctly

my script isn't working. It was supposed to create random circles all touching the bottom of the canvas, with their radius shrinking each circle by the number of circles.
Here is the code:
for (var i = 0; i < NUM_CIRCLES; i++){
var circle = new Circle(radius);
circle.setPosition(CENTER_X,CENTER_Y);
circle.setColor(color);
add(circle);
radius /= i;
CENTER_Y = getHeight() - radius;
color = Randomizer.nextColor();
}
Ok so here is the full code:
var NUM_CIRCLES = 30;
var BIG_RADIUS = 180;
var color = Randomizer.nextColor();
var radius = BIG_RADIUS;
var CENTER_X = getWidth() / 2;
var CENTER_Y = getHeight() - radius;
function start(){
for (var i = 0; i < NUM_CIRCLES; i++){
var circle = new Circle(radius);
circle.setPosition(CENTER_X,CENTER_Y);
circle.setColor(color);
add(circle);
radius /= i;
CENTER_Y = getHeight() - radius;
color = Randomizer.nextColor();
}
}
as far as i understand you are trying to produce circles from bigger to smaller reducing radius of them by number of circles
to achive that do eachReduce = radius / numberofcircles and use it as eachReduce constant to reduce each circle by that number to achieve bigger to smaller size till zero
take a look at below example
let numofcir = 10,
radius = 80,
reduceEachBy = radius / numofcir,
offset = radius / 2
function setup() {
createCanvas(640, 360);
noLoop()
}
function draw() {
background(0)
stroke(255)
noFill()
for(let i=0;i < numofcir;i++){
// in p5 ellipse creates circle by x and y radius
ellipse(offset + (i * offset),150,radius,radius)
radius -= reduceEachBy
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.min.js" integrity="sha512-N4kV7GkNv7QR7RX9YF/olywyIgIwNvfEe2nZtfyj73HdjCUkAfOBDbcuJ/cTaN04JKRnw1YG1wnUyNKMsNgg3g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

Drawing diagonal lines at an angle within a rectangle

I'm trying to fill a rectangle with diagonal lines at 30 degrees that don't get clipped by the canvas. Each line should start and end on the edges of the canvas, but do not go outside the canvas.
I've gotten somewhat of a result but is struggling to understand how I can fix the ends so the lines become evenly distributed:
Here is the code I got so far:
const myCanvas = document.getElementById("myCanvas");
const _ctx = myCanvas.getContext("2d");
const canvasWidth = 600;
const canvasHeight = 300;
// Helper function
const degToRad = (deg) => deg * (Math.PI / 180);
const angleInDeg = 30;
const spaceBetweenLines = 16;
const lineThickness = 16;
_ctx.fillStyle = `black`;
_ctx.fillRect(0, 0, canvasWidth, canvasHeight);
const step = (spaceBetweenLines + lineThickness) / Math.cos(angleInDeg * (Math.PI / 180));
for (let distance = -canvasHeight + step; distance < canvasWidth; distance += step) {
let x = 0;
let y = 0;
if(distance < 0) {
// Handle height
y = canvasHeight - (distance + canvasHeight);
} else {
// Handle height
x = distance;
}
const lineLength = canvasHeight - y;
const slant = lineLength / Math.tan(degToRad((180 - 90 - angleInDeg)));
const x2 = Math.min(x + slant, canvasWidth);
const y2 = y + lineLength;
_ctx.beginPath();
_ctx.moveTo(x, y);
_ctx.lineTo(x2, y2);
_ctx.lineWidth = lineThickness;
_ctx.strokeStyle = 'green';
_ctx.stroke();
}
and a JSFiddle for the code.
What I'm trying to achieve is drawing a pattern where I can control the angle of the lines, and that the lines are not clipped by the canvas. Reference photo (the line-ends don't have flat):
Any help?
My example is in Javascript, but it's more the logic I'm trying to wrap my head around. So I'm open to suggestions/examples in other languages.
Update 1
If the angle of the lines is 45 degree, you will see the gutter becomes correct on the left side. So I'm suspecting there is something I need to do differently on my step calculations.
My current code is based on this answer.
Maybe try something like this for drawing the lines
for(var i = 0; i < 20; i++){
_ctx.fillrect(i * spaceBetweenLines + lineThickness, -100, canvas.height + 100, lineThickness)
}

JavaScript - rotate SVG based line's angle

I draw the line on Canvas and want to merge svg image on line based it's position. How can I find the angle between start and end points of draw line?
Edit
This function for get Angle of Line
public angleOfWall(p1,p2){
var angleDeg = Math.atan2(p2.y - p1.y, p2.x - p1.x) * 180 / Math.PI;
return angleDeg;
}
var angleOfWall = this.angleOfWall(closestWall.getStart(), closestWall.getEnd());
After find the angle, I want to merge img to on it.
for (let i = 0; i < this.model.floorplan.items.length; i++) {
item = this.model.floorplan.items[i];
var hover = item===this.viewmodel.activeItem;
var itemWidth = item.width|32;
var itemHeight = item.height|32;
if (!item.el) {
item.el = document.createElement('img');
// draw door line on that position
item.el.src = this.model.floorplan.items[i].model_url_2d;
item.el.onload = (( /** image **/ ) => {
this.context.drawImage(item.el,
this.viewmodel.convertX(item.xpos * item.scale_x) - itemWidth/2.,
this.viewmodel.convertY(item.zpos * item.scale_z) - itemHeight/2.,
itemWidth, itemHeight);
}
.("model_url2d" is SVG image's url )
private rotateSVG(rotateSVG) {
var innerArrow = document.getElementById("#add-items");
innerArrow.setAttribute("transform", rotateSVG);
}
Is it right way to follow line rotate position? Just Im new in JS side so need some help. thanks
here What I have now
but want to rotate img angle as line's angle
IMPORTANT: This answer addresses the question as of revision 1
This is the content of the question I answered:
"I draw the line on Canvas and want to merge svg image on line based it's position. How can I find the angle between start and end points of draw line?"
Given 2 points p1 and p2 you may calculate the angle between start and end points of the line drawn from p1 to p2 using the atan2 method.
If you consider the line as the hypotenuse and the distance in x (dx) & y (dy) as catheti you can write: let angle = Math.atan2(dy, dx);. This will give you the angle in radians. If you need the angle in degrees you have to: let angleInDegrees = angle*180/Math.PI
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
let cw = canvas.width = 300,
cx = cw / 2;
let ch = canvas.height = 300,
cy = ch / 2;
// given 2 points: p1 and p2
let p1 = {x:50, y:200},
p2= {x:200, y:50}
ctx.beginPath();
ctx.moveTo(p1.x, p1.y);
ctx.lineTo(p2.x, p2.y);
ctx.stroke();
//the distance in x & y between the 2 points
let dx = p2.x - p1.x;
let dy = p2.y - p1.y;
// the angle in radians
let angle = Math.atan2(dy, dx);
// the angle in degrees
console.log(angle*180/Math.PI)
canvas{border:1px solid #d9d9d9;}
<canvas></canvas>
I hope this helps.

How to translate and rotate chairs around a table

I'd like to evenly devide a n number of chairs around a round table.
Tried several solutions that involve animation an object around a circle, but I'm not able to convert any of them to a solution for my problem.
(http://jsfiddle.net/m1erickson/dFctW/ and http://jsfiddle.net/Cu6Zv/1/)
The project I'm working on involves a chosen amount of chairs that need to be devided among a chosen amount of tables. I managed to sort of build a prototype, but the chairs are not evenly devided and not rotated toward the center of the table.
var step = 360 / chairs;
for(var count = 0; count < chairs; count++){
angle += Math.acos(1-Math.pow(step/radius,2)/2);
var x = cx + radius * Math.cos(angle);
var y = cy + radius * Math.sin(angle);
ctx.rect(x-5,y-5,10,10);
ctx.stroke();
}
I created a jsfiddle of what I've got so far.
Hopefully someone can explain me how to:
Translate the chairs evenly around the circle
Rotate each chair to line up with the table (pointed towards the center of the table)
Perhaps explain the math behind it, so I can understand what it's doing and how it could be adapted if needed.
Thanks in advance.
You're almost at right track with the code. Simply use radians instead and drop the acos line:
var ctx = c.getContext("2d");
var angle = 0;
var chairs = 6;
var cx = c.width>>1, cy = c.height>>1, radius = (c.height>>1)-10;
var step = Math.PI * 2 / chairs;
for(var count = 0; count < chairs; count++){
var x = cx + radius * Math.cos(angle);
var y = cy + radius * Math.sin(angle);
ctx.rect(x-5,y-5,10,10);
angle += step;
}
ctx.stroke();
<canvas id=c></canvas>
Now, all the chairs will face the same direction. If you want to rotate them so they face center of tables it's perhaps easier to use transforms instead of manually calculating the position:
var ctx = c.getContext("2d");
var angle = 0;
var chairs = 6;
var cx = c.width>>1, cy = c.height>>1, radius = (c.height>>1)-10;
var step = Math.PI * 2 / chairs;
// translate to center
ctx.translate(cx, cy);
for(var count = 0; count < chairs; count++){
// rotate around center (0,0)
ctx.rotate(step);
// draw using radius as offser on x-axis only
ctx.rect(radius -5,-5,10,10);
ctx.rect(radius -5, -1, 4,2);
}
ctx.stroke();
<canvas id=c></canvas>
For your first problem, try changing:
var step = 360 / chairs;
to
var step = 360 / (chairs + 1);

Categories

Resources