I'm attempting to make a very very simple paint project in C#'s WPF. I have pretty much everything working except for drawing a triangle. I can't figure out the math required to create the triangle.
I have code like this for drawing rectangles and circles:
case "Rectangle":
case "Ellipse":
var x = Math.Min(pos.X, mm.startPoint.X);
var y = Math.Min(pos.Y, mm.startPoint.Y);
var width = Math.Max(pos.X, mm.startPoint.X) - x;
var height = Math.Max(pos.Y, mm.startPoint.Y) - y;
mm.shapeObj.Width = width;
mm.shapeObj.Height = height;
Canvas.SetLeft(mm.shapeObj, x);
Canvas.SetTop(mm.shapeObj, y);
break;
I add it to the children of the canvas elsewhere. This code allows me to click on the canvas and drag my mouse to size the rectangle or ellipse.
I was hoping to do something similar with a triangle. I only want the user to be able to click on the screen and drag out an equilateral triangle, for simplicity sake. I thought about making it so the user could just click three times to create the triangle but due to the way the project is coded, that would be a little more difficult than it sounds. However, if there isn't any way to calculate the triangle I'm trying to create, I can make it work with three clicks.
if you order your points like this:
int smX = startPoint.X < finalPoint.X ? startPoint.X : finalPoint.X;
int bgX = startPoint.X < finalPoint.X ? finalPoint.X : startPoint.X;
int smY = startPoint.Y < finalPoint.Y ? startPoint.Y : finalPoint.Y;
int bgY = startPoint.Y < finalPoint.Y ? finalPoint.Y : startPoint.Y;
You can imagine a rectangle with the points:
(smX, smY)
(smX, bgY)
(bgX, smY)
(bgX, bgY)
So you could use the middle of the rectangle to set a point of triangle, than draw a triangle with the points:
(smX, bgY)
(bgX, bgY)
(smX + ((bgX - smX) / 2), smY)
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;
Is there a formula to average all the x, y coordinates and find the location in the dead center of them.
I have 100x100 squares and inside them are large clumps of 1x1 red and black points, I want to determine out of the red points which one is in the middle.
I looked into line of best fit formulas but I am not sure if this is what I need.
Sometimes all the red will be on one side, or the other side. I want to essentially draw a line then find the center point of that line, or just find the center point of the red squares only. based on the 100x100 grid.
List<Point> dots = new List<Point>();
int totalX = 0, totalY = 0;
foreach (Point p in dots)
{
totalX += p.X;
totalY += p.Y;
}
int centerX = totalX / dots.Count;
int centerY = totalY / dots.Count;
Simply average separately the x coordinates and the y coordinates, the result will be the coordinates of the "center".
What if there are two or more subsets of red points ? Do you want the black point inside them?
Otherwis, if I understood your question, just give a weight of 1 to red points and 0 to blacks. Then do the weighted mean on X and Y coordinate
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
I want to move through the pixels of an image, not by going line by line, column by column in the "normal" way. But begin at the center pixel and going outward in a spiral motion. But I'm not sure how to do this.
Any suggestions on how this can be done?
You can do this by using parametric functions, function for radius is r(t) = R, and x(t) = Rcos(t) and y(t)=Rsin(t).
Do you mean something like this?
It would be helpful to think about this in reverse.
For example, starting at the top left corner and moving in a clockwise direction you would move along the top row, then down the right hand side, along the bottom, and up the left edge to the pixel under the starting point.
Then move along the second row, and continue in a spiral.
Depending on the dimensions of the image you will end up with either a single column of pixels or a single row of pixels and will be moving either up/down or left/right.
From this finishing point you can then follow your steps backwards and process all the pixels as you need to.
To work out your starting position mathematically you would need to know the width/height of the image as well as which pixel you would like to end on and the direction you want to be travelling in when you get to the last pixel.
Something like this should do it:
int x = width / 2;
int y = height / 2;
int left = width * height;
int dir = 0;
int cnt = 1;
int len = 2;
int[] move = { 1, 0, -1, 0, 1 };
while (left > 0) {
if (x >= 0 && x < width && y >= 0 && y < height) {
// here you do something with the pixel at x,y
left--;
}
x += move[dir % 4];
y += move[(dir % 4) + 1];
if (--cnt == 0) {
cnt = len++ / 2;
dir++;
}
}
If the image is not square, the spiral will continue outside the coordinates of the image until the entire image has been covered. The condition in the if statement makes sure that only coordinates that are part of the image are processed.