I have some code which will detect the start and end point of a click-and-drag action, and will save it to 2 vector2 points. I then use this code to convert:
public Rectangle toRect(Vector2 a, Vector2 b)
{
return new Rectangle((int)a.X, (int)a.Y, (int)(b.X - a.X), (int)(b.Y - a.Y));
}
The code above does not work and googling, so far has come up inconclusive.
Could anyone please provide me with some code or a formula to properly convert this?
Note: a vector2 has an x and a y, and a rectangle has an x, a y, a width, and a height.
Any help is appreciated! Thanks
I think you need to have additional logic in there to decide which vector to use as the top left and which to use as the bottom right.
Try this:
public Rectangle toRect(Vector2 a, Vector2 b)
{
//we need to figure out the top left and bottom right coordinates
//we need to account for the fact that a and b could be any two opposite points of a rectangle, not always coming into this method as topleft and bottomright already.
int smallestX = (int)Math.Min(a.X, b.X); //Smallest X
int smallestY = (int)Math.Min(a.Y, b.Y); //Smallest Y
int largestX = (int)Math.Max(a.X, b.X); //Largest X
int largestY = (int)Math.Max(a.Y, b.Y); //Largest Y
//calc the width and height
int width = largestX - smallestX;
int height = largestY - smallestY;
//assuming Y is small at the top of screen
return new Rectangle(smallestX, smallestY, width, height);
}
Related
My issue is that I've been trying to check if a rectangle that is rotated by a certain amount of degrees contain a point, but I wasn't able to calculate that after many attempts with the help of some code samples and examples that I've found online.
What I got is the rectangle (X, Y, Width, Height, Rotation) and the point (X, Y) and I've been trying to create a simple function that lets me instantly calculate that, which would be something something like this:
public bool Contains(Rect Rectangle, float RectangleRotation, Point PointToCheck);
But as I mentioned, I wasn't able to do so, those mathematical calculations that include some formulas I found online are way too much for me to understand.
Could someone help me with calculating this? If you could provide the calculation in C# code form (not formulas) then that would be great! Thanks.
PS: Using the 2D Physics Engine that is available in Unity3D is not a option, my rectangle is not associated with a gameobject that I could attach a 2D collision component to, I need to do this mathematically without the involvement of gameobjects or components.
Edit: I forgot to mention, the rectangle is being rotated by the middle of the rectangle (center/origin).
Rather than checking if the point is in a rotated rectangle, just apply the opposite of the rotation to the point and check if the point is in a normal rectangle. In other words, change your perspective by rotating everything by -RectangleRotation, so that the rectangle does not appear rotated at all.
public bool Contains(Rect rect, float rectAngle, Point point)
{
// rotate around rectangle center by -rectAngle
var s = Math.Sin(-rectAngle);
var c = Math.Cos(-rectAngle);
// set origin to rect center
var newPoint = point - rect.center;
// rotate
newPoint = new Point(newPoint.x * c - newPoint.y * s, newPoint.x * s + newPoint.y * c);
// put origin back
newPoint = newPoint + rect.center;
// check if our transformed point is in the rectangle, which is no longer
// rotated relative to the point
return newPoint.x >= rect.xMin && newPoint.x <= rect.xMax && newPoint.y >= rect.yMin && newPoint.y <= rect.yMax;
}
I'm using EMGU CV for my project and I'm facing a weird problem.
I use cannyedges to find some squares in a photo.
This is working correctly. After that i want to take a pixel inside each square and use that to draw the border.
The problem I'm facing is that i need the vertices of each corner in order to generate a random pixel.
To do this I use the code:
PointF[] corners = rectangle.GetVertices();
float x = Math.Max(corners[1].X, corners[0].X);
float y = Math.Max(corners[1].Y, corners[2].Y);
float width = Math.Min(corners[2].X, corners[3].X) - x;
float height = Math.Min(corners[0].Y, corners[3].Y) - y;
The problem with this code is that rectangle.GetVertices(); gives a different order of corners each time.
The first rectangle returns bottomleft as corner 0, top left as corner 1 etc.
How ever the second rectangle returns bottomright as corner 0, bottomleft as corner 1 etc.
I'm wondering if anyone else is having this problem and if anyone knows how to fix this?
If you need more info to answer this problem please tell me.
PointF[] corners = rectangle.GetVertices();
// Maybe this
corners = corners.OrderBy(s => s.X).ThenBy(s => s.Y).ToArray();
float x = Math.Max(corners[1].X, corners[0].X);
float y = Math.Max(corners[1].Y, corners[2].Y);
float width = Math.Min(corners[2].X, corners[3].X) - x;
float height = Math.Min(corners[0].Y, corners[3].Y) - y;
I am drawing an imaginary circle around the middle of a button.
The radius of the circle is the Height/2 if Height>Width or Width/2 if Width>Height.
Now i have to calculate which coordinates (in pixels) are in this circle.
The idea is that if e.g. the mouse cursor hovers over that circle, something happens.
Calculating each co-ordinate is overkill; just compare the distance to the center. For example:
int radius = 5; // whatever
int deltaX = originX - mouseX, deltaY = originY - mouseY;
// compare the square distance, to avoid an unnecessary square-root
if((deltaX * deltaX) + (deltaY * deltaY) <= (radius * radius)) {
// inside the circle, or on the edge
}
To avoid a little math, you could also do a quick bounding-box check, i.e. checking the rectangular region (just addition/subtraction). This can be used in combination, i.e.
check the bounding box
if it isn't in the bounding box it certainly isn't in the circle
if it is in the bounding box, do the math to compare the square-distance
You are inside the circle when this equation is satisfied:
Math.pow(mouse_pos_x-center_circle_x,2)+Math.pow(mouse_pos_y-center_circle_y,2)<Math.pow(radius,2)
The area of a a circle by definition is a group of points whose distance is equal to or less than the center.
All you must do to test if a point is within a circle is to calculate the distance between it and the center point. If this distance is smaller than the radius of the circle, the point is within the circle.
double Distance(Point p1, Point p2)
{
int x = p1.X - p2.X;
int y = p1.Y - p2.Y;
return Math.Sqrt(x * x + y * y);
}
You can use next condition:
x^2+y^2<R^2
Where R - radius,
All this points are in circle.
I was searching for this but I couldnt find anything. The idea is I have a PointF like (52.66, 60.11) and I want to draw an empty circle with this PointF as its center. I was trying to do with DrawEllipse but it does not care about the center! it is just a rectangle...I think some kind of conversion formula should be used?
You can compute the coordinates of the rectangle from the center and radius:
float x = center.X - radius;
float y = center.Y - radius;
float width = 2 * radius;
float height = 2 * radius;
graphics.DrawEllipse(pen, x, y, width, height);
out of mind:
RectangleF circle2Rect(Point midPoint, float radius) {
return new RectangleF(midPoint.X-radius,
midPoint.Y-radius,
radius*2,
radius*2);
}
(This is not tested)
Use it to convert the parameter of the circle to a rectangle for drawing.
if you draw an ellipse with same height and width you get a circle, if you need to know the Top-Left and Bottom-Right point's coordinates of the square in which your circle is drawn, it's quite banal knowing the middle point (center).
I'm making an inventory screen for a game I'm working on, and I'd like to be able to draw a series of panels representing each item in the inventory. I want to be able to fit those panels on a circular path.
Here's a mock up I made of what I mean
http://fc02.deviantart.net/fs70/f/2010/280/7/2/khmp_magic_menu_concept_by_magna_alphamon-d30a7em.png
basically I'd like to be able to, give a radius, a center point, and the y co-ordinate to start drawing at, draw this series of panels so they align with the path of the circle like in the image.
Computing the y dimension is easy, its just the startposition y + panel height * panel index, but I'm unsure how to compute the x for a variable radius/center point circle.
Any help would be appreciated.
This is in C#, but something similar in C/C++ will be fine as long as I can convert it
Thanks in advance
EDIT: To calirify, y's position is relative to the top or bottom of the screen and is independent of the circle. If a given y does not map to a point on the circle, then I'll discard that point and not draw the panel.
While ideally I'd like to be able to use any elliptical shape (given two radii), a circle would be good too
Let cx, cy be the coordinates of the center point. Let r be the radius of the circle. Let y be the drawing y-coordinate and x, the x-coordinate. You observe that y = cy + panel height * panel index. By the magic of right triangles, this means that x^2 + y^2 = r^2. Solving for x, we get x = cx + sqrt(r^2 - (y-cy)^2).
EDIT: Converting to code:
#include <math>
float ordinate(float cx, float cy, float r, float y) {
// assumes cx and cy are in the same coordinate system as x and y
// assumes the coordinate origin is in the lower left corner.
return cx + sqrtf(powf(r,2) - powf(y-cy,2));
}
I'm dumb. After seeing Eric's answer, I remembered I can just rearrange and solve the equations of a circle or elipse as necessary.
Thanks
You can use a rotational matrix for this. Here is a simple algorithm that finds the next point {x, y} such that it is rotated theta radians around a circle. You can start with the first item at x=radius and y=radius (wherever really, just a point that you know will contain an item), and then just continue to increment theta as you loop through your items.
Point Rotate(int x, int y, float theta)
int x_p = (x * Math.Cos(theta)) - (y * Math.Sin(theta));
int y_p = (y * Math.Cos(theta)) + (x * Math.Sin(theta));
return new Point(x_p, y_p);
end
On a side note; I always preferred "Bolt1, Bolt2, Bolt3" to "Thunder, Thundara, Thundaga" =P