I'm trying to make a circle out of a Polygon (I know I could just use for example the shape renderer, but I need it like this).
The circle should consist out of 4 Nodes and 4 curved Edges.The nodes are rendered by a ShapeRenderer and are positioned like a "+", the edges by an edge renderer to curve them. Right now I have the problem, that the edges enter all the nodes on the sides, which is OK for the top and bottom node, but does not work for the left and the right node as they should enter the nodes on top and the bottom, and so I don't get a perfect circle but more something egg-shaped.
Does anybody know how I can change the position the edges enter the nodes or how to rotate this nodes for 90 degrees?
The method to set control points in EdgeRenderer looks very simple:
protected void getCurveControlPoints(EdgeItem eitem, Point2D[] cp,
double x1, double y1, double x2, double y2)
{
double dx = x2-x1, dy = y2-y1;
cp[0].setLocation(x1+2*dx/3,y1);
cp[1].setLocation(x2-dx/8,y2-dy/8);
}
Probably, you have to override it to set achieve the curve you want.
Please share your solution here for other, if that is the case.
OK, i was trying some stuff and came up mwith the following:
protected void getCurveControlPoints(EdgeItem eitem, Point2D[] cp,
double x1, double y1, double x2, double y2)
{
double dx = x2-x1, dy = y2-y1;
// cp[0].setLocation(x1+2*dx/3,y1);
// cp[1].setLocation(x2-dx/8,y2-dy/8);
cp[0].setLocation(x1+2*dx/3,y1);
cp[1].setLocation(x2,y2-dy/3);
}
This works for me, i'm not sure if it is a perfect circle, but i can't spot a difference.
I also dont really understand why it works, because I add 2*dx/3 to x1, but substracted only dy/3 from y2. Does anybody have a clue why this works?
Related
So I have a set of points making up a simple polygon
points = [(x0, y0), (x1, y1), ..., (xn, yn)]
The polygon may be concave or convex, both cases must be handled.
Next I create two arcs for each line by treating the arc between point A-B as different from the arc between point B-A. Next I create paths from these points by always choosing the closest counter-clockwise arc. So one path goes clockwise and one counter-clockwise: [(x0, y0), (x1, y1), ... , (xn, yn)] and [(xn, yn), (xn-1, yn-1), ... , (x0, y0)]
By traversing these arcs how do I know if the arcs are creating an internal face or an external face?
For example, in the two polygons below the same orange line is used on two different polygons. In the first polygon the top orange arc is in the internal face (pointing inwards) while in the other polygon the top orange arc is in the external face (pointing outwards).
My question arose from the answer by #HEKTO in this post: How to find all the polygonal shapes of given the vertices?.
Use Green's theorem. Iterate over the points and compute the integral, then check the sign. Like this:
decimal sum = 0.0;
for(int current = 0; current < points.length; current++)
{
int next = current + 1;
if (next == points.length)
next = 0;
sum += (points[this].y + point[next].y) * (point[next].x - point[this].x);
}
Check the sign of sum to find out whether the winding is clockwise or counter-clockwise. Which is which will depend on which direction the Y axis increases in.
Note that if you were trying to compute the area of the polygon you would multiply the Y part of the equation by 0.5, but since you're only interested in the sign of the result you don't need to.
Given a cartesian plane and rectangle on this plane where bottom-left corner has coordinates (x1, y1), the top-right one has coordinates (x2, y2).
Now I need to find the count of those rectangles that have the common area with the rectangle with a bottom-left corner coordinates (x1, y1) and a top-right corner coordinates (x2, y2).
How this can be done in an efficient way?
Their can be many such queries of the form x1 y1 x2 y2 and for given rectangle i need to find count of overlapping rectangles.Also even if the two rectangles only share a common point, they are still regarded as sharing common area.There can be a few same rectangles on the plane, they should be regarded as a few different rectangles.
The main point is rectangles can be added and deleted at any given instant.
Constraints :
Their can be total of 10^5 queries.And each coordinate can go from 1 to 10^9.
My approach : We know that Suppose we have two rectangles R1 and R2. Let (x1, y1) be the location of the bottom-left corner of R1 and (x2, y2) be the location of its top-right corner. Similarly, let (x3, y3) and (x4, y4) be the respective corner locations for R2. The intersection of R1 and R2 will be a rectangle R3 whose bottom-left corner is at (max(x1, x3), max(y1, y3)) and top-right corner at (min(x2, x4), min(y2, y4)).
If max(x1, x3) > min(x2, x4) or max(y1, y3) > min(y2, y4) then R3 does not exist, ie R1 and R2 do not intersect.
Now main problem with me that ma facing is say we have insert query of say (I X1 Y1 X2 Y2) and delete query of type(D index) which will delete rectangle inserted at index th query of insertion.How to handle them efficiently
An R-tree should work. See http://en.wikipedia.org/wiki/R-tree for more.
I wrote a solution in C# for a similar problem
https://github.com/ERufian/Overlap/blob/master/RectangleOverlap/Heap.cs
With minor modifications it would do what you need:
namespace RectangleOperations
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
public static class Heaped
{
public static int GetOverlap(double x1, double y1, double x2, double y2, Rect[] rects, int rectCount)
{
Rect startingArea = new Rect(new Point(x1, y1), new Point(x2, y2));
return Overlap(startingArea, 0, 0, rects, rectCount)
}
private static int Overlap(Rect currentArea, int currentIndex, int currentCount, Rect[] rects, int rectCount)
{
List<int> counts = new List<int>();
for (int i = currentIndex; rectCount > i; i++)
{
Rect newArea = currentArea;
newArea.Intersect(rects[i]);
// include point and edge (size 0) overlaps
if (0 <= newArea.Size.Height && 0 <= newArea.Size.Width)
{
counts.Add(Overlap(newArea, i + 1, currentCount + 1));
}
}
return (0 == counts.Count) ? currentCount : counts.Max();
}
}
}
Some help for translating this code if not using C#
Rect.Intersect calculates the intersection of the current rectangle with another rectangle and replaces the current rectangle.
List<> is a dynamic array (that grows as you add items), you can use regular arrays but then you'll need to calculate sizes, keep track of how many items were actually added and provide a way to calculate the Max.
I have defined a Polygon. I want to intersect and trim a list of other Lines with the Edges of this polygon (white rectangle here), so that endpoints of lines are limited to the inner part of the polygon.
currently, I'm intersecting each cyan line with the edges of the polygon which gives me the intersection points. But the problems is I don't know how to trim them. I know that I need to change the X1, Y1, X2 and Y2 of each intersecting line (cyan line) to the intersection point. But I don't know how do do it.
Let me explain it this way. A cyan line intersects one of the edges of the polygon, now I need to move the endpoint of the cyan line to the intersection point to simulate a trim right? Which endpoint I need to move? I'm a bit lost here.
public class Polygon
{
public List<Line>() Edges;
}
public class Line
{
public double X1;
public double X2;
public double Y1;
public double Y2;
}
var listOfIntersectingLines = new List<Line>() {L1, L2, ... };
var ListOfLinesLimitedToPolygon = ?
When you intersect two sections, that dont have an intersection point, your function should return null. For example: in your first picture, the 4th line from the bottom does not intersect the left or the top edge of the rectangle, it only intersects the bottom and the right edges. If you pick a cyan line, and intersect it with all edges of the polygon, you will always get either 2 or 0 intersection points. If you got 2, then those 2 points are the endpoints of your trimmed cyan line. If you got 0, that means the cyan line is outside of the polygon.
Possible problems:
1. An edge overlaps with a cyan line. You must decide whether you want to keep this line or not, and adjust you intersection function accordingly.
2. An edge goes through a corner. The easiest way to handle it is to return an intersect point if the line goes to the "first" endpoint of your edge, but return null if it crosses the 2nd endpoint. As your polygon is probably defined from point to point, it ensure that at every corner, there is only 1 edge that can be intersected.
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.
Given a point (pX, pY) and a circle with a known center (cX,cY) and radius (r), what is the shortest amount of code you can come up with to find the point on the circle closest to (pX, pY) ?
I've got some code kind of working but it involves converting the circle to an equation of the form (x - cX)^2 + (y - cY)^2 = r^2 (where r is radius) and using the equation of the line from point (pX, pY) to (cX, cY) to create a quadratic equation to be solved.
Once I iron out the bugs it'll do, but it seems such an inelegant solution.
where P is the point, C is the center, and R is the radius, in a suitable "mathy" language:
V = (P - C); Answer = C + V / |V| * R;
where |V| is length of V.
OK, OK
double vX = pX - cX;
double vY = pY - cY;
double magV = sqrt(vX*vX + vY*vY);
double aX = cX + vX / magV * R;
double aY = cY + vY / magV * R;
easy to extend to >2 dimensions.
i would make a line from the center to the point, and calc where that graph crosses the circle oO i think not so difficult
Solve it mathematically first, then translate into code. Remember that the shortest line between a point and the edge of a circle will also pass through its center (as stated by #litb).
The shortest distance point lies at the intersection of circumference and line passing through the center and the input point. Also center, input and output points lie on a straight line
let the center be (xc, yc) and shortest point from input (xi, yi) be (x,y) then
sqrt((xc-x)^2 + (yc-y)^2) = r
since center, input and output points lie on a straight line, slope calculated between
any of two of these points should be same.
(yc-yi)/(xc-xi) = (y-yc)/(x-xc)
4.solving equations 2&3 should give us the shortest point.
Trig functions, multiply by r, and add pX or pY as appropriate.
Treat the centre of the circular as your origin, convert the co-ordinates of (pX, pY) to polar co-ordinates, (theta, r') replace r' with the original circle's r and convert back to cartesian co-ordinates (and adjust for the origin).
You asked for the shortest code, so here it is. In four lines it can be done, although there is still a quadratic.
I've considered the point to be outside the circle.
I've not considered what happens if the point is directly above or below the circle center, that is cX=pX.
m=(cY-pY)/(cX-pX); //slope
b=cY-m*cX; //or Py-m*Px. Now you have a line in the form y=m*x+b
X=( (2mcY)*((-2*m*cY)^2-4*(cY^2+cX^2-b^2-2*b*cY-r^2)*(-1-m^2))^(1/2) )/(2*(cY^2+cX^2-b^2-2*bc*Y-r^2));
Y=mX+b;
1] Get an equation for a line connecting the point and the circle center.
2] Move along the line a distance of one radius from the center to find the point on the circle. That is: radius=a^2+b^2 which is: r=((cY-Y)+(cX-X))^(1/2)
3] Solve quadratically. X=quadratic_solver(r=((cY-Y)+(cX-X))^(1/2),X) which if you substitute in Y=m*X+b you get that hell above.
4] X and Y are your results on the circle.
I am rather certain I have made an error somewhere, please leave a comment if anyone finds something. Of course it is degenerate, one answer is furthest from your point and the other is closest.
Easy way to think about it in terms of a picture, and easy to turn into code: Take the vector (pX - cX, pY - cY) from the center to the point. Divide by its length sqrt(blah blah blah), multiply by radius. Add this to (cX, cY).
Here is a simple method I use in unity... for the math kn00bs amongst us.
Its dependent on the transform orientation but it works nicely. I am doing a postion.z = 0 but just fatten the axis of the 2d circle you are not using.
//Find closest point on circle
Vector3 closestPoint = transform.InverseTransformPoint(m_testPosition.position);
closestPoint.z = 0;
closestPoint = closestPoint.normalized * m_radius;
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere(transform.TransformPoint(closestPoint), 0.01f);