Convert value to Angle with maximum value - c#

I made a speedometer control My controller has a property called Angle that changes the shape of my speedometer (180 for Complete Circul, and so on...)
With the help of a converter, I can move the speedometer correctly
// values[0] = Angle
// values[1] = Value
var startAngle = System.Convert.ToDouble(values[0]) * -1;
var endAngle = startAngle + (((double)values[1]) * 2);
return endAngle;
Now I want to have a property called Maximum, And if the user sets it to 50, even if my circle is 360 degrees, the whole circle will be full with 50 values.
I used the following code but unfortunately it does not work properly
return value * angle / maximum;
also this is my arc
<x:Arc StartAngle="{Binding Angle, RelativeSource={RelativeSource Mode=TemplatedParent}, Converter={StaticResource Positive2Nagative}}" EndAngle="{Binding Angle, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
UPDATE:
this code:
//a = s * A / max
value * angle / maximum;
Compile to this:
<loc:speedometer Angle="120" MaximumValue="50" Value="{Binding ElementName=sld, Path=Value}"
/>
UPDATE 2:
i fixed problem with this code
return ((value * angle / maximumValue * 2) - angle);

You're using a very strange notation for this.
Let's call a change in value of 1 a step. So 50 km/h maximum means 50 steps.
You want 50 steps between the start and end.
Your first task is to work out angle per step.
For that you need to know the angle the entire arc will go through.
If the start is always over there on the left of the vertical line then it's always negative.
Hence you want -1 * start for the left number of degrees offset from vertical.
The right is easy it's just end.
Hence (-1 * start) + end = totalArc degrees
That gives you how many degrees the 0 to max covers.
Let's call the thing you're representing speed. Because angle is a very very bad name for a variable in a calculation which is all about angles.
totalArc / maximum gives the value in degrees of each step in our speed.
Hence you want (totalArc / maximum) * speed.
That gives you the angle between the start and where the speed indicator should go to.
You will then have to work out what that means in terms of your display.
I would suggest the simplest is to rotatetransform whatever does the red stuff so 0 angle matches the start. Maybe you're already doing that though.

I think you are looking for the following:
Given an angle a, the equivalent value s, considering A degrees repesents the maximum value max, is:
s = a * max / A
Or what is pobably more useful, the angle a which reprenets a given speed s in a A degree speedometer with a maximum speed max is:
a = s * A / max
That said, I'm not really sure how your speedometer works. At first you talk about a 180º gauge and then you start talking about a full 360º one. Either way, A is either 180 or 360.

Related

I am trying to code Canny edge detection in C#

I am trying to code Canny edge detection in C#. I am confused about finding the Direction of the edge. I know The Direction is the angle between the gradient vector and the x-axis. When finding the gradient vector's Direction (D), you do inverse tan of the y/x ratio.
I understand that part. The part that I am lost at is some examples online seem to add PI out of nowhere, and I do not understand. So is it :
` double angle = X/ Y;
double radians = angle * (180/Math.PI);
Angle = Math.Tan(radians) + Math.PI;`
or this:
double angle = X/ Y;
double radians = angle * (180/Math.PI);
Angle = Math.Tan(radians);
I have also seen :
orientation[index] = Math.Atan2(dy, dx) + Math.PI;
but this is not even inverse tan or is it ?
Both your first examples don't make any sense. X / Y is surely not an angle but the tangens of an angle.
To get the angle from the tangens you must use the one of the two inverse functions Math.Atan or Math.Atan2.
Always prefer Math.Atan2 over Math.Atan if you have got both components (X and Y) of the direction vector because Math.Atan2 returns an unambiguous angle in the range for -Pi to +Pi, while Math.Tan only gives you a result in the range form -Pi/2 to +Pi/2. Then you have to decide if in a certain case you have to add or subtract Pi (ATan doesn't "know" whether the angle is in the first or in the third quadrant if the result is positive or whether it is in the second or fourth quadrant if the result is negative).
Try to learn how to work with trigonometric functions and when you understand how to apply them and the corresponding inverse trigonometric functions come back to your programme.
And read the Microsoft documentation concerning the trigonometric functions.

Calculating the speed a sprite changes size based on the distance it needs to travel and speed it is travelling

I am doing some sprite scaling and have a sprite starting at scale 0.2 on the x+y axis it travels at a constant speed (10) between its start point and end point increasing in scale as it travels.
I need it to scale evenly across that distance so that when it reaches its end point it is at its final scale (0.2 - 1).
Now because the distance changes based on where it spawns the time that it takes to scale in size must also change so that it can scale evenly across the distance, what I need is the calculation to work out the 'scale speed' based on the distance it is traveling and speed the item is moving.
I'm getting the distance between the two points with Vector3.Distance
distance = Vector2.Distance(transform.position, centerScreen);
This scales the object over time
if (transform.localScale.x < 1 && transform.localScale.y < 1)
{
transform.localScale = new Vector3(transform.localScale.x + scaleSpeed * Time.deltaTime, transform.localScale.y + scaleSpeed * Time.deltaTime, 1);
}
and the object moves at a speed of 10
My question is, How do I calculate the scale speed based on the distance and speed the object is traveling?
In Unity, there is a function called InverseLerp, which creates a point from 0 - 1 based on how far the value v is between the values a and b. It is the opposite of the Lerp function. (https://docs.unity3d.com/ScriptReference/Mathf.InverseLerp.html).
Here is example code for your situation: float sizeVal = Mathf.InverseLerp(0, yourSetDistance, distance) * 0.8f + 0.2f;
This changes the range of the inverse lerp to between 0.2 and 1. Use the sizeVal in the size vector. If this isn't what you wanted, please explain in more detail or restate your question.

How to I calculate clock-angle on x-y axis using C#?

We have a monitoring application that can monitor in intervals like 5 minutes, 15 minutes, 1 hour, etc. That's represented on the x-axis; The y-axis is also scalable and have values like 1.2345 - 1.5567 or can be switched to values like 26000 - 30000, etc.
Once the scale is set on the x and y axis, they don't dynamically change without a whole complete data refresh.
That being said, we only want certain people to be notified depending on the clock angle, of say, the last 5 intervals along the y axis.
The clock angles will never go counter-clockwise past 0/12; likewise, they'll never go past 6 clockwise.
I know the 3 o'clock angle is obvious when the x axis value is exactly the same as it was 5 intervals ago.
But how does one even start coding for everything in between? I can get the differences in x values easily (in the example graphic below, it's 0.3), and the difference in the y-axis in the below graphic is 4.
So with trigonometry that's opposite over adjacent, which means a tan operation I believe? If so, 0.3/5 doesn't seem to yield any values that seem like a clock angle.
Since I can't get any farther than that, I have no idea how it would be coded in C# other than calculating the differences.
Any help would be greatly appreciated!
You should be using atan2 (wiki , docs)
From the wiki:
atan2(y, x) returns the angle θ between the ray to the point (x, y) and the positive x axis, confined to (−π, π]
Note that the result is in radians, so you need to convert it if you want degrees
As stated, one radian is equal to 180/π degrees. Thus, to convert from radians to degrees, multiply by 180/π.
A couple of things here. First I think what you are asking for is the angle φ below, given two data points (x1,y1) and (x2,y2).
The problem here is that the angle is measuring the indicated triangle in pixels and not in x, y units.
So it is incorrect to do var φ = Math.Atan( (y2-y1)/(x2-x1) ); because the x and y axis have different units and angles are always dimensionless.
What additional information is needed, is the size of the graph area in pixels, as well as the range of values. Alternatively, the scaling gx,gy in pixels/unit for both axis.
For example, if the x-axis needs 45 pixels to span 1 grid of 1 hour (60 minutes) then te scaling is double gx = 45/60.0, and if the y-axis needs also 45 pixels to span 1 grid of 0.1 value then double gy = 45/0.1.
Then you can use this to calculate the sides of the triangle in pixels before calculating the angle
var adjacent = gx*(x2-x1); // convert x-axis units to pixels
var opposing = gy*(y2-y1); // convert y-axis units to pixels
var φ = Math.Atan(addjacent/opposing) * (180/Math.PI);
The last part calculates the angle φ and converts it from radians to degrees.

Find Angle Between Two Vectors

I have read some of the duplicate answers about angle between two vectors, but I'm still stuck with my problem. I have two vectors and I want that the angle between them to always be 90 degrees. To achieve that I need to find the angle between them, so that I can subtract or add the correct amount of degrees so that the angle between them always is 90 degrees.
The picture illustrates a sprite and two vectors. How do I find the angle A between them two? I have tried to use this code to get the angle between two vectors, but I must have missed something out, because I don't get the correct results:
public float GetAngleBetween (Vector2 A, Vector2 B)
{
float DotProd = Vector2.Dot (A, B);
float Length = A.Length () * B.Length ();
return (float)MathHelper.ToDegrees ((float)Math.Acos (DotProd/Length));
}
Any input is welcome and thank you in advance for any answers.
The actual angle in radians is
Math.ACos(Vector2.Dot(a, b));
Make sure that a and b are normalized vectors or the results can get pretty weird.
I think you may be looking for the Vector2.Dot method which is used to calculate the product of two vectors, and can be used for angle calculations.
For example:
// the angle between the two vectors is less than 90 degrees.
Vector2.Dot(vector1.Normalize(), vector2.Normalize()) > 0
// the angle between the two vectors is more than 90 degrees.
Vector2.Dot(vector1.Normalize(), vector2.Normalize()) < 0
// the angle between the two vectors is 90 degrees; that is, the vectors are orthogonal.
Vector2.Dot(vector1.Normalize(), vector2.Normalize()) == 0
// the angle between the two vectors is 0 degrees; that is, the vectors point in the same direction and are parallel.
Vector2.Dot(vector1.Normalize(), vector2.Normalize()) == 1
// the angle between the two vectors is 180 degrees; that is, the vectors point in opposite directions and are parallel.
Vector2.Dot(vector1.Normalize(), vector2.Normalize()) == -1
Is this what you're looking for, or do you need the exact angle?
If I understand your question diagram and comments, the Dot product and Acos are not the only bits of info you need. You also need to account for when the sprite is not located at (0,0).
float angleInRadians = (float) Math.Acos(Vector2.Dot(Vector2.Normalize(vector1 - spritePosition), Vector2.Normalize(vector2 - spritePosition)));
int angleInDegrees = MathHelper.ToDegrees(angleInRadians);

Math.sin - flush out of ideas

I'm trying math.sin and math.cos to do a moving edge line in my program. I get all the math and it seems to add up properly (I use mouse location from a click and a moving mouse variable to determine the draw areas. I then use a width value to give it the edge offset.
I use math.cos to find how far in to offset the points in the X and Y locations. While doing this, the value of cos(Angle) seems to go absolutely crazy, from +1 to -1. Here's an example.
Angle = 29.153788462442
Cos as per window calculator = 0.8733152733324487151754721490934
Cos as per Math.Cos(Angle) = -0.637571130025255
I tried converting Angle to a float and an int in case the decimal place was causing it an issue, no avail.
This is the code I am using to bring up those answers.
lblInOpts.Text = Math.Cos(Angle).ToString() + " " + Angle.ToString();
The document is in degrees, switched over from radians and being use the same way MSDN seems to suggest.
You need to convert from degrees to radians:
Math.Cos(Angle * Math.PI / 180.0)
You are passing the angle in degrees, Math.Cos expects an angle in radians
The result from the Windows Calculator is the cosine of the angle interpreted as degrees.
The result from your C# code is the cosine of the angle interpreted as radians, which is the equivalent of 1670.389... degrees.
To convert degrees to radians in your code, use
public static double ToRadians(double x) {
return x * Math.PI / 180.0;
}
-0.637571130025255 is the cosine of 29.153788462442 radians (1670.38903571 degrees). Check the documentation of Math.Cos() - does it take an argument in radians or degrees?

Categories

Resources