Number of dashes per circle the same - SVG - svg

Let me start out by saying my end goal is something that resembles the image below. It has 36 circles in each of the rings, spaced such that each dot is mid way between two dots in the circle inside of it
I figured out I could use a stroke-dasharray with really small lengths (.001 in my case) and stroke-linecap="round" to make the borders circular dots. The way I have it set up now each circle has a radius 5 bigger than the last and an incremented percentage for the stroke-dasharray. Here is my jsFiddle. Currently My inner most ring only has 21 dots and my outermost ring has 29 dots
How can I get the same number of dots per circle? Is there a mathematical way to do this or an attribute that I am unaware of? What can be done to evenly space out the circles using the whole circumference equally (instead of having some on the right side of the what I perceive as the x-axis)?
It seems to me that I would have to simply guess and check with the values in order to get it the way I want but I would love to be proven wrong. The stroke-dasharray documentation on Mozilla and W3C aren't very useful

Since you're using stroke-dasharray on a circle, you need to use π (3.14159265) to get even spacing.
Given the formula spacing = (radius × 2) × 3.14159265 ÷ numberOfCircles, your SVG circle would be <circle r="{radius}" stroke-dasharray="0.001, {spacing}"/>.
To achieve the spiral effect, apply a rotation of 360 ÷ numberOfCircles ÷ 2 to every other ring. I used CSS to accomplish this, circle:nth-child(even) being the selector and -webkit-transform: rotate( {rotation} ); being the style applied.
I forked your JSFiddle1.
1 Note that the spiral is visible in webkit browsers only. Also, the rings are slightly misaligned on the right for, to my knowledge, unknown reasons.

Related

SVG arc slips away as it completes it's arc

http://codepen.io/andrewplummer/pen/pyjjbJ
I'm trying to make a simple arc for a graph. I've read up on "A a" arc in SVG and I believe I understand the specifics, but when the arc approaches its origin point it starts slipping to the right and I can't figure out why.
The main problems seems to be here: <path d="M75 5 A70 70 0 1 1 71 6" stroke="#3f51b5"></path>. As the closing point (71 76) approaches the origin (75 5) the arc starts to shift to the right. The pen shows more details... All browsers show this behavior so it doesn't seem to be a bug.
If you need accuracy, then don't try to draw a complete 360deg arc with one path arc command. Because you don't specify the centre point when describing arcs, tiny mathematical inaccuracies between the combination of start point, end point and radiuses can cause the arc to shift around by quite a surprising amount.
I would suggest keeping your arcs to a maximum of 180 degrees. For large radiuses you may want to go even lower, and limit it to 90 degrees.
As it turns out, it's the call to Math.ceil that was causing this issue. It appears that even small changes in the final x/y position (the last 2 arguments to the svg A command) can have big effects on the resulting arc. When drawing larger arcs these smaller differences can have more exaggerated effects, so #Paul LeBeau's answer is somewhat correct. However, simply not rounding fixed the issue and renders perfectly so it seems that one arc will in fact do the trick, just don't round (rounding pixel values is kind of a force of habit for older devs used to crappy browsers).
The arc command has two flags, the attached image should explain it.
Are you trying to draw a complete circle ?

How to draw shapes in the proper order when rendering?

I am trying my hand at writing a 3d graphics engine, but I am having some trouble with drawing the shapes in the correct order.
When I translate the points of triangles into window space, i.e. the 2-dimensional space that directly correlates to position on the screen, in addition to an x and y position of each point, I also assign them a depth variable that stores how far away from the viewer that point was in 3d space.
At the moment, the only shapes I am rendering are triangles. My current render order algorithm sorts the triangles by the average depth of their 3 points. I knew when I started it that it would not be perfect, but I wanted a placeholder for testing.
For testing purposes, I constructed a square box with an open top, each side being a different color and made from 2 triangles, as shown below:
As you can see from the image above, the algorithm I am using works most of the time. However, at certain angles and positions, the triangles will be rendered in the wrong order, as show below:
As you can see, one of the cyan triangles on the bottom of the box is being drawn before one of the yellow triangles on the side. Clearly, sorting the triangles by the average depth of their points is not satisfactory.
Is there a better method of ordering shapes so that they are rendered in the correct order?
The standard method to draw 3D in correct depth order is to use a Z-buffer.
Basically, the idea is that for each pixel you set in the color buffer, you also set it's interpolated depth in the z (depth..) buffer. Whenever you're about to paint the next pixel, you first check that z-buffer to validate the new pixel if in front of the already painted pixel.
On top of that you can add various sorts of optimizations, such as sorting triangles in order to minimize the number of times you actually paint the color buffer.
On the other hand, it's sometimes required to do the exact opposite in order to properly handle transparency or other "advanced" effects.

Avoiding lines between adjecent svg rectangles

Although there's some standardized options for hinting the browser about anti-aliasing in svg, none of them seems to work for my case where I have rectangles with rounded corners - and therefore can't afford turning off anti-aliasing.
Although my rectangles are sized to leave no vertical spaces between them, a thin line shows between them, due to the effects of anti-aliasing. E.g. my svg has one rectangle end at pixel 80 and the next one starts at 81, but still they get a thin background line show between them.
There's no way to force latest version browsers to avoid anti-aliasing for straight lines (crispEdges doesn't force that for my rounded rectangles).
I read some about tweaking by adding 0.5 of a pixel to the y values and about tweaking only even or only odd y values (I believe this is related to the fact that most contemporary LCD screens comprise two hardware vertical pixels per software exposed pixel). I am unsure how precisely this mitigates the problem, and would like to get a definite account of why exactly this makes sense and what is the most correct/solid tweaking approach.
two hardware vertical pixels per software exposed pixel
No that's wrong.
When you specify a coordinate like "81" in an SVG, that coordinate falls on the imaginary line between pixel 80 and 81. If your line has width "1", then the renderer will attempt to draw that by placing 50% of the colour on the 80 pixel and 50% on the 81 pixel. This is anti-aliasing. If you want the one pixel line to not be anti-aliased like that, give it coordinate 81.5. That way the whole line will fall within pixel 81.
However if your line had width 2 (or any other even width) you should not use 81.5 but stay with 81. Because it will render 50% (ie. 1) in pixel 80 and 50% (1) in pixel 81. Resulting in no anti-aliasing effect.
This applies for both horizontal and vertical lines. And applies whether you are on an LCD or old CRT.
Does this explanation make sense now?

Smoothing overlapping stroke edges

I'm using Raphael to draw the arcs as shown in the image below:
Z-index order is from lowest to highest: gray, blue, green.
Both the gray and the blue arcs start from the top, where the green one starts.
Is there any way to improve the edges? Especially the green over blue one.
Thank you.
I'm afraid there's not much you can do. How the shape is rendered depends on the viewer (browser, image viewer or importing application). You could play with the rendering properties and see if this gives you an improvement, but I believe hardly any SVG implementation supports them.
I am not sure exactly what you mean, and it is hard to know how you made the image without the raphael code. Are you talking about the way the outer edge of the green arc extends slightly beyond the outer edge of the blue arc? I would check that the corner points of the two paths are the same, and include the stroke-width in your calculations of the paths.
Perhaps you could try reducing the stroke-width to 0 to make things easier.
The problem is that you are overlapping the shapes. This causes some colors to spill out from underneath. To solve this you need to start each arc where the previous one ends.
You might get very faint gaps, this can easily solved by applying a 1px stroke to each arc.

Manipulate/creation of SVGs relative to their center

I would like to identify the center of an SVG, so that I can manipulate multiple SVGs with ease.
I am trying to make multiple examples of the basic polygons (3 to 8 sides), and quickly realized that I either hade to make my own, which involves a lot of math, or I could pull from wikipedia the current ones. The problem with the former is that it takes a lot of time to translate the coordinates from Sketchup. The problem with the latter is that they are oriented differently and of different size.
I know that you can transform, scale, and rotate the SVG, but I need to know the coordinates of the center of the SVG. How do I find this out, so I can set universal manipulations?
Take the transform="rotate(degrees x y)", I need to know the center to accomplish this.
JS Fiddle
Here, I would like to set all the centers to the same, and then scale them to the same height and width, and potentially rotate them individually so that they all have a flat bottom, not a vertex.
The generic answer to your question isn't obvious...
It might be simpler for polygons, particularly convex polygons: you can iterate on the path and find its bounding box by computing the max and min of the x and y coordinates of each point of the path.
Then you can decide that the center of the shape is the center of the of the bounding box.
An alternative is to put an invisible element at what you estimate to be the center (for complex shapes, the concept of "center" can be variable), and get its coordinates to find out where the center is. Particularly for rotating purpose: you might want to do this rotation around a specific point which might not be the geometrical center.

Resources