I have listed bounding boxes X top left, Y top left , X top right , Y top right, X bottom right , Y bottom right , X bottom left , Y bottom left
Need to create fill rectangle on image.
How can i calculate x,y,width and height for Rectangle
Have used Pen and DrawRectangle
Bitmap bmp = (Bitmap)Bitmap.FromFile(imageFilePath);
Graphics g = Graphics.FromImage(bmp);
Pen snowPen = new Pen(Color.Black, width);
g.DrawRectangle(snowPen, x , y , width, height);
How can i convert the boundingboxes data to get x,y,height and width ?
If you look at the documentation of DrawRectangle here to know how are expressed x and y:
The x-coordinate of the upper-left corner of the rectangle to draw.
The y-coordinate of the upper-left corner of the rectangle to draw.
And based on the fact that you mentioned that your input info is:
X top left, Y top left, X top right, Y top right, X bottom right , Y bottom right , X bottom left , Y bottom left
Then:
x= X top left
y= Y top left
Height= (Y top left - Y bottom left) or Y top right - Y bottom right: if you have a boundingbox value which was a rectangle, the values are equals)
Width= (X top right - X top left) or X bottom right - X bottom left: if you have a boundingbox value which was a rectangle, the values are equals)
Remarks:
As you did not mention how your boundingbox values were expressed (int? float?), keep in mind that here your values should be int values.
If your bounding box is not a rectangle, you should use DrawPolygon instead
Related
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 am creating a Rect in C# with two points. These points are actually Geographical bounds. The problem I am having is what when I create the rectangle the y axis is flipped.
For example say my data is west="5.42194487004" south="46.407494" east="17.166386" north="55.056664"
I pass that into Rect geoBounds = new Rect(new Point(west, north),new Point(east, south));
The Rectangle that is created has the following properties
Bottom 55.056664 double
Height 7.781945 double
IsEmpty false bool
Left 5.864166 double
Right 15.038887000000003 double
Top 47.274719 double
Width 9.1747210000000017 double
X 5.864166 double
Y 47.274719 double
The Y axis is flipped. I have triple checked that the data being fed into the call is correct. What is wrong? Also I know that I did not supply much code but did not feel any more was needed. Will provide more if needed.
The coordinate system has 0,0 at the top left of the screen, with Y increasing in the downward direction. You can see this at the example page for the Rect.Bottom property: http://msdn.microsoft.com/en-us/library/system.windows.rect.bottom.aspx
Note on that page this comment:
// Bottom property gets the y-axis value of the bottom of the rectangle.
// For this rectangle the value is 55.
rectInfo = rectInfo + "Bottom: " + myRectangle.Bottom;
and this one:
// Top property gets the y-axis position of the top of the rectangle which is
// equivalent to getting the rectangle's Y property.
// For this rectangle the value is 5.
rectInfo = rectInfo + "| Top: " + myRectangle.Top;
This is further supported by the explicit constructor for Rect: http://msdn.microsoft.com/en-us/library/ms587929%28v=vs.95%29.aspx
Note that x and y describe the top left corner, where width extends that in the rightward direction and height extends downwards.
Rect geoBounds = new Rect(west, north, (east - west), (north - south));
I need to convert an extents BottomLeft (-180, -90), TopRight (180, 90) to System.Windows.Rect. Rect is created using top left position and size of rect so, I tried to create it using position as (-180, 90) and size as width & height of above extents but which is wrong.
So, I am unable to create Rect for the above extents. Please help in creating it.
Thanks!
Rectangle can be represented as:
Rectangle d = new Rectangle(xCoordinate, yCoordinate, width, height);
where coordinates relevant here is that of the top-left corner. So you should calculate these parameters from the coordinates available to you. In your case:
Rectangle d = new Rectangle(-90, 180, 180, 360);
where
width = right - left
height = top - bottom
I'm currently trying to understand per pixel collision detection.
This is the code I don't understand:
static bool IntersectPixels(Rectangle rectangleA, Color[] dataA,
Rectangle rectangleB, Color[] dataB)
{
// Find the bounds of the rectangle intersection
int top = Math.Max(rectangleA.Top, rectangleB.Top);
int bottom = Math.Min(rectangleA.Bottom, rectangleB.Bottom);
int left = Math.Max(rectangleA.Left, rectangleB.Left);
int right = Math.Min(rectangleA.Right, rectangleB.Right);
// Check every point within the intersection bounds
for (int y = top; y < bottom; y++)
{
for (int x = left; x < right; x++)
{
// Get the color of both pixels at this point
Color colorA = dataA[(x - rectangleA.Left) +
(y - rectangleA.Top) * rectangleA.Width];
Color colorB = dataB[(x - rectangleB.Left) +
(y - rectangleB.Top) * rectangleB.Width];
// If both pixels are not completely transparent,
if (colorA.A != 0 && colorB.A != 0)
{
// then an intersection has been found
return true;
}
}
}
// No intersection found
return false;
}
I really haven't understood the all loop. I'll be glad for some explanation how it works.
First up, it finds the region the two image rectangles intersect, then it iterates through each pixel in that region, and compares the alpha values of each image of each pixel. If neither has an alpha value of 0, they are both considered 'solid' and therefore colliding.
it's not that hard (in this case) - you give the algorithm the two bounding-boxes of your objects (so the hole object is inside this box), and a array with color-information for them.
Tha algorithm assumes that a point belongs to the object IFF it is not transparent - this is important.
The first step is to calculate the intersecting rectangle - if you intersect two rectangles that have sides parallel to the axes like in this case - you will get a rectangle again or an empty set.
The next step is to iterate in this intersecting rectangle for all (x,y) -coordinates insiede - first y, then x -so you get your normal first x, then y inside, but this is minor point and not important.
Then finally the algorithm gets the color for object A and B at the current pixel (x,y) - if both colors are NOT transparent then the pixel is in both objects and the objects have to intersect at this point - so the algorithm terminates with "YES they intersect"
If all pixels in the intersection of the bounding boxes where checked and no common (e.g. not transparent) pixel was found the object don't intersect and so the algorithm terminates with "NO they don't intersect"
I hope this helps.
for (int y = top; y < bottom; y++) loops over the lines of the resulting rectangle from top to bottom, and for (int x = left; x < right; x++) loops over pixels inside each line, left to right.
I am drawing a triangle with the following code
int x = x coordinate for center;
int ax = x coordinate for left;
int bx = x coordinate for right;
int top = y coordinate for top;
int bottom = y coordinate for bottom;
// (x, top)
//(ax, bottom) (bx, bottom)
GraphicsPath path = new GraphicsPath();
// _
path.AddLine(ax, bottom, bx, bottom);
// /
path.AddLine(ax, bottom, x, top);
// \
path.AddLine(bx, bottom, x, top);
// order of drawing is _ / \ (bottom line, left side, right side)
When I call DrawPath, it always draws my lines, no matter the order. But when I call FillPath, it does nothing. Only when my order is / _ \ or \ _ / does my triangle actually fill. Why is this?
It turns out that the answer I posted originally didn't really solve the problem and that it worked on my machine because of an additional change I introduced, which is to change the FillMode:
GraphicsPath path = new GraphicsPath(FillMode.Winding);
When you use the Winding mode, the algorithm will detect a closed path even if you didn't add the lines in order.