How can I find the area of the rectangle formed with 2 2-dimensional Vectors. ex:
p1 = (20, 40);
p2 = (30, 60);
I need to find the rectangle this forms. Is there a common used formula?
Just multiply the lengths of the sides of the rectangle, which are the differences between the coordinates of the two vectors:
(p2.X - p1.X) * (p2.Y - p1.Y)
Related
I'm trying to find the cursor position related to the red line in the image below.
I tried these topics:
Using atan2 to find angle between two vectors
And How to calculate the angle between a line and the horizontal axis? but using
Math.Atan2
But there is a problem, P1 and P2 have not same values if I use these methods.
Is there any method to get any position of any points on a UIElement (e.g. Ellipse) using the red vector such as every point with the same angle (here P1 and P2) has the same value ?
Yes, and atan2 is perfectly the needed method. We can use cross- and dot-product to achieve result:
bx = redline_end.x - center.x
by = redline_end.y - center.y
// here bx=0 and by=75
px = p1.x - center.x
py = p1.y - center.y
angle = atan2(px * by - py * bx, px * bx + py * by) //and similar for P2
I have been scratching my head on this for quite a while now. Guess I should have paid more attention in the trigonometry math classes when I was younger but here we go:
I have an angle and a point. I then want to put a second point in the direction of the angle, 200 units away from the first point. I use Atan2 to get the angle, then cos and sin to get the third point. But... I think something goes wrong when calculating the Sin for p3.Y.
EDIT: To clarify, I removed p2 and used the angle directly:
PointF p1 = new PointF(20, 20);
double angle = 1.3034851559678624f;
//Create a new PointF in the same direction, 200 pixels away from p1
//{ X = 199,9482, Y = 4,549629 }
PointF p3 = new PointF
{
X = (float)(Math.Cos(Math.PI * angle / 180.0) * 200),
Y = (float)(Math.Sin(Math.PI * angle / 180.0) * 200)
};
//This is where I would expect 1.3034851559678624 as the first angle
//but I get -4.9073849244837184
double angle2 = Math.Atan2(p3.Y - p1.Y, p3.X - p1.X) * 180 / Math.PI;
Here is a visual representation of the values above. The green line is the first angle.
The problem with your current code is that you don't calculate p3 relative to p1. You need to add p1.X and p1.Y to the coordinates of p3:
PointF p3 = new PointF
{
X = p1.X + (float)(Math.Cos(Math.PI * angle / 180.0) * 200),
Y = p1.Y + (float)(Math.Sin(Math.PI * angle / 180.0) * 200)
};
Well if p3 is supposed to be on the line p1-p2 you don't need to use any trigonometry at all. You can find the coordinates of p3 directly from those of p1 and p2. Suppose the distance between p1 and p2 is 1000 units. Then the location of p3, 200 units from p1 is:
{p1.x+(p2.x-p1.x)*(200/1000),p1.y+(p2.y-p1.y)*(200/1000)}
If the distance between the two points is not 1000 (which of course it won't be), replace that value by the Euclidean Distance between them.
If you still want the slope of the line you calculate the ratio
(p2.y-p1.y)/(p2.x-p1.x)
which gives you the slope as a single number, where 1 represents the line which passes through the origin at a +45deg angle. A little fiddling around will turn the slope into the angle, be careful when the line is vertical, ie where the denominator of the ratio is 0.
You did not have to use atan to get the angle and then calc sin/cos.
You can get sin and cos direct from coordinates of points.
cos = (p2.x - p1.x)/length
sin = (p2.y - p1.y)/length
http://en.wikipedia.org/wiki/Line_%28geometry%29
I have an application for drawing and editing vector graphics in WinForms
I have images, rectangles, ellipses, regions etc. and I know how to resize them by mouse move. But I don't know how to rotate them by mouse move.
I draw objects into Graphics.
I've tried this, but it didn't work.
g.TranslateTransform((float)(this.Rectangle.X + this.Rectangle.Width / 2), (float)(this.Rectangle.Y + this.Rectangle.Height / 2));
g.RotateTransform(this.Rotation);
g.TranslateTransform(-(float)(this.Rectangle.X + this.Rectangle.Width / 2), -(float)(this.Rectangle.Y + this.Rectangle.Height / 2));
//g.TranslateTransform(-(float)(rect.X + rect.Width / 2), -(float)(rect.Y + rect.Height / 2));
g.DrawImage(img, rect);
g.ResetTransform();
This didn't work, because I don't know how to find corners of objects in new (rotated) position, so I'm not able to resize that...
You need to apply high school trigonometry. There are lots of articles if you google "graphics.drawimage rotation"
But to start with, you should NOT be transforming the Graphics object itself. You are just looking to get the new bounding box of your image. To do this:
Take the bounding box of the image centered on the origin. Remember this is defined as three points for the benefit of DrawImage(Image, Point[])
Point[] boundingBox = { new Point(-width /2, -height/2),
new Point(width/2, -height/2),
new Point(-width/2, height/2) };
Use trig to rotate it. Feed each point through the following function:
Point rotatePointAroundOrigin(Point point, float angleInDegrees) {
float angle = angleInDegrees * Math.PI/180; // get angle in radians
return new Point( point.X * Math.Cos(angle) - point.Y * Math.Sin(angle),
point.X * Math.Sin(angle) + point.Y * Math.Cos(angle));
}
Translate the boundind box to where it has to go. Add the width/2 and height/2 to each of its points, plus whatever extra amount you want.
Call DrawImage(image, boundingBox)
I have four points which form a rectangle, and I am allowing the user to move any point and to rotate the rectangle by an angle (which rotates each point around the center point). It stays in near-perfect Rectangle shape (as far as PointF precision allows). Here's an example of my "rectangle" drawn from four points:
However, I need to be able to get the width and height between the points. This is easy when the rectangle is not rotated, but once I rotate it my math returns the width and height shown by the red outline here:
Assuming I know the order of the points (clockwise from top-left for example), how do I retrieve the width and the height of the rectangle they represent?
If by "width" and "height", you just mean the edge lengths, and you have your 4 PointF structures in a list or array, you can do:
double width = Math.Sqrt( Math.Pow(point[1].X - point[0].X, 2) + Math.Pow(point[1].Y - point[0].Y, 2));
double height = Math.Sqrt( Math.Pow(point[2].X - point[1].X, 2) + Math.Pow(point[2].Y - point[1].Y, 2));
Just use the algorithm for the distance between two points.
If you have points A, B, C, D, you will get two distances.
sqrt((Bx-Ax)^2 + (By-Ay)^2) will be equal to sqrt((Dx-Cx)^2 + (Dy-Cy)^2)
sqrt((Cx-Bx)^2 + (Cy-By)^2) will be equal to sqrt((Ax-Dx)^2 + (Ay-Dy)^2)
Pick one to be your width and one to be your height.
Let's say top-most corner is A. Then name other edges anti-clockwise as ABCD
width of rectangle = distance between A and B
height of rectangle = distance between B and C
Formula to find distance between two points say A(x1,y1) and B(x2,y2) is:
d = sqrt( (x2 - x1)^2 + ( y2 - y1)^2 )
where d is distance.
I want to visually join two circles that are overlapping so that
becomes
I already have methods for partial circles, but now I need to know how large the overlapping angle for earch circle is, and I don't know how to do that.
Anyone got an Idea?
Phi= ArcTan[ Sqrt[4 * R^2 - d^2] /d ]
HTH!
Edit
For two different radii:
Simplifying a little:
Phi= ArcTan[Sqrt[-d^4 -(R1^2 - R2^2)^2 + 2*d^2*(R1^2 + R2^2)]/(d^2 +R1^2 -R2^2)]
Edit
If you want the angle viewed from the other circle center, just exchange R1 by R2 in the last equation.
Here is a sample implementation in Mathematica:
f[center1_, d_, R1_, R2_] := Module[{Phi, Theta},
Phi= ArcTan[Sqrt[-d^4-(R1^2-R2^2)^2 + 2*d^2*(R1^2 + R2^2)]/(d^2 +R1^2 -R2^2)]
Theta=ArcTan[Sqrt[-d^4-(R1^2-R2^2)^2 + 2*d^2*(R1^2 + R2^2)]/(d^2 -R1^2 +R2^2)]
{Circle[{center1, 0}, R1, {2 Pi - Phi, Phi}],
Circle[{d, 0}, R2, {Pi - Theta, -Pi + Theta}]}
];
Graphics[f[0, 1.5, 1, 1]]
Graphics[f[0, 1.5, 1, 3/4]]
And...
ImageMultiply[
Binarize#FillingTransform[#],
ImageResize[Import#
"http://i305.photobucket.com/albums/nn235/greeneyedgirlox/blondebabybunny.jpg",
ImageDimensions##]] &#
Rasterize#Graphics[f[0, 1.5, 1, 1], Background -> Black]
:)
Now this will work 100% for you even the figure is ellipse and any number of figures
private void Form1_Paint(object sender, PaintEventArgs e)
{
Pen p = new Pen(Color.Red, 2);
Rectangle Fig1 = new Rectangle(50, 50, 100, 50); //dimensions of Fig1
Rectangle Fig2 = new Rectangle(100, 50, 100, 50); //dimensions of Fig2
. . .
DrawFigure(e.Graphics, p, Fig1);
DrawFigure(e.Graphics, p, Fig2);
. . .
//remember to call FillFigure after drawing all figures.
FillFigure(e.Graphics, p, Fig1);
FillFigure(e.Graphics, p, Fig2);
. . .
}
private void DrawFigure(Graphics g, Pen p, Rectangle r)
{
g.DrawEllipse(p, r.X, r.Y, r.Width, r.Height);
}
private void FillFigure(Graphics g, Pen p, Rectangle r)
{
g.FillEllipse(new SolidBrush(this.BackColor), r.X + p.Width, r.Y + p.Width, r.Width - 2 * +p.Width, r.Height - 2 * +p.Width); //Adjusting Color so that it will leave border and fill
}
Don't have the time to solve it right now. But I'll give you what you need to work it out:
http://en.wikipedia.org/wiki/Triangle#The_sine.2C_cosine_and_tangent_rules
In the picture on wikipedia you see the triangle A,B,C. Let A be the center of the left circle, B the center of the right circle. And AC the radius of the left circle and BC the radius of the right circle.
Then point C would be the top intersection point. The corner in A, α, is half the angle in the left circle.The corner in b, β, half the angle in the right circle. These are the angles you need, right?
Wikipedia explains further: 'If the lengths of all three sides of any triangle are known the three angles can be calculated.'
Pseudocode:
a=radius_a
b=radius_b
c=b_x - a_x
alpha=arccos((b^2 + c^2 - a^2) / (2*b*c)) //from wikipedia
left_angle=2*alpha
Good luck :)