this is precisely what I want multiple markers and covering them is a rectangle polygonI am having multiple latitude and longitude points. I need to plot a polygon in my Windows form application covering all those specified. Something like this.
It consists of a polygon and rectangle. Avoid polygon I just want the rectangle.
As hinted by #Taw, you can draw the rectangle with following co-ordinates:
List<PointF> ptlist = new List<PointF>();
// Add points to the list here
ptlist.Sort((p1, p2) => (p1.X.CompareTo(p2.X))); //Sort by X
float left = ptlist[0].X
float right = ptlist[ptlist.Count - 1].X
ptlist.Sort((p1, p2) => (p1.Y.CompareTo(p2.Y))); //Sort by Y
float top = ptlist[0].Y
float bottom = ptlist[ptlist.Count - 1].Y
// Use left, top and right, bottom to draw your rectangle.
Instead of sort, you may also write a simple code to find minimum and maximum of the list for efficiency.
Related
I have a list of coordinates (circle objects) and I'm trying to find the object on the bottom left.
(top left is 0,0)
I'm using the logic "bottom left circle is when X is minimum and Y is maximum" and it works in most cases;
But it fails in this case for example because the bottom left coordinate (circle) is not the one with smallest X value;
I use something like this and it mostly works;
private static int FindBottomLeftCircle(List<Circle> circles)
{
return circles.IndexOf(circles.OrderBy(c => c.Center.Y).Reverse().Take(13).OrderBy(c => c.Center.X).First());
}
It works best if the bottom row has roughly 13 circles. But as you can see this approach has problems.
How can I reliably find the bottom left circle object?
Just an idea. Will it be correct to say that one circle is bottom-leftier than another, when vector drawn from that circle to another makes angle with X in range (-45, 135) degrees. Then we can determine if angle is correct by calculating scalar product with vector (1, -1).
So we will need to find circle that is bottom-leftier than any other:
circles.First(x => circles.All(y => y.Center.X - x.Center.X - (y.Center.Y - x.Center.Y) => 0))
I have a BitMap image where the image contains a black circle. I have found all the pixels from the image that are black which represent the circle and have saved the points into a List.
Where I am lost is finding the center of the circle from coordinates saved in the list. I am thinking that I need to find the diameter of the circle somehow but how do I loop though the pixels to do that to determine that?
One naive approach could be to find the bounding box for the circle.
Seeing as you already have all of the points in a list you can find the top, bottom, left and right.
Assuming the (0,0) is the top left of the co-ordinate system:
The top is the point with min Y.
The bottom is the point with max Y.
The left is the point with min X.
The right is the point with max X.
The center of the bounding box is the center of the circle.
Similarly the width/height of the bounding box is its diameter.
Edit: an alternative solution
Find the mean of all the points in the circle.
This will then give you the center of the circle.
var aggregate = points.Aggregate((point, result) => new Point{ X = point.X + result.X, Y = point.Y + result.Y });
var center = new Point { X = aggregate.X / points.Count, Y = aggregate.Y / points.Count };
This may be a more optimal solution because it could be done while you are scanning the image for the black pixels. Rather than finding the black pixels and then using LINQ.
Circle is a relative term when it comes to images, that's to say, that the shape you are referring to is shown in pixels and may only be representative of a circle.
However to get the midpoint all you need to do is get the extents.
Assuming you have a List<Point>
var left = list.Min(x => x.X);
var right = list.Max(x => x.X);
var top= list.Min(x => x.Y);
var bottom = list.Max(x => x.Y);
Point mid = new Point();
mid.X = left + (right-left) / 2; //calculate mid point x
mid.Y = top + (bottom-top) / 2; //calculate mid point y
Note : Totally untested
I answered a question on how to set up a Chart to look like a regular mathematical graph, i.e. with the axes centered and with nice arrows to the top and to the right..
However I found the built-in AxisArrowStyle.Triangle to be rather big and found no way to make it smaller.
Lines - A line-shaped arrow is used for the relevant axis.
None - No arrow is used for the relevant axis.
SharpTriangle - A sharp triangular arrow is used for the relevant axis.
Triangle - A triangular arrow is used for the relevant axis.
Here is the original look of it:
So how can we fix this?
The Chart's axis.AxisArrowStyle enumeration doesn't let us pick a smaller arrow, only a slimmer one.
So we need to draw it ourselves:
Here is a simple but effective piece of code that achieves just that:
private void chart1_PrePaint(object sender, ChartPaintEventArgs e)
{
if (e.ChartElement.ToString().StartsWith("ChartArea-") )
{
// get the positions of the axes' ends:
ChartArea CA = chart1.ChartAreas[0];
float xx = (float)CA.AxisX.ValueToPixelPosition(CA.AxisX.Maximum);
float xy = (float)CA.AxisY.ValueToPixelPosition(CA.AxisY.Crossing);
float yx = (float)CA.AxisX.ValueToPixelPosition(CA.AxisX.Crossing);
float yy = (float)CA.AxisY.ValueToPixelPosition(CA.AxisY.Maximum);
// a simple arrowhead geometry:
int arrowSize = 18; // size in pixels
Point[] arrowPoints = new Point[3] { new Point(-arrowSize, -arrowSize / 2),
new Point(-arrowSize, arrowSize / 2), Point.Empty };
// draw the two arrows by moving and/or rotating the graphics object:
e.ChartGraphics.Graphics.TranslateTransform(xx + arrowSize, xy);
e.ChartGraphics.Graphics.FillPolygon(Brushes.Black, arrowPoints);
e.ChartGraphics.Graphics.TranslateTransform(yx -xx -arrowSize, yy -xy -arrowSize);
e.ChartGraphics.Graphics.RotateTransform(-90);
e.ChartGraphics.Graphics.FillPolygon(Brushes.Black, arrowPoints);
e.ChartGraphics.Graphics.ResetTransform();
}
}
I am drawing 10 circles in an array, these circles are moving around and bouncing across the screen. How would I take these drawn circles and detect when they collide with each other. When they collide I need them to bounce off of each other. These circles have random widths and heights. random speeds and all spawn at center screen.
How the circles are drawn:
private void pbGamescreen_Paint(object sender, PaintEventArgs e)
{
for (int mt = 0; mt < spawn; mt++)
{
e.Graphics.FillEllipse(ballBrush[mt], (int)xPos[mt], (int)yPos[mt], ballSizex[mt], ballSizey[mt]);
e.Graphics.DrawEllipse(Pens.Gray, (int)xPos[mt], (int)yPos[mt], ballSizex[mt], ballSizey[mt]);
}
}
Two circles intersect if the distance between their center points is smaller than the addition of their radiuses. You need to iterate each of your circle and check this against each other circle.
For instance, say you have these two circles on a horizontal axis:
(-----o-----) (---o---)
They do not intersect, as the distance between their center points is 12, and the sum of their radiuses is 8. However, these two do:
(-----o----(-)--o---)
The formula for the distance between two 2D points is:
var xdiff = x2 - x1;
var ydiff = y2 - y1;
return Math.Sqrt(xdiff * xdiff + ydiff * ydiff);
if r1 and r2 are radiuses of the two circles, and d is the distance between the centers of teh two circles then
bounce off when d<=r1 + r2;
ideally you should do it when d == r1 + r2;
Just a suggestion:
also keep the mass of the circle proportional to their r(radius) and then using the law of conservation momentum m1v1 = m2v2; bounce them offf in a way that looks real
Here's 2 methods available;
if(rectangle.Intersects(otherRectangle))
{
//collision stuff
}
Catch: Only works with non-rotating rectangles.
if(Vector2.Distance(player.pos, enemy.pos) < 50)
{
//collision stuff
}
Catch: Only works with circles.
What I want is to calculate x and y in this image:
Facts
The width and length of both rectangles is defined, along with their rotations.
I can calculate D using the Pythagorean theorem.
But the TRUE distance is D - (X + Y).
General approach
Evidently x and y can be calculated using the Cosine rule.
But I only have the width or length and the angle between the two shapes.
Complication
Plus, this needs to work for any rotation.
The rectangle on the left could be rotated in any direction, and x would be different depending on said rotation.
Question
How would I calculate x and y?
I just want an effective collision detection method more complex than bounding boxes and Pythagoras' theorem.
One approach is to rotate the line with the inverse angle and check with the axis-aligned box:
class RotatedBox
{
...
float CalcIntersectionLength(Vector2 lineTo) //assume that the line starts at the box' origin
{
Matrix myTransform = Matrix.CreateRotationZ(-this.RotationAngle);
var lineDirection = Vector2.Transform(lineTo -this.Center, myTransform);
lineDirection.Normalize();
var distanceToHitLeftOrRight = this.Width / 2 / Math.Abs(lineDirection.X);
var distanceToHitTopOrBottom = this.Height / 2 / Math.Abbs(lineDirection.Y);
return Math.Min(distanceToHitLeftOrRight, distanceToHitTopOrBottom);
}
}
Now you can calculate the actual distance with
var distance = (box1.Center - box2.Center).Length
- box1.CalcIntersectionLength(box2.Center)
- box2.CalcIntersectionLength(box1.Center);
Be sure that the rotation direction matches your visualization.