Does anybody knows an algorithm for drawing an ellipse with thickness?
I googled, but I found only algorithms that draws an 1 pixel width ellipse, like this:
http://homepage.smc.edu/kennedy_john/belipse.pdf
Thanks.
By an ellipse with thickness do you mean the difference between two ellipses, one where the two axes have been lengthened by 1/2-thickness and the other where they have been shortened by 1/2-thickness?
If so, then you can adapt the linked algorithm into a scanline fill algorithm. One thing you want to do is work only along the shorter axis. (working along the longer axis works too, but involves redundant computation).
Let's say it's wider than it is tall. (If it's the other way around you just flip axes when drawing.) In that case you'll be drawing one or two horizontal line segments for each y position.
For each value of y from the top of the outer ellipse to the center of the ellipses:
If y is above inner ellipse:
Draw one horizontal line segment from the upper left quadrant point on the outer ellipse to the upper right quadrant point on the outer ellipse.
Else (y is not above inner ellipse):
Draw two horizontal line segments:
One from the upper left quadrant point of the outer ellipse to the upper left quadrant point of the inner ellipse.
Another from the upper right quadrant point of the inner ellipse to the upper right quadrant point of the outer ellipse.
Either way, mirror all drawing over the x-axis of the ellipses to
render the bottom two quadrants.
how accurate do you need to be?
do you want the real ellipse point in the approximate center of the 'x' pixel width border? have the real elipse point be the inside edge? outside edge?
I ask b/c the gentleman's algorithm you found strives to stick with integer math where possible, so I'll append to his algorithm with integer work as well.
inside edge: alter the Plot4EllipsePoints sub routine to paint x pixels instead of one, where the new x pixels are further away from the ellipse center. 2 pixel eg:
procedure Plot4EllipsePoints(X,Y : longint);
begin
PutPixel(CX+X, CY+Y); {point in quadrant 1}
PutPixel(CX+X+1, CY+Y+1); {point in quadrant 1}
PutPixel(CX-X, CY+Y); {point in quadrant 2}
PutPixel(CX-X-1, CY+Y+1); {point in quadrant 2}
PutPixel(CX-X, CY-Y); {point in quadrant 3}
PutPixel(CX-X-1, CY-Y-1); {point in quadrant 3}
PutPixel(CX+X, CY-Y) {point in quadrant 4}
PutPixel(CX+X+1, CY-Y-1) {point in quadrant 4}
end;
taken from :http://homepage.smc.edu/kennedy_john/belipse.pdf
outside edge: same as inside edge, but closer to the ellipse center.
centered: perform the inside edge +
outside edge both. This will only have odd thicknesses, 1 pix, 3 pix, 5 pix.
Let E1 be an ellipse of radius r + thickness / 2 and E2 an ellipse of radius r - thickness / 2.
Adapt the Scanline Fill Algorithm to fill E1 without filling E2.
Related
Given a 2D grid of square cells of the form grid[x,y], I would like an algorithm that produces an ordered set of points that form the perimeter of the shape. In other words, the algorithm would produce a perimeter route around the corners of the shape as shown in this image:
.
I have looked at posts like this (where I got the above image), and I can find the corners of the shape. I have two questions: 1) once I have found the corners of the shape, how would I iterate over them in order to find a correct (and valid) route? 2) Would such a method to find the route consistently produce clockwise/counterclockwise routes? It does not matter to me that order of the vertices is clockwise/counterclockwise, only that they are consistently either clockwise or counterclockwise.
Thanks for any help
This assumes that any single corner won't be visited more than once per circuit. in other words, no corners where there are two grey and two black with the two grey squares in non adjacent corners.
Get your corners in some data structures that let you quickly :
get a list of all corners with a given x coordinate ordered by y coordinate.
get a list of all corners with a given y coordinate ordered by x coordinate.
Here's the algorithm:
Start with arbitrary corner c.
We'll say it has 3 adjacent black squares and 1 grey, and that the
1 grey square is in the -x,+y direction.
Choose perimeter direction. We'll say clockwise.
Determine which direction the perimeter goes in that corner. This can be done
by looking at the direction of the adjacent tile there's only 1 color of.
In our example, the perimeter goes -x/+y
Determine if c is concave or convex.
Convex has 3 adjacent black squares, concave has 3 adjacent grey squares.
In our example, c is convex because it has 3 adjacent black squares.
Knowing the direction of the perimeter from that corner and if it's concave or
not tells us what direction is clockwise:
clockwise at convex +x/-y is +x,
clockwise at convex +x/+y is +y,
clockwise at convex -x/-y is -y,
clockwise at convex -x/+y is -x
If it is concave clockwise goes the other direction.
(obviously if the desired perimeter direction is counterclockwise, it's the opposite)
Because c in our example is a convex corner and it goes -x/+y,
that means clockwise is along the x wall, so set current_axis = x,
It goes negative in that direction so set current_direction = -1
Otherwise, it would be set to 1
create list ordered_corner_list that only contains c
While length of ordered_corner_list < number of corners:
Get list of all corners with same value of current_axis as c ordered by the other axis.
e.g. for the first iteration, get same x value as c ordered by y
if current_direction = -1:
find node with the next lowest ordered value from c.
e.g. for the first iter, get corner with next lowest x from c
else:
find node with the next highest ordered value from c
assign that node to c
append c to ordered_corner_list
set current_axis = the other axis
e.g. for the first iteration, current_axis = y here
set current_direction to the direction that corner goes in the current_axis
For an ellipsoid of the form
with orientation vector and centre at point , how to find whether a point is inside the ellipsoid or not?
An additional note that the geometry actually is with a=b (spheroid) and therefore one axis is sufficient to define orientation
Note: I see a similar question asked in the forum. But, it is about an ellipsoid at origin and without any arbitrary orientation and here both arbitrary position and orientation are considered.
Find affine transform M that translates this ellipse in axis-oriented one (translation by -p and rotation to align orientation vector r and proper coordinate axis).
Then apply this transform to point p and check that p' lies inside axis-oriented ellipsoid, i.e.
x^2/a^2+ y^2/b^2+z^2/c^2 <= 1
Create a coordinate system E with the center at p and with the long axis of the ellipse aligned with r. Create a matrix that can transform global coordinates to the coordinate system E. Then put the transformed coordinates into the ellipse equation.
A center point p and an "orientation vector" r do not suffice to completely specify the position of the ellipsoid, there is one degree of freedom left. Your problem is indeterminate.
If your vector r is a unit vector from the origin to the pole, then the test for whether a point q is in (or on) the ellipse is:
v = q-p; // 3d vector difference
dot = v.r; // 3d dot product
f = dot*dot;
g = v.v - f; // 3d dot product and scalar subtraction
return f/(b*b) + g/(a*a) <= 1
Note that if the ellipse was aligned so that r was the z unit vector, then the test above translates into the usual test for inclusion of a point in an ellipse.
I would like to check the intersection of two squares which are not axis-aligned. I know how to do it for axis-aligned squares. Can I extend the same idea?
Basically I want to distribute squares by gaussian distribution on the x-y plane in +ve quadrant say, but two squares should not be intersecting so I have to shift the original center of the square. Suggestions are welcome.
Separating axis theorem (link2) is suitable for effective checking of convex polygon intersection. For squares prerequisite (normals and so on) calculation becomes especially simple.
After almost 4-5 hours of thinking, I got one click. Just sharing if anyone needs this. PseudoCode
Input: Square1 and Square2
Bool(Sqaure1,square2)
for vertex v0 to v3 of sqaure 1
angle = 0;
for vertex P0 to P3 of square 2 (In anticlockwise of clockwise way)
angle = angle + angle(Pj,vi,P((j+1)%4));
if(abs(angle-360) == 0)
return true;
return false;
IDEA: point of one square inside or on the line of another square will have angle sum of 360 with all points if two squares intersects.So you can call function twice by swapping arguments and if anyone returns true then answer is yes.(Call twice or check if angle sum is 0 or 360 exactly)
If I am right, you can proceed as follows:
rotate both Sa and Sb so that Sa becomes axis-aligned;
check overlap of Sa' with the bounding box of Sb';
rotate both Sa and Sb so that Sb becomes axis-aligned;
check overlap of the bounding box of Sa" with Sb".
If there is a configuration with no overlap, then the squares are disjoint.
In analytical terms, the no-overlap conditions will have a form like
C1 + C2 (|cos(t1+t2)| + |sin(t1+t2)|) < 2D Min(|cos(t1)|, (|sin(t1)|)
where C1, C2 are the sides, D the distance between centers and t1, t2 are the angles between sides and the center line, and similar by exchange of 1/2.
I have a grid which is 100 by 100, and I have a circle. I want the circle to put a value in every cell that the circle covers. Is there a good algorithm for this ? I will be using as3 but I don't think that would be a issue.
edit.
I'm trying to find a algorithm which will return all cells within the circle and all cells which are semi in the circle / mostly in the circle (Greater than 50%). As I haven't found algorithm which does this I cannot show any code.
I know this is an old question but might be useful for anyone (like me) looking for an answer here.
The (pseudocode) approach I took was to work out a bounding box around the circle of centre a,b radius r using two opposite corners:
topLeft = (x:a - r, y:b + r)
bottomRight: (x:a + r, y:b - r)
Then iterate over all squares within the bounding box and test if they are in the circle
for(x between topLeft.x and bottomRight.x){
for(y between topLeft.y and bottomRight.y){
if((x-a)^2 + (y-b)^2 < r^2){
// point is in circle
}
}
}
Start at the centre of the circle. Mark that grid square. Now construct a spiral starting from that square, checking each grid square along the spiral and marking as appropriate. There will be some formula for how long each new turn of the spiral will be. When a full turn of the spiral is outside the circle you do not need to check any more grid squares.
I have 100 similar shapes (simple vector graphics). How can i find the "average/merged" shape of all 100 instances?
Thank,
you
Algorithm Proposal
Compute the area of each shape {A}.
Find the shape {S} with most points {N} (you're going to end up with a N side polygon)
Merge {S} with another shape and create the first merged {M} shape. Then merge {M} with each other shape remaining. {M} will be dynamic/rewritten/will change every time it's merged with another shape.
Merge function: pseudocode
Call Merge({S}, {S2}) first, then call Merge({M}, {S2}) for the rest of the shapes.
Parameters:
{S1}=the shape with most points;
{S2}=shape to merge with;
function Merge({S1}, {S2}):
FOR EACH {point} of {S1} DO
{near}=find nearest {S2}{point}
{size}=( SQRT({S1}{A}) + SQRT({S2}{A}) )/2
{line}=create line starting at {near}, going to/over {point} of length {size}
add point in {M} with position at half the {line}
END FOR
RETURN {M}
;
3 initial shapes: rectangle, triangle, 7 side polygon {S}=green
merged green with rectangle {M}=blue
merged blue with triangle {M}=yellow <-final result
Notice: merged shapes not on scale! didn't account for areas!