drawing arc points - algorithm

Can someone provide me an algorithm to draw points on arc? I know the start-point, end-point and radius. I need to show points on the arc made by this information(start-point, end-point and radius).
See the image for more details
I have Start-Point (x,y), End-Point(a,b). I have to calculate equally distance 5 points on arc. Is it possible?

The standard algorithm for this is the Midpoint circle algorithm (sometimes called Breshenham's circle algorithm).
Note that your arc specification is incomplete. There are generally two arcs of the same radius joining two given points, one for the center on each side of the line joining the points. Also, as #In silico points out, the radius can be no smaller than half the distance between the points.

The means of specifying an arc is similar to that used in SVG, which has some detailed implementation notes which are too long to copy here. For circular arcs, the x and y radii are equal so the x axis angle is not important. As Ted Hopp noted, you need a flag to indicate which direction the arc is drawn in ( in SVG called large-arc-flag ).
Once you have the centre and angles of start and end of the arc, divide the angle into six and use the sin/cos of this angle to plot the five intermediate points.

Related

Separate circle and rectangle

In a 2d space there are a rectangle and a circle that overlap each other. How can
I calculate the smallest distance (depth) that I need to separate the circle and the rectangle?
I'll assume from the way you've described it if one shape entirely contains the other, that still counts as "overlapping"
The strategy to separate a circle from a rectangle while moving the circle the shortest distance is as follows:
Draw a line from the circle's centre to the nearest point on one of the rectangle's vertices
Pull the circle along this line until they are no longer overlapping
So to calculate the distance that it needs to be pulled, your formula will be:
pullDistance = radius - centreDistance
Where:
pullDistance is what you're trying to calculate
radius is the radius of the circle
centreDistance is the distance of the centre of the circle from the nearest point on the edge of the rectangle.
Two things to note:
If the centre of the circle is inside the rectangle, then centreDistance should be calculated the same way, but made negative
If the pullDistance is negative then the two shapes are already not overlapping, so the true distance is 0.
So since radius is known, all you have to do is calculate the centreDistance. The way to do this is to find the distance from the circle's centre point to each of the rectangle's four line segments and take the minimum. Finding the distance between a point and a line segment is a common task, I won't repeat how to do that here. This question has a lot of samples and information for how to do it.

Algorithm for bisecting a set of points using a circle of fixed radius

Suppose I have a set of points in the Cartesian plane, defined by an array/vector of (X,Y) coordinates. This set of points will be "contiguous" in the coordinate plane, if any set of discontinuous points can be contiguous. That is, these points originated as a rectangular grid in which regions of points were eliminated by a prior algorithm. The shape outlined by the points is arbitrary, but it will tend to have arcs for edges.
Suppose further that I can create circles of fixed radius r.
I would like an algorithm that will find me the center X,Y for a circle that will enclose as close to exactly half of the given points as possible.
OK, try this (sorry if I have very bad wording: I didn't learn my Maths in english)
Step 1: Find axis
For all pairs of points, that are less than 2r apart calculate how many points lie on either side of the connecting line
Chose the pair with the worst balance
Calculate the line, that bisects these two points as an axis ("Axis of biggest concavity")
Step 2: Find center
Start on the axis far (>2r) away on the side, that had the lower point count in step 1 (The concave side)
Move the center on the axis, until you reach the desired point. This can be done by moving up with a step of sqrt(delta), where delta is the smallest distance between 2 points in the set, if overreaching move back halfing the step, etc.
You might want to look into the algorithm for smallest enclosing circle of a point set.
A somewhat greedy algorithm would be to simply remove points 1 at a time until the circle radius is less or equal to r.

How to find collision center of two rectangles? Rects can be rotated

I've just implemented collision detection using SAT and this article as reference to my implementation. The detection is working as expected but I need to know where both rectangles are colliding.
I need to find the center of the intersection, the black point on the image above (but I don't have the intersection area neither). I've found some articles about this but they all involve avoiding the overlap or some kind of velocity, I don't need this.
The information I've about the rectangles are the four points that represents them, the upper right, upper left, lower right and lower left coordinates. I'm trying to find an algorithm that can give me the intersection of these points.
I just need to put a image on top of it. Like two cars crashed so I put an image on top of the collision center. Any ideas?
There is another way of doing this: finding the center of mass of the collision area by sampling points.
Create the following function:
bool IsPointInsideRectangle(Rectangle r, Point p);
Define a search rectangle as:
TopLeft = (MIN(x), MAX(y))
TopRight = (MAX(x), MAX(y))
LowerLeft = (MIN(x), MIN(y))
LowerRight = (MAX(x), MIN(y))
Where x and y are the coordinates of both rectangles.
You will now define a step for dividing the search area like a mesh. I suggest you use AVG(W,H)/2 where W and H are the width and height of the search area.
Then, you iterate on the mesh points finding for each one if it is inside the collition area:
IsPointInsideRectangle(rectangle1, point) AND IsPointInsideRectangle(rectangle2, point)
Define:
Xi : the ith partition of the mesh in X axis.
CXi: the count of mesh points that are inside the collision area for Xi.
Then:
And you can do the same thing with Y off course. Here is an ilustrative example of this approach:
You need to do the intersection of the boundaries of the boxes using the line to line intersection equation/algorithm.
http://en.wikipedia.org/wiki/Line-line_intersection
Once you have the points that cross you might be ok with the average of those points or the center given a particular direction possibly. The middle is a little vague in the question.
Edit: also in addition to this you need to work out if any of the corners of either of the two rectangles are inside the other (this should be easy enough to work out, even from the intersections). This should be added in with the intersections when calculating the "average" center point.
This one's tricky because irregular polygons have no defined center. Since your polygons are (in the case of rectangles) guaranteed to be convex, you can probably find the corners of the polygon that comprises the collision (which can include corners of the original shapes or intersections of the edges) and average them to get ... something. It will probably be vaguely close to where you would expect the "center" to be, and for regular polygons it would probably match exactly, but whether it would mean anything mathematically is a bit of a different story.
I've been fiddling mathematically and come up with the following, which solves the smoothness problem when points appear and disappear (as can happen when the movement of a hitbox causes a rectangle to become a triangle or vice versa). Without this bit of extra, adding and removing corners will cause the centroid to jump.
Here, take this fooplot.
The plot illustrates 2 rectangles, R and B (for Red and Blue). The intersection sweeps out an area G (for Green). The Unweighted and Weighted Centers (both Purple) are calculated via the following methods:
(0.225, -0.45): Average of corners of G
(0.2077, -0.473): Average of weighted corners of G
A weighted corner of a polygon is defined as the coordinates of the corner, weighted by the sin of the angle of the corner.
This polygon has two 90 degree angles, one 59.03 degree angle, and one 120.96 degree angle. (Both of the non-right angles have the same sine, sin(Ɵ) = 0.8574929...
The coordinates of the weighted center are thus:
( (sin(Ɵ) * (0.3 + 0.6) + 1 - 1) / (2 + 2 * sin(Ɵ)), // x
(sin(Ɵ) * (1.3 - 1.6) + 0 - 1.5) / (2 + 2 * sin(Ɵ)) ) // y
= (0.2077, -0.473)
With the provided example, the difference isn't very noticeable, but if the 4gon were much closer to a 3gon, there would be a significant deviation.
If you don't need to know the actual coordinates of the region, you could make two CALayers whose frames are the rectangles, and use one to mask the other. Then, if you set an image in the one being masked, it will only show up in the area where they overlap.

Circle to Circle Segment Collision

I'm struggling to find a rock solid solution to detecting collisions between a circle and a circle segment. Imagine a Field of View cone for a game enemy, with the circles representing objects of interest.
The diagram at the bottom is something I drew to try and work out some possible cases, but i'm sure there are more.
I understand how to quickly exlude extreme cases, I discard any targets that don't collide with the entire circle, and any cases where the center of the main circle is within the target circle are automatically true (E in the diagram).
I'm struggling to find a good way to check the rest of the cases. I've tried comparing distances between circle centers and the end points of the segments outer lines, and i've tried working out the angle of the center of the target circle from the center of the main circle and determining whether that is within the segment, but neither way seems to catch all cases.
Specifically it seems to go funky if the target circle is close to the center but not touching it (somewhere between E and B below), or if the segment is narrower than the target circle (so that the center is within the segment but both edges are outside it).
Is there a reliable method for doing this?
Extra info: The segment is described by position P, orientation O (whose magnitude is the circle radius), and a view size, S.
My most successful attempt to date involved determining the angles of the vectors ca1 and ca2, and checking if either of them lies between the angles of vectors a1 and a2. This works for some cases as explained above, but not situations where the target circle is larger than the segment.
Edit 2
After implementing the best suggestion from below, there is still a false positive which I am unsure how best to eliminate. See the pink diagram below. The circle in the lower right is reporting as colliding with the segment because it's bounds overlap both half spaces and the main circle.
Final Edit
After discovering another edge case (4th image), i've settled on an approach which combines the two top answers from below and seems to cover all bases. I'll describe it here for the sake of those who follow.
First exclude anything that fails a quick circle-to-circle test.
Then test for collision between the circle and the two outer lines of the segment. If it touches either, return true.
Finally, do a couple of point-to-halfspace tests using the center of the circle and the two outer lines (as described by Gareth below). If it passes both of those it's in, otherwise return false.
A. Check if it is intersecting the whole cirlce.
B. Check if it is intersecting either of the straight segment lines.
C. If not, check if the angle between the circle centres lies in the angular range of the segment (dot product is good for this).
Intersection requires A && (B || C)
A circular segment (with central angle less than 180°) is the intersection of three figures: a circle, and two half-planes:
So a figure intersects the circular segment only if it intersects all three of these figures. [That's only if but not if; see below.]
Circle/circle intersection is easy (compare the distance between their centres with the sum of their radii).
For circle/half-plane intersection, represent the half-plane in the form p · n ≤ k (where p is the point to be tested, n is a unit vector that's normal to the line defining the half-plane, and k is a constant). Then a circle with centre x and radius r intersects the half-plane if x · n ≤ k + r.
(If you need to handle a circular segment with central angle greater than 180°, split it into two segments with central angle less than 180°. If I understand your problem description correctly, you won't need to do this, since your field of view will always be less than 180°, but it's worth mentioning.)
Edited to add: as pointed out by beeglebug, a circle can intersect all three figures without intersecting their intersection. Oops. But I believe that this can only happen when the circle is behind the centre of the segment, as in the diagram below, and in this case we can apply the separating axis test for convex figures.
The separating axis theorem says that two convex figures fail to intersect if there exists a line such that one figure falls entirely on one side of the line, and the other figure on the other.
If any separating axis exists in this case, then the axis that's perpendicular to the line between the centre of the circle and the centre of the segment is a separating axis (as shown).
Let the centre of the segment be at the origin, let the circle have centre x and radius r, and let the two half-planes have (outward) normals n₁ and n₂. The circle is "behind" the segment if
x · n₁ > 0 and x · n₂ > 0
and the axis separates it from the segment if
|x| > r

fast sphere-grid intersection

given a 3D grid, a 3d point as sphere center and a radius, i'd like to quickly calculate all cells contained or intersected by the sphere.
Currently i take the the (gridaligned) boundingbox of the sphere and calculate the two cells for the min anx max point of this boundingbox. then, for each cell between those two cells, i do a box-sphere intersection test.
would be great if there was something more efficient
thanks!
There's a version of the Bresenham algorithm for drawing circles. Consider the two dimensional place at z=0 (assume the sphere is at 0,0,0 for now), and look at only the x-y plane of grid points. Starting at x= R, y=0, follow the Bresenham algorithm up to y = y_R, x=0, except instead of drawing, you just use the result to know that all grid points with lower x coordinates are inside the circle, down to x=x_center. Put those in a list, count them or otherwise make note of. When done with two dimensional problem, repeat with varying z and using a reduced radius R(z) = sqrt(R^2-z^2) in place of R, until z=R.
If the sphere center is indeed located on a grid point, you know that every grid point inside or outside the right half of the sphere has a mirror partner on the left side, and likewise top/bottom, so you can do half the counting/listing per dimension. You can also save time running Bresenham only to the 45 degree line, because any x,y point relative to the center has a partner y,x. If the sphere can be anywhere, you will have to compute results for each octant.
No matter how efficiently you calculate an individual cell being inside or outside the sphere, your algorithm will always be O(radius^3) because you have to mark that many cells. DarenW's suggestion of the midpoint (aka Bresenham) circle algorithm could give a constant factor speedup, as could simply testing for intersection using the squared radius to avoid the sqrt() call.
If you want better than O(r^3) performance, then you may be able to use an octree instead of a flat grid. Each node of the tree could be marked as being entirely inside, entirely outside, or partially inside the sphere. For partially inside nodes, you recurse down the tree until you get to the finest-grained cells. This will still require marking O(r^2 log r) nodes [O(r^2) nodes on the boundary, O(log r) steps through the tree to get to each of them], so it might not be worth the trouble in your application.

Resources