When I want to draw a pie chart in SVG, all tutorials say that you need to calculate the end point of the arc element. Unless you want an exact 90° angle, that calculated point must unvariably fall beside the circumference line of the underlying circle because of rounding, if you scale up the scalable (!) graphic.
I cannot believe there is no way to draw a circle segment by giving a center, a radius and an angle.
Or is there?
Related
I have two endpoint of a line segment. I calculated the pixels to be colored using Mid Point Line algorithm. Now, I want to apply unweighted antialiasing to those pixels which provides the intensity of a pixel based on the area overlapping of that pixel and line.
I am asking for suggestions on how to find out those percentage of overlapping area?
It is not necessary that pixels are to be considered as rectangle only.
The Xiaolin Wu algorithm draws an anti-aliased line between two points. The points can be at sub-pixel, i.e. non-integer coordinates. I'll assume the reader is familiar with the algorithm and just recall the important features. We loop across the major (longer) axis of the line, let's say it's the x-axis, basically proceeding column-by-column. In each column we color two pixels. The computation is equivalent to this: place a 1x1 square centered on the line, at the point whose x coordinate is the center of the the given column of pixels. Let's call it S. If we think of each pixel as a 1x1 square in the plane, we now calculate the area of intersection between S and each of the two pixels it straddles, and use those areas as the intensities with which to color each pixel.
That's nice and clear, but what is going on with the calculations for the endpoints? Because the endpoints can be at non-integer positions, they have to be treated as a special case. Here's the pseudocode from the linked Wikipedia article for handling the first endpoint x0, y0:
// handle first endpoint
xend := round(x0)
yend := y0 + gradient * (xend - x0)
xgap := rfpart(x0 + 0.5)
xpxl1 := xend // this will be used in the main loop
ypxl1 := ipart(yend)
plot(ypxl1, xpxl1, rfpart(yend) * xgap)
plot(ypxl1+1, xpxl1, fpart(yend) * xgap)
I edited out the if (steep) condition, so this is the code for the case when the slope of the line is less than 1. rfpart is 1-fpart, and fpart is the fractional part. ipart is the integer part.
I just have no idea what this calculation is supposed to be doing, and I can't find any explanations online. I can see that yend is the y-coordinate of the line above xend, and xend is the x coordinate of the pixel that the starting point (x0, y0) is inside of. Why are we even bothering to calculate yend? It's as if we're extending the line until the nearest integer x-coordinate.
I realize that we're coloring both the pixel that the endpoint is in, and the pixel either immediately above or below it, using certain intensities. I just don't understand the logic behind where those intensities come from.
With the Xiaolin Wu algorithm (and sub-pixel rendering techniques in general) we imagine that the screen is a continuous geometric plane, and each pixel is a 1x1 square region of that plane. We identify the centers of the pixels as being the points with integer coordinates.
First, we find the so-called "major axis" of the line, the axis along which the line is longest. Let's say that it's the x axis. We now loop across each one-pixel-wide column that the line passes through. For each column, we find the point on the line which is at the center of that column, i.e. such that the x-axis is an integer. We imagine there's a 1x1 square centered at that point. That square will completely fill the width of that column and will overlap two different pixels. We color each of those pixels according to the area of the overlap between the square and the pixel.
For the endpoints, we do things slightly differently: we still draw a square centered at the place where the line crosses the centerline of the column, but we cut that square off in the horizontal direction at the endpoint of the line. This is illustrated below.
This is a zoomed-in view of four pixels. The black crosses represent the centers of those pixels, and the red line is the line we want to draw. The red circle (x0, y0) is the starting point for the line, the line should extend from that point off to the right.
You can see the grey squares centered on the red crosses. Each pixel is going to be colored according to the area of overlap with those squares. However, in the left-hand column, we cut-off the square at x-coordinate x0. In light grey you can see the entire square, but only the part in dark grey is used for the area calculation. There are probably other ways we could have handled the endpoints, for instance we could have shifted the dark grey region up a bit so it's vertically centered at the y-coordinate y0. Presumably it doesn't make much visible difference, and this is computationally efficient.
I've annotated the drawing using the names of variables from the pseudocode on Wikipedia.
The algorithm is approximate at endpoints. This is justified because exact computation would be fairly complex (and depend on the type of endpoint), for a result barely perceivable. What matters is aliasing along the segment.
Given a number of points on a 2d surface and radiuses for these points I can easily paint circles for them. What I need is an algorithm that only paints the envelope (right word for what I am looking for?) or outer bound of these combined circles. Additionally a second set of circles can 'encroach' on these circles, resulting in a kind of 'border'.
Image of what I am looking for
A quick way to draw the outline of the union of the disks is to
fill all disks in yellow, then
fill all disks in white with a smaller radius.
This can be adapted to the "encroached" circles, provided you only fill the remaining portions of the disks. Unfortunately, in a general setting finding the remaining portions can be an uneasy geometric problem.
There is an alternative approach which can work in all cases:
fill an image with zeroes, then for all disks fill every pixel with the value of the distance to the circumference (maximum at the center), but only keep the highest value so far.
while you do this, fill a second image with the color of the disk that achieved that highest value. (Initialize the image with the background color.)
At the end of this process, the first image will represent a "terrain" made of intersecting cones; and for every point of the terrain, you will know the color.
finally, color the pixels that have a height smaller than the desired stroke width, using the color map.
You can do the drawing in two steps.
1) Draw the outline using the following method: For each point, draw a circle using your favorite circle-drawing method, but before drawing a pixel, ensure that it is not contained inside any other circle. Do this for every point and you will get your outline.
2) Draw the borders between different sets using the following method: For each pair of points from different sets, calculate the two intersection points of the circles. If there is an intersection, the border can be drawn as a segment joining these two points. However, you have to make two lines, one for circle A, and another for circle B. To draw the line for circle A, slightly offset the segment towards point A. Then, use your favorite line-drawing method, but before drawing a pixel, ensure that it is closer to point A that any other point of the opposite set. After drawing the line, repeat the process for circle B. Note that both segment are not guaranteed to be the same length since the asymmetry of the points of the different sets. It will, however, always form a closed shape when all outlines and borders are drawn.
Let's say I have a polygon specified by a set of vertices.
In addition, I also have a defined "starting point" that could be anywhere in the polygon.
How could I find the largest square, centered at the starting point, that fits completely within the polygon?
How about finding the largest x,y aligned distances from vertices to the start point?
If you also consider the sign of the distance you get the maximun +x,-x size and +y,-y size
The size of the square is limited by either one of its sides hitting a vertex of the polygon or one of its corners hitting a side of the polygon.
If rotation is not allowed,
find the shortest horizontal or vertical distance from the target point to the vertices;
find the closest intersections of the main bissectors through the target point and the polygon outline.
Keep the smallest square so defined.
If rotation is allowed, the problem is more difficult.
Does anyone know how to draw a circular, minor arc given the centre point and two other points that lie on the circle?
I want to draw the pixels directly to the screen, and preferably, not have to calculate the angles.
I am using SDL and C, but may be OK studying code given that uses a different language.
Thanks.
All points on a circle are equal distance to the centre.
Given you know two points on the circle you can calculate this distance.
Assuming you have cartesian coordinates, for every x or y value between the known points calculate the other value so that the point is equal distance to the centre and plot these points.
I think this is conceptually the easiest way, though not the most efficient.