I'm trying to figure out what sort of equation would get me this.
If I have a center node, and an undetermined number of nodes orbiting it, how would I get the canvas coordinates I need to place them at even intervals?
In this case we have eight nodes because they were easiest for me to draw. But in other cases we could have more or less.
If you have a response in Java that would be best. Otherwise pseudocode is fine.
Sample image to help explain:
If you travel from 0,0 to D,0 at an angle of 0 radians, at any other angle A you travel the following distance:
xdiff = D*cos(A)
ydiff = D*sin(A)
(note that A must be in radians - 0 and 2*pi are a full 0/360 degrees, so 2pi/2 is 180 degrees, 2pi/4 is 90 degrees and so on)
So (for example), to draw ten circles at a distance D around a central circle, consider each angle A = i*2pi/10, compute the xdiff and ydiff for each angle, add them to the central circle's position and draw the orbiting circle.
There are a number of approaches.
As a starting point take a look at
http://en.wikipedia.org/wiki/Force-directed_graph_drawing
Related
I am building a road editor where one can drag predefined road segments together and combine them to a connected road. One of those segments is a right curve.
The curve is drawn as SVG (using D3 arc path function) and has two handles to change the radius and the length directly within the SVG (small black circle changes length and small black square changes the radius). I use a d3 drag handler on the handles.
To calculate the new central angle I do as follows:
get YOffset from center point of the arc
flip YOffset (to match screen y and math)
get corresponding x value with Pythagoras (x = Math.sqrt(r^2 - YOffset^2))
get the respective central angle (Math.PI / 2 - Math.atan2(YOffset, x);
This will only work if the arc starts at PI/2 like in the figure. If I add further arcs with arbitrary start angles (see next figure, red arc), my solution wont work.
I'm looking for a general solution so it will work for any arc regardless of its start angle.
To me it seems this is not much of a programming problem, but of math. What I understand is: given a start point (x₁, y₁), an end pont(x₂, y₂) and a radius r, what is the angle α?
You can compute the distance d between the two points. Half its length is the far leg of a right triangle with r as its hypothenuse. d/2r is the sinus of the near angle; double that and you have the angle between the end points.
(And, having α expressed in radians, the path length is simply α * r.)
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.
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.
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.
I'm working on a project that requires me to accurately control the number of pixels that are used to draw (roughly) circular stimuli, and although Bresenham's algorithms are great, they don't draw circles of an arbitrary area (to my knowledge). I've tried scripts that interrupt Bresenham's algorithm when the desired area has been plotted, but the results are decidedly hit-or-miss. Does anyone know of a way to plot the "best" circle (somewhat subjective, I know) using a given number of pixels? Many thanks!
A rough way of doing it, for example:
The radius of a circle of area 1000 sq px is sqrt(1000/pi) = 17.8... That circle should then fit in a 35x35 matrix. If you make "indices" for that matrix where the central pixel is (0,0), you can check easily if the pixel falls in the circle or not by substitution into the equation of a circle x^2 + y^2 = r^2. Or you can use the alternative equation for a circle centered at (a,b). If it evaluates to TRUE, it does, if not, it's outside the circle.
As a pseudocode/example, in Python I would do an optimized version of:
import numpy, math
target_area = 1000.0
r = (target_area / math.pi) ** 0.5
m = numpy.zeros((2*r+2,2*r+2))
a, b = r, r
for row in range(0, m.shape[0]):
for col in range(0, m.shape[1]):
if (col-a)**2 + (row-b)**2 <= r**2:
m[row,col] = 1
numpy.sum(m)
#>>> 999
Here is the result when the target area is 100,000 pixels (the actual circle generated is 99988.0):
You could also write a routine to find which areas can be matched more closely than others with this algorithm, and select those values to ensure conformity.
The area of a circle is A=Pi*r2. You're starting from the area and (apparently) want the radius, so we divide both sides by Pi to get: r2=A/pi. Taking the square root of both sides then gives us: r=sqrt(A/pi). Once you have the radius, drawing with most of the normal algorithms should be straightforward.
A simple (but somewhat naive approach) would be to simply count the number of pixels drawn by Bresenham's algorithm for a given radius, and then use binary search to find the radius that produces the desired number of pixels.
My first thought is to use an algorithm with sub-pixel precision. Consider what happens if you're center has irrational coordinates and you gradually increase the radius. This would fill seemingly random pixels around the perimeter as they became included in the circle. You want to avoid symmetry that causes the 4 quadrants of the circle adding pixels at the same time so you get closer to single pixels getting added. How something like this could be implemented I haven't a clue.
I had to solve a single instance of the 3d version once. I needed to a set of lattice points inside a sphere to be less-than or equal to 255. IIRC if r*r = 15 there are 240 points inside the sphere. I was not concerned with getting 255 exactly though.
Supposedly you have 2000 pixels in total that should make up your complete circle. By complete I mean there should be no breakage in pixels and must be connected to each other. Since 2Pi*R = circumference, the running length of diameter of the circle, this is the total amount of pixels you have. Now simply write R = 2000/2*Pi and this will give you the radius. Now you should be able to draw a circle the comprised of 2000 pixels. I hope this is what you wanted.
Let's forget about pixels for a second and let's work through the basic math/geometry.
We all know that
Area of a Circle = Pi * Radius ^2
which is the same as saying
Area of a Circle = Pi * (Diameter / 2) ^2
We all know that
Area of the Square Enclosing the Circle (i.e. each side of the square is tangent to the circle) = Diameter * Diameter
Thus
Ratio of the Circle Area to the Square Area = Circle Area / Square Area = (Pi * (Diameter / 2) ^2) / (Diameter * Diameter) = Pi / 4
Now let's assume that we have a circle and square with a pixel count large enough so that we don't have to worry about the troublesome edge cases around the border of the circle. In fact let's assume for a second that we have a very large diameter (maybe 10,000 or maybe even infinite). With this assumption the following holds:
Number of Pixels in the Circle = (Number of Pixels in the Square) * (Ratio of the Circle Area to the Square Area)
In other words for a sufficiently large number of pixels, the ratio of the areas of a perfectly drawn circle to a perfectly drawn square will approximate the ratio of the number of pixels in a pixelated circle to the number of pixels in the enclosing pixelated square.
Now in a pixelated square, the number of pixels in that square is the number of pixels across times the number of pixels high. Or in other words it is the square's diameter (in pixels) squared. Let's call the square's pixel diameter d. So substituting with the formulas above we have:
Number of Pixels in the Circle = (d * d) * (Pi /4)
So now let's solve for d
d = Sqrt(4 * (Num of Pixels in the Circle) / Pi)
Well we said earlier that d was the diameter of the square. Well it also happens to be the diameter of the circle. So when you want to draw a circle with a certain number of pixels, you draw a circle with the diameter being:
Diameter of Circle = Sqrt(4 * (Desired Number of Pixels in Circle Area) / Pi)
Now obviously you have to make some choices about rounding and so forth (there is no such thing as a fractional pixel), but you get the point. Also, this formula is more accurate as the desired number of pixels for the area of the circle goes up. For small amounts of pixels the roundoff error may not give you exactly the right number of pixels.