I have a canvas with objects (product images, e.g. an apple) and I want elements to circle around them (icons, e.g. warnings about allegenes).
I've tried to add an Ellipse and now I want to align the icons on the border of the Ellipse. Is that possible? Hope you can help - thanks a lot!
You don't need an ellipse, you just need to do the maths yourself.
You know how many elements you want to order so you calculate the positions using trigonometry and then set the position with:
element.SetValue(Canvas.TopProperty, pos.Y);
element.SetValue(Canvas.LeftProperty, pos.X);
To calculate the positions, first calculate the angle between each object in the circle.
double radius = 100; // Or what ever your radius is
double angle = 360.0 / numItems * Math.PI / 180.0;
var centre = //position of product image
pos.X = centre.X + Math.Cos(angle * itemNumber) * radius;
pos.Y = centre.Y + Math.Sin(angle * itemNumber) * radius;
so you'll need a list or array of your elements and loop over that.
Related
The problem I want to solve is:
Calculate the intersection of the ball and the circle with the following information.
Known information about the circle:
1. The coordinates of the center A are known, and the center A is on the spherical surface.
2. The radius ra of the circle A is known.
3. Know the coordinates of a point B on the circle
Known information about the ball:
1. The coordinates of the spherical center B of the known ball.
2. The radius of the known ball rb.
Picture is as follows
Icon
With the above information, I hope to calculate the coordinates of the intersection point.
Then put the algorithm into C# so that the associated points on the plane can be placed on the sphere and the distance between these points does not change.
If the above method works, I can place many points equidistant from A on the sphere, and after placement, the distance between these points and A is unchanged.
I tried before:
1. Solve the problem with simultaneous equations, but unfortunately the final result is not available.
2. Try to get the result by the intersection of two circles, but the circle and the circle are both in a plane relationship, only the coordinates of x, y can be obtained, and the coordinates of z cannot be obtained.
I successfully put some points on the sphere through the following code, but the distance between the points and the points has changed, and the more the number of points, the more obvious this change, I don't want their distance to change, so I came up with it. Determine the position of these points by intersecting the circle with the ball。
The parameter (List atoms ) stores some points on the plane, and (double r) is the radius of the ball. By this method, the point on the plane will be "sticked" to the sphere.
/// <summary>
/// Stick the atom to the sphere
/// </summary>
private void BendAtom(List <Atom> atoms,double r)
{
double L = 2d * Math.PI * r;
double w = L;// * 2d;
double h = L / 2d;
for (int i = 0; i < atoms.Count; i++)
{
atoms[i].Point.x = (float)((360 / w) * atoms[i].Point.x - 180);
atoms[i].Point.y = (float)((180 / h) * atoms[i].Point.y - 90);
}
for (int i = 0; i < atoms.Count; i++)
{
double lat = atoms[i].Point.x;
double lng = atoms[i].Point.y;
double phi = ((90d - lat) * Math.PI) / 180d;
double theta = ((180 - lng) * Math.PI) / 180d;
double x = r * Math.Sin(phi) * Math.Cos(theta);
double y = r * Math.Cos(phi);
double z = r * Math.Sin(phi) * Math.Sin(theta);
atoms[i].Point.x = (float)x;
atoms[i].Point.y = (float)y;
atoms[i].Point.z = (float)z;
}
}
I hope that after the point is "posted" on the ball, the distance of the points does not change, but as a result, they change, and the more the number of points, the greater the change.
My math level is limited. If you have a better way to solve this problem, thank you very much and thank you for your help.
The result of the above code
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
It's been 10 years since I did any math like this... I am programming a game in 2D and moving a player around. As I move the player around I am trying to calculate the point on a circle 200 pixels away from the player position given a positive OR negative angle(degree) between -360 to 360. The screen is 1280x720 with 0,0 being the center point of the screen. The player moves around this entire Cartesian coordinate system. The point I am trying trying to find can be off screen.
I tried the formulas on article Find the point with radius and angle but I don't believe I am understanding what "Angle" is because I am getting weird results when I pass Angle as -360 to 360 into a Cos(angle) or Sin(angle).
So for example I have...
1280x720 on a Cartesian plane
Center Point (the position of player):
let x = a number between minimum -640 to maximum 640
let y = a number between minimum -360 to maximum 360
Radius of Circle around the player: let r always = 200
Angle: let a = a number given between -360 to 360 (allow negative to point downward or positive to point upward so -10 and 350 would give same answer)
What is the formula to return X on the circle?
What is the formula to return Y on the circle?
The simple equations from your link give the X and Y coordinates of the point on the circle relative to the center of the circle.
X = r * cosine(angle)
Y = r * sine(angle)
This tells you how far the point is offset from the center of the circle. Since you have the coordinates of the center (Cx, Cy), simply add the calculated offset.
The coordinates of the point on the circle are:
X = Cx + (r * cosine(angle))
Y = Cy + (r * sine(angle))
You should post the code you are using. That would help identify the problem exactly.
However, since you mentioned measuring your angle in terms of -360 to 360, you are probably using the incorrect units for your math library. Most implementations of trigonometry functions use radians for their input. And if you use degrees instead...your answers will be weirdly wrong.
x_oncircle = x_origin + 200 * cos (degrees * pi / 180)
y_oncircle = y_origin + 200 * sin (degrees * pi / 180)
Note that you might also run into circumstance where the quadrant is not what you'd expect. This can fixed by carefully selecting where angle zero is, or by manually checking the quadrant you expect and applying your own signs to the result values.
I highly suggest using matrices for this type of manipulations. It is the most generic approach, see example below:
// The center point of rotation
var centerPoint = new Point(0, 0);
// Factory method creating the matrix
var matrix = new RotateTransform(angleInDegrees, centerPoint.X, centerPoint.Y).Value;
// The point to rotate
var point = new Point(100, 0);
// Applying the transform that results in a rotated point
Point rotated = Point.Multiply(point, matrix);
Side note, the convention is to measure the angle counter clockwise starting form (positive) X-axis
I am getting weird results when I pass Angle as -360 to 360 into a Cos(angle) or Sin(angle).
I think the reason your attempt did not work is that you were passing angles in degrees. The sin and cos trigonometric functions expect angles expressed in radians, so the numbers should be from 0 to 2*M_PI. For d degrees you pass M_PI*d/180.0. M_PI is a constant defined in math.h header.
I also needed this to form the movement of the hands of a clock in code. I tried several formulas but they didn't work, so this is what I came up with:
motion - clockwise
points - every 6 degrees (because 360 degrees divided by 60 minuites is 6 degrees)
hand length - 65 pixels
center - x=75,y=75
So the formula would be
x=Cx+(r*cos(d/(180/PI))
y=Cy+(r*sin(d/(180/PI))
where x and y are the points on the circumference of a circle, Cx and Cy are the x,y coordinates of the center, r is the radius, and d is the amount of degrees.
Here is the c# implementation. The method will return the circular points which takes radius, center and angle interval as parameter. Angle is passed as Radian.
public static List<PointF> getCircularPoints(double radius, PointF center, double angleInterval)
{
List<PointF> points = new List<PointF>();
for (double interval = angleInterval; interval < 2 * Math.PI; interval += angleInterval)
{
double X = center.X + (radius * Math.Cos(interval));
double Y = center.Y + (radius * Math.Sin(interval));
points.Add(new PointF((float)X, (float)Y));
}
return points;
}
and the calling example:
List<PointF> LEPoints = getCircularPoints(10.0f, new PointF(100.0f, 100.0f), Math.PI / 6.0f);
The answer should be exactly opposite.
X = Xc + rSin(angle)
Y = Yc + rCos(angle)
where Xc and Yc are circle's center coordinates and r is the radius.
Recommend:
public static Vector3 RotatePointAroundPivot(Vector3 point, Vector3 pivot, Vector3 angles)
{
return Quaternion.Euler(angles) * (point - pivot) + pivot;
}
You can use this:
Equation of circle
where
(x-k)2+(y-v)2=R2
where k and v is constant and R is radius
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 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)