Finding pixels inside an ellipse - graphics

My maths skills are terrible so I don't even know where to start with this. This is for a hobby project written in C#.
To keep things simple, let's say I need to operate on all of the pixels positioned inside an ellipse. How would I get an array of the valid pixel locations inside the ellipse that I need to work with?

For that task i would recommend taking a look at bresenhams filled circle Algorithm.
If you scale the y achsis you can use it to draw ellipses, too.
Bresenham algorithms work by using only integer arithmetic, which makes them fast(est)
This works only for axe-parallel ellipses

In an ellipse the sum of the distance between a point in the ellipse and both foci is twice the major axis so:
PF1 + PF2 = 2a
Where P is the point, F1 and F2 the foci and a the semi major axis.
If the sum is less then 2a the point will be inside the ellispe.
Wikipedia

Related

Circle triangulation

I am currently experimenting with openGL, and I'm drawing a lot of circles that I have to break down to triangles (triangulate a circle).
I've been calculating the vertices of the triangles by having an angle that is incremented, and using cos() and sin() to get the x and y values for one vertex.
I searched a bit on the internet about the best and most efficient way of doing this, and even though there's not much information avaliable realized that thin and long triangles (my approach) are not very good. A better approach would be to start with an equilateral triangle and then repeatedly add triangles that cover the larges possible area that's not yet covered.
left - my method; right - new method
I am wondering if this is the most efficient way of doing this, and if yes, how would that be implemented in actual code.
The website where I found the method: link
both triangulations has their pros and cons
The Triangle FAN has equal sized triangles which sometimes looks better with textures (and other interpolated stuff) and the code to generate is simple for loop with parametric circle equation.
The increasing detail mesh has less triangles and can easily support LOD which might be faster. However number of points is not arbitrary (3,6,12,24,48,...). The code is slightly more complicated you could:
start with equilateral triangle remembering circumference edges
so add triangle (p0,p1,p2) to mesh and edges (p0,p1),(p1,p2),(p2,p0) to circumference.
for each edge (p0,p1) of circumference
compute:
p2 = 0.5*(p0+p1); // mid point
p2 = r*p2/|p2|; // normalize it to circle circumference assuming (0,0) is center
add triangle (p0,p1,p2) to mesh and replace p0,p1 edge with (p0,p2),(p2,p1) edges
note that r/|p2| will be the same for all edges in current detail level so no need to compute expensive |p2| over and over again.
goto #2 until you have enough dense triangulation
so 2 for loops and few dynamic lists (points,triangles,circumference_edges,and some temps if not doing this inplace). Also this method does not need goniometrics at all (can be modified to generate the triangle fan too).
Here similar stuff:
sphere triangulation using similar technique

Divide area into subareas based on circles of point cloud

I have a rectangle R of side lenghts lx (horizontal) and lz (vertical) and area of A = lx*lz. In this rectangle, there are N randomly distributed points. I would like to split A into N sub-areas, where each sub-area is determined based on circles of growing radius around each point of the point cloud. As soon as two growing circles intersect, the resulting radical line should demark the local border between the sub-areas of two points. The borders of rectangle R should additionally delimit the sub-areas.
The expected result is sketched in this Figure:
Expected sub-areas in an example with 6 points
The approximate procedure is artistically illustrated in this short Youtube movie:
https://www.youtube.com/watch?v=BXNvcQTNWXM&ab_channel=stopmotionkim
To find the sub-areas, I am looking for an approximate or exact algorithm that (first priority) is efficient and scales well with N (better than O[N^2], ideally O[N], although I doubt that this is possible), and (second priority), if approximate, is as accurate as possible.
Does anybody know how to do this or has a hint how one could start? Thanks a lot for your help!
What you are looking for is Clipped Voronoi Diagram. It can be calculated in O(nlogn). I suggest you to look at those papers/courses to have a better idea of the underlying theory and computational methods:
Efficient Computation of 3D Clipped Voronoi Diagram
Computational Geometry
For a Python implementation, see this post

How to describe fat curve (curved line of variable thickness)?

I know how to describe curved line of constant thickness (with Bezier or similar models).
Are there any common models of curved line with variable thickness?
I am imagining some similar things like in Bezier. For example, each node can contain thickness value and it's weight, so renderer would interpolate thickness along curve.
Is there some implementations and/or descriptions?
UPDATE
More precisely the question is follows.
Suppose we have cubic Bezier segment, controlled by 4 points ABCD
In Bezier, the longer we have vector, say AB, then the longer curve follows AB direction. On the picture above, we have raltively long following.
So, I want thikness behave synchronously with control nodes B and C. If AB and CD is long, then thinkness should follow end nodes thinkness long and change to another thickness fast, like below
and if control vectors are short, then thinkness should smoothly change from one to another, like below
Metafont and its successor MetaPost
support variable thickness in the form of shaped pens.
See also
L.M. Mestetskii, Fat curves and representation of planar figures, Computers & Graphics, 24:1 (2000) 9-21 doi: 10.1016/S0097-8493(99)00133-8
If you want to use a "disc based" approach, you need to draw circles around every control point, then find the points on those circles that represent the "offset" (normal to the tangent, for on-curve points, normal to the tangent of the projection for off-curve points). You then plug those new points into the Bezier functions to get your "offset curve".
Curve offsetting, in your case with variable width, is essentially the trick of finding an outline rather than a single curve. For Bezier curves you can find a full explanation over at http://pomax.github.io/bezierinfo/#offsetting, with the variable width explanation over at http://pomax.github.io/bezierinfo/#offsetting (you're interested in the latter, but you need to understand the basics before you look at the special case =)

How to tell if two rings (circles in 3d) are linked

I have two rings in 3 space each represented by a normal vector, center coordinate, and a radius.
How can I determine if the rings are linked. I.e. a point on one circle lies in the other disk.
This will be implemented in a tight loop so I am concerned about performance. I feel like there should be a closed form solution. So far I've only thought iterative solutions.
Any help?
Outline of the algorithm:
Handle the cases where the planes of the circles are parallel or concurrent.
Find the line of intersection of the planes of the circles.
Find the intersections of the circles with this line.
All the circle intersections with the line are on both planes. We can now do distance checks to see if the circles are linked.
Details:
I'll assume that the circles C1 and C2 are given by a center point (p1, p2), unit normal axis vector (n1, n2) and radii (r1, r2).
If n1 == k n2 for some scalar k, then the planes are parallel or concurrent. If they're concurrent this becomes the trivial 2d problem: check whether dist(p1, p2) < r1+r2.
Otherwise, the planes intersect at a line L. If the circles are linked, then they must both intersect L since linking implies that they mutually pass through each other's plane of definition. This gives you your first trivial rejection test.
L is given by a point q and a vector v. Finding v is easy: It's just the cross product of n1 and n2. q is a little trickier, but we can choose a point of nearest approach of the lines
l1(s) = p1 + s (v X n1)
l2(t) = p2 + t (v X n2)
These lines are perpendicular to v, n1 and n2, and are on the planes of C1 and C2. Their points of nearest approach must be on L.
You can refer to this post to see how to find the points of nearest approach.
Finally, the only way the circles can intersect is if they both have points on L. If they do, then consider the intersection points of C1 and L as they relate to C2. The circles are linked if there are two intersection points q11 and q12 of C1 and L and exactly one of them are inside of C2. Since L is on the plane of C2, this becomes a planar point-in-circle test:
IF dist(p1, q11) < r1 THEN
linked = (dist(p1, q12) > r1)
ELSE
linked = (dist(p1, q11) < r1)
ENDIF
Of course this pseudo-code is a little sloppy about handling the case that the circles actually intersect, but how that should be handled depends on your application.
A straightforward solution that is relatively easy to code: compute the line of intersection of the two planes and rotate and translate everything (in my case the six points defining the two circles) together so that the line becomes the Z axis (x=y=0). Then the planes can be rotated separately around Z so that the first circle, C1, lies on the XZ plane and C2 lies on the YZ plane. Now the centers and radii are easy to find (in my situation I don't initially have them). These rotations do not change the link/no link property and the link or lack of it can be easily determined from the order of the four intersections of the circles with the Z axis. (If either of the circles does not intersect x=y=0, there is no link.) (I may have confused the axes but I think this will work.)
Thank you.
Is this the 3D circle-disk intersection problem? Or, is it the circle-circle intersection problem?
If it's the former, there is a fast, closed form algorithm. First, weed out the circles-too-distant case: dist(CIR1.c, CIR2.c) > CIR1.r + CIR2.r
Handle the edge case: coplanar circles.
Extrude the disk into its plane, then intersect the circle with this plane. If there are 1 or 2 intersection points, test to see if they meet pointInDisk(p, CIR) logic. Report out any surviving intersection points.
A computational geometry textbook might have a good solution!
But I don't have a computation geometry textbook handy at the moment. If I were going to roll my own right now, based on my own (very limited) intuition, I think I'd start with 3d axis-aligned bounding boxes.
e.g., create an "just inside the circle" bounding box, as well as a "just outside the circle" bounding box. I believe it's trivial to figure out if two axis-aligned boxes overlap (section 2.1 of a homework assignment I once did talks about a related problem in the 2D situation --- finding the nearest rectangle to a point: http://juliusdavies.ca/uvic/report.html ).
I suspect the following assertions would hold (but I could be wrong):
If the inner-boxes overlap, then the rings are definitely connected. (I now think this is wrong...)
If the outer-boxes DO NOT overlap, then they are definitely not connected --- I am very confident this assertion holds! :-) :-)
If the outer-boxes overlap, but the inner-boxes do not, then they might be connected.
That's where I'd start, if I were rolling my own.
Conclusion: uhhh, I hope you have better luck with the other answers. :-)

Algorithm for Polygon Image Fill

I want an efficient algorithm to fill polygon with an Image, I want to fill an Image into Trapezoid. currently I am doing it in two steps
1) First Perform StretchBlt on Image,
2) Perform Column by Column vertical StretchBlt,
Is there any better method to implement this? Is there any Generic and Fast algorithm which can fill any polygon?
Thanks,
Sunny
I can't help you with the distortion part, but filling polygons is pretty simple, especially if they are convex.
For each Y scan line have a table indexed by Y, containing a minX and maxX.
For each edge, run a DDA line-drawing algorithm, and use it to fill in the table entries.
For each Y line, now you have a minX and maxX, so you can just fill that segment of the scan line.
The hard part is a mental trick - do not think of coordinates as specifying pixels. Think of coordinates as lying between the pixels. In other words, if you have a rectangle going from point 0,0 to point 2,2, it should light up 4 pixels, not 9. Most problems with polygon-filling revolve around this issue.
ADDED: OK, it sounds like what you're really asking is how to stretch the image to a non-rectangular shape (but trapezoidal). I would do it in terms of parameters s and t, going from 0 to 1. In other words, a location in the original rectangle is (x + w0*s, y + h0*t). Then define a function such that s and t also map to positions in the trapezoid, such as ((x+t*a) + w0*s*(t-1) + w1*s*t, y + h1*t). This defines a coordinate mapping between the two shapes. Then just scan x and y, converting to s and t, and mapping points from one to the other. You probably want to have a little smoothing filter rather than a direct copy.
ADDED to try to give a better explanation:
I'm supposing both your rectangle and trapezoid have top and bottom edges parallel with the X axis. The lower-left corner of the rectangle is <x0,y0>, and the lower-left corner of the trapezoid is <x1,y1>. I assume the rectangle's width and height are <w,h>.
For the trapezoid, I assume it has height h1, and that it's lower width is w0, while it's upper width is w1. I assume it's left edge "slants" by a distance a, so that the position of its upper-left corner is <x1+a, y1+h1>. Now suppose you iterate <x,y> over the rectangle. At each point, compute s = (x-x0)/w, and t = (y-y0)/h, which are both in the range 0 to 1. (I'll let you figure out how to do that without using floating point.) Then convert that to a coordinate in the trapezoid, as xt = ((x1 + t*a) + s*(w0*(1-t) + w1*t)), and yt = y1 + h1*t. Then <xt,yt> is the point in the trapezoid corresponding to <x,y> in the rectangle. Now I'll let you figure out how to do the copying :-) Good luck.
P.S. And please don't forget - coordinates fall between pixels, not on them.
Would it be feasible to sidestep the problem and use OpenGL to do this for you? OpenGL can render to memory contexts and if you can take advantage of any hardware acceleration by doing this that'll completely dwarf any code tweaks you can make on the CPU (although on some older cards memory context rendering may not be able to take advantage of the hardware).
If you want to do this completely in software MESA may be an option.

Resources