Connecting arcs on HTML5 Canvas - html

I am trying to make a donut chart using the arc function in the HTML5 canvas. I am wanting to know how to use the lineTo function to connect two arcs together.
At the moment I have a pie chart which has fixed central x/y coords, so making the slices is easy as once the arc of each slice is done, the lineTo method simply uses the the fixed coords.
However with a ring/donut chart, I have two arcs, one with a smaller radius, but no idea how to connect the ends together without horrifically complicated trigonometry. Is there any way to get the 'start' and 'end' x/y coords of the arc?
I have a current hackyish 'solution' of simply drawing a smaller white circle over the pie chart to give the ring graph, but I want to know the answer to the question above.

You just have to remember a little trigonometry. If your center point is x, y and radius is r; then the coordinates on the circle at an angle alpha are:
pointX = x + Math.cos(alpha) * r;
pointY = y + Math.sin(alpha) * r;
And you have two of those angles, corresponding to the starting and the ending point.

Why are you drawing arcs? Would'nt it be easier if you just draw the circle (or circles for the ring) and then draw radius?

Related

Libgdx rotating ellipse for collision detection

I try to use 2 ellipses to detect a collision if they overlap. I have to rotate the ellipses but I can't figure out how this works. I'm working with the "com.badlogic.gdx.math.Ellipse" class but it seems to have no method for rotating. Any ideas? Thx in advance!!
Unfortunately, LibGDX doesn't have in-built rotating functions for ellipses.
Instead, I'd either be resorting to a circle in which rotation does not matter, or use polygons to check intersection.
Polygons are formed through an array of float values (vertices), where, every even element of the array is the horizontal component (x) and the odd, the vertical component (y).
Polygon polygon1 = new Polygon(vertexSet1);
Polygon polygon2 = new Polygon(vertexSet2);
Then, by using an Intersector, you can then check whether these polygons have intersected. The more vertices, the more accurate your shape will be. Just remember to have 6 or more elements in your vertex array, as the 6 floats will give 3 (x, y) points which is the minimum required for a polygon.
if (intersector.overlapConvexPolygons(polygon1, polygon2) {
//do your intersection code
}
The polygons themselves have commands to translate, scale and rotate, allowing for the rotations you mentioned above.

I want to draw a pipeline image like draw a line that follow the mouse cursor

I want to draw a pipeline image (below) like draw a line, that follow the mouse cursor. When I press down the left button,and move the mouse cursor,the pipeline image draw to the cursor position (Like bessel curve)
. How can I do that? Thank you!
Here’s an example of how to define a “tube” given some mouse points.
The red points connected by red lines represent your mouse points.
The green & blue lines are calculated to be parallel to the red mouse line with an offset of 15 pixels.
The green & blue lines form the outside of your tube.
I'll help you with the math, but styling your tube is up to you.
Requires some trigonometry...ready?
Given that your mouse travels along a polyline (a series of points connected by line segments). Your mouse points are the red line in the illustration.
At each point, calculate 2 points perpendicular to that point and on either side of that point.
When you connect these perpendicular points, they become the sides of your "tube". These are the green & blue lines on either side of the mouse line.
How:
Use Math.atan2 to calculate the angle of slope between [x1,y1] and [x2,y2].
var dx=x2-x1;
var dy=y2-y1;
var originalAngle=Math.atan2(dy,dx);
Use Math.cos/Math.sin to find 2 points perpendicular to [x1,y1]
// a perpendicular angle is always 90 degrees different
// from the angle of the original line.
// (90 degrees == Math.PI/2 radians)
// let's subtract 90 degrees
var perpendicularAngle=originalAngle-Math.PI/2;
// let's get a perpendicular point that's
// 15 pixels away from [x1,y1]
var offsetLength=15;
// use cosine and sine to calculate that perpendicular point
var perpX1=x1+offsetLength*Math.cos(perpendicularAngle);
var perpY1=y1+offsetLength*Math.sin(perpendicularAngle);
// repeat to get the opposite perpendicular point
// This time add 90 degrees to the original angle.
var perpendicularAngle=originalAngle+Math.PI/2;
var perpX2=x1+offsetLength*Math.cos(perpendicularAngle);
var perpY2=y1+offsetLength*Math.sin(perpendicularAngle);
One edge issue you must work around: If the angle of slope is either horizontal or vertical, the cosine/sine calculation won't work. Instead, just add/subtract the offset length to the point.
The math part is done!
Now just style the data-points as you desire. Maybe connect the perpendicular points on each side of the mouse line to form the sides of your tube. Apply some semi-transparent fill to allow the background to show through. Whatever your design requires.
Good luck with your project!

Rotate the group and scribbling on the group in a stage.. postting with code

Please this fiddle I have copied my complete project in it
here if you open the fiddle in the output you can see an image, scribble on the image selecting pen,add text etc(like this perform some functions).then rotate the group using rotate button and then try to scribble you will understand what is the problem exactly.
In me view Problem is I am having a stage and a layer is added to the stage and a group is added to the layer and different elements like lines text etc are added to the group. then group is rotated the i am trying to draw the line based on the mouse position of the stage.But it is not coming correctly because the group got rotated the x and y what we are taking to draw a line is from stage.I need to take the x and y from the group not from the stage is their any way.If hav't understand please ask me or post a reply.
This should get you fairly close: http://jsfiddle.net/k4qB8/24/
// This rotates that added active line along with your group.
// This makes the draw direction correct
activeline.setRotationDeg(0-rootGroup.getRotationDeg());
// Here you'll have to figure a way to calculate how much to move the
// line over so the draw is on the correct spot
// This is as close as I got it
if(Math.abs(rootGroup.getRotationDeg()%360)==0)
activeline.move(rootGroup.getX()-375, rootGroup.getY()-175);
if(Math.abs(rootGroup.getRotationDeg()%360)==90)
activeline.move(rootGroup.getX()-175, rootGroup.getY()+375);
if(Math.abs(rootGroup.getRotationDeg()%360)==180)
activeline.move(rootGroup.getX()+375, rootGroup.getY()+175);
if(Math.abs(rootGroup.getRotationDeg()%360)==270)
activeline.move(rootGroup.getX()+175, rootGroup.getY()-375);
Also, add some more logic for counter-clockwise rotation, as this doesn't work 100%.
I think the real solution would be to just draw on separate layers for each rotation, kind of like this:
if (rotation is 90) : draw on lineLayer1;
if (rotation is 180) : draw on lineLayer2;
if (rotation is 270) : draw on lineLayer3;
if (rotation is 360 || 0) : draw on lineLayer4;
This way you could just rotate the layers which are not drawn on to simulate the feel of rotation.

HTML5 Canvas (or alternative): Moving lines to simulate meridians on a planet

This is my firs excursion on the HTML5 canvas, I have working knowledge of jQuery and Javascript.
I'm trying to create a "spinning globe" effect with it.
The idea is to have a circle and meridians "spinning" on it, to give the effect of a rotating globe.
I've drawn the circle and now I'm trying to create lines that start from the right (following the curve of the circle), move towards the centre straightnening up (in the middle they are straight) and follow the inverse curvature on the left, ending with the circle.
I'm trying to do this with the HTML5 canvas and jQuery but I'm not sure of where to start... should I create an arc and then try to animate it?
I'm even wondering if the canvas is the right tool or if I should use anything else.
Any suggestion is welcome!
Sebastian
You could use a quadratic bezier curve, which is basically just a curve with a start point, an end point, and a "control point" in the middle, which is what you would want to change as the globe spins. In this case, all of your lines would start and end at the north and south poles, respectively, of your "globe". For example, to make one of these lines:
// start drawing a line
canvas.beginPath();
// move the the top of your globe
canvas.moveTo(0,0);
/* draw a curve with the control point specified by the first two args,
* end point by the second two:
* (in your case, the control point would be in the middle of the globe) */
canvas.quadraticCurveTo(control_point_x, control_point_y, 0, 50);
// finish drawing, stroke and end
canvas.stroke();
canvas.closePath();
You would also have to take in to account how you will clear the lines after each frame, of course.
See: The Canvas element API, Complex Paths
This is what I got, didn't have the time to proceed any further: http://jsfiddle.net/Z6h3Z/
I use bezier curves where the two control points are in a sort of oval arc centered at the poles.
What I got stuck at is the distribution of points along the arc to look more realistic.

How to draw a circle sector on an html5 canvas?

I'm trying to make a sort of pie-chart shape on a canvas element, however I can't seem to find any function that does this by itself. I only seem to be able to draw full circles and segments. Is there an easy way to do this?
(See also: Wikipedia on circle terminology)
The following should work:
context.moveTo(cx,cy);
context.arc(cx,cy,radius,startangle,endangle);
context.lineTo(cx,cy);
context.stroke(); // or context.fill()
with cx, cy being the center of the arc.