How to separate n-sided polygons in Scratch - spacing

https://scratch.mit.edu/projects/123719143/#player
I have written a simple Scratch exercise for my son that draws an array of n-sided polygons, but I want the spacing to be consistent, regardless of the number of sides chosen. It's not bad as it is, though I feel that the line where I calculate the apothem is overcomplicated and ugly (the 0.35 was reached through experimentation):
set apothem to sides * 0.35 * length / cos of 180 / sides
where sides is the number of sides for the poly and length is the side length.
The equation line was lifted and modified from a different script, not originally written by me otherwise I'd better know how to parse it.
I'd appreciate a way to make it more elegant :)
B

Related

How can you measure the length of curved grid lines on an image?

Suppose you have an image like this:
How can you measure the combined length of all the lines in this image?
I have tried (naively) skeletonising the image and then counting the number of pixels. However, this gives inaccurate results, as diagonal steps are actually longer than vertical/horizontal ones.
My other idea is to generate a chain code for all the line segments , and then use something like Freeman's method to measure the length from the chain code. However, generating the chain code is going to be quite tricky I think, as usually they start/stop at the same point, and this won't work for the grid shape.
Am I missing something obvious here? Is there an easier way to do this?
As far as I can see, the strokes are 3 pixels wide. So dividing the number of black pixels by three isn't a too bad approximation.
Alternatively, use a thinning algorithm to reduce the width to a single pixel (connexity 8), then seed-fill the whole outline. You will use a simple recursive 8-ways fill, and count the lateral and diagonal moves separately. In the end the length is given by L + D√2.

Finding All Pixels Within Certain Range in Polar Coordinates

I want to find all pixels in an image (in Cartesian coordinates) which lie within certain polar range, r_min r_max theta_min and theta_max. So in other words I have some annular section defined with the parameters mentioned above and I want to find integer x,y coordinates of the pixels which lie within it. The brute force solution comes to mid offcourse (going through all the pixels of the image and checking if it is within it) but I am wondering if there is some more efficient solution to it.
Thanks
In the brute force solution, you can first determine the tight bounding box of the area, by computing the four vertexes and including the four cardinal extreme points as needed. Then for every pixel, you will have to evaluate two circles (quadratic expressions) and two straight lines (linear expressions). By doing the computation incrementally (X => X+1) the number of operations drops to about nothing.
Inside a circle
f(X,Y) = X²+Y²-2XXc-2YYc+Xc²+Yc²-R² <= 0
Incrementally,
f(X+1,Y) = f(X,Y)+2X+1-2Xc <= 0
If you really want to avoid that overhead, you will resort to scanline conversion techniques. First think of filling a slanted rectangle. Drawing two horizontal lines by the intermediate vertices, you decompose the rectangle in two triangles and a parallelogram. Then for any scanline that crosses one of these shapes, you know beforehand what pair of sides you will intersect. From there, you know what portion of the scanline you need to fill.
You can generalize to any shape, in particular your circle segment. Be prepared to a relatively subtle case analysis, but finding the intersections themselves isn't so hard. It may help to split the domain with a vertical through the center so that any horizontal always meets the outline twice, never four times.
We'll assume the center of the section is at 0,0 for simplicity. If not, it's easy to change by offsetting all the coordinates.
For each possible y coordinate from r_max to -r_max, find the x coordinates of the circle of both radii: -sqrt(r*r-y*y) and sqrt(r*r-y*y). For every point that is inside the r_max circle and outside the r_min circle, it might be part of the section and will need further testing.
Now do the same x coordinate calculations, but this time with the line segments described by the angles. You'll need some conditional logic to determine which side of the line is inside and which is outside, and whether it affects the upper or lower part of the section.

Compute a fine-grained list of points on a UIBezierCurve [duplicate]

This question already has answers here:
Equidistant points across Bezier curves
(3 answers)
How to create several UIButtons along a path/BezierCurve?
(2 answers)
Closed 8 years ago.
So I've encountered a rather interesting, and likely highly math related problem to do with apple's implementation of the Bezier Curve.
So to cut to the chase, I've got a UIBezierCurve. I've plotted 3 points to generate an curve. A left point, the control point and the right point. Here is an example:
UIBezierPath *bezierCurve = [UIBezierPath bezierPath];
[bezierCurve moveToPoint:leftCorner];
[bezierCurve addQuadCurveToPoint:rightCorner controlPoint:controlPoint];
Where leftCorner, rightCorner and controlPoint are all CGPoints. Its pretty much an upside down parabola (with the values I am using usually, although this likely doesn't matter, its a parabola in some fashion that would pass the vertical line test). Like this: https://www.wolframalpha.com/input/?i=graph+of+y+%3D+-x%5E2
Now what I want to do is gather a list of points along this bezierCurve. Not just the 3 points I used to create it. For example, I would like to have, lets say a fine-grained list of probably hundreds of points along the curve that are all evenly spaced.
How I approached solving this: Hill-climb algorithm. My implementation of it was basically to start at the left of the curve (left corner) and walk along the curve until I got to the right corner. While walking 1 unit to the right each time I would try to hug the curve using:
- (BOOL)containsPoint:(CGPoint)point
This worked reasonably well, I got a list of a few hundred points along the curve. The problem however is they are certainly not equally spaced (equidistant is likely the term I am looking for here). Where the slope of the curve is relatively flat I get many points, and they are reasonably evenly spaced. When the slope is large however I get very few points compared to the length of the line in those areas. Sometimes only a point or two in very steep areas (when there should be many).
How I think I should solve this problem is to go with my hill climb algorithm (doing a pass horizontally, by walking along the x-axis hugging the curve) and add a second pass vertically (walking along the y-axis, hugging the curve). And then merge those 2 sets of points by sorting by x-value, and then within each x-value I sort by y-value.
However I am thinking there must be an easier, trivial way to do this. On Android all you have to do on the similar class to UIBezierCurve (android's "Path" class) is:
for (int i = 0; i < pathMeasure.getLength(); i++)
{
float[] point = new float[2];
float[] tangent = new float[2];
boolean success = pathMeasure.getPosTan(i, point, tangent);
if (success)
{
curvePoints.add(new Point((int)point[0], (int)point[1]));
}
}
In the end of that I basically have a list of points (curvePoints) that are all equidistant. PathMeasure is the class that works on android's Path (they are both built-in Android classes). I was hoping there was something similar to PathMeasure to easily get a list of equidistant points (of fine-grained granularity) on a UIBezierCurve and to avoid having to get heavy into the math of doing this all by hand. Is there something I'm missing?
Thanks!

how to calculate number of point between three points for curve drawing?

i have three points in 2D and I want to draw a spline curve passing through them. How do I calculate the middle point (x1 and y1 as in quadTo)? i want to implement free curve like denon eq curve
For the first segment of the curve, you can probably use addQuadCurveToPoint, picking a control point with the same y value as the second point (and I picked an x value half way between the two end points):
For the second portion of the curve, you can't use quad curve, because you need two control points (or, you'd have to break it up into two quad curves, which is more hassle than its worth, IMHO). So use addCurveToPoint, using control point y values that are the same value as the y value of the point to which the control point refers (and, again, I picked x values half way between the x values of the two end points):
There are lots of permutations of this idea, but I hope this illustrates the concept. I'd suggest you start playing around with UIBezierPath and addCurveToPoint until you achieve the desired effect.

Math/OpenGL ES: Draw 3D bezier curve of varying width

I've been working on a problem for several weeks and have reached a point that I'd like to make sure I'm not overcomplicating my approach. This is being done in OpenGL ES 2.0 on iOS, but the principles are universal, so I don't mind the answers being purely mathematical in form. Here's the rundown.
I have 2 points in 3D space along with a control point that I am using to produce a bezier curve with the following equation:
B(t) = (1 - t)2P0 + 2(1 - t)tP1 + t2P2
The start/end points are being positioned at dynamic coordinates on a fairly large sphere, so x/y/z varies greatly, making a static solution not so practical. I'm currently rendering the points using GL_LINE_STRIP. The next step is to render the curve using GL_TRIANGLE_STRIP and control the width relative to height.
According to this quick discussion, a good way to solve my problem would be to find points that are parallel to the curve along both sides taking account the direction of it. I'd like to create 3 curves in total, pass in the indices to create a bezier curve of varying width, and then draw it.
There's also talk of interpolation and using a Loop-Blinn technique that seem to solve the specific problems of their respective questions. I believe that the solutions, however, might be too complex for what I'm going after. I'm also not interested bringing textures into the mix. I prefer that the triangles are just drawn using the colors I'll calculate later on in my shaders.
So, before I go into more reading on Trilinear Interpolation, Catmull-Rom splines, the Loop-Blinn paper, or explore sampling further, I'd like to make sure what direction is most likely to be the best bet. I think I can say the problem in its most basic form is to take a point in 3D space and find two parallel points along side it that take into account the direction the next point will be plotted.
Thank you for your time and if I can provide anything further, let me know and I'll do my best to add it.
This answer does not (as far as I see) favor one of the methods you mentioned in your question, but is what I would do in this situation.
I would calculate the normalized normal (or binormal) of the curve. Let's say I take the normalized normal and have it as a function of t (N(t)). With this I would write a helper function to calculate the offset point P:
P(t, o) = B(t) + o * N(t)
Where o means the signed offset of the curve in normal direction.
Given this function one would simply calculate the points to the left and right of the curve by:
Points = [P(t, -w), P(t, w), P(t + s, -w), P(t + s, w)]
Where w is the width of the curve you want to achieve.
Then connect these points via two triangles.
For use in a triangle strip this would mean the indices:
0 1 2 3
Edit
To do some work with the curve one would generally calculate the Frenet frame.
This is a set of 3 vectors (Tangent, Normal, Binormal) that gives the orientation in a curve at a given parameter value (t).
The Frenet frame is given by:
unit tangent = B'(t) / || B'(t) ||
unit binormal = (B'(t) x B''(t)) / || B'(t) x B''(t) ||
unit normal = unit binormal x unit tangent
In this example x denotes the cross product of two vectors and || v || means the length (or norm) of the enclosed vector v.
As you can see you need the first (B'(t)) and the second (B''(t)) derivative of the curve.

Resources