Calculating two numbers - math

Sorry for asking this question, I didn't pay attention in school...
Say I have two numbers: 3 and 7
I'd like to create a bar that shows the percentage of both numbers (out of 100%)
in other words, calculate those numbers, so the bar shows:
IIIXXXXXXX
I hope I make sense.. thanks in advance.

I think you mean you want a bar to display 3 and 7 as relative values, each taking up an appropriate percentage of the whole
IIIXXXXXXX
The calculation is simple:
var total = 3 + 7;
var percentA = 3 / total; // 30%
var percentB = 7 / total; // 70%
The width of each component is the total bar width multiplied by the selected value and divided by the sum of values.
So if the bar should be, say, 100px, you would calculate the width of the two components like
var widthA = 100 * ( A / (A+B) );
var widthB = 100 * ( B / (A+B) );
or 100 * ( 3 / (3+7) ) => 100 * (3/10) => 30, and 70.

If your asking for a physical representation of the numbers percentage out of 100 I would start by getting the percent:
int number = 3; //or 7
int percent = number/100;
Then I would have a sprite 1 pixel big and scale it based on percent, for example:
mybarsprite.scale = percent*100;
Then you could add a background image to create the bar and have that be 100 pixels. Add both sprites at the same position, the background sprite at a lower z level add you have a bar affect.

Here's one way (taken from a progress bar plugin):
This is JavaScript, but the language is of course irrelevant.
var max = 250; // the total amount representing 100%
var current = $obj.val().length; // the length we are measuring
// important: current / max * 100
// use min() to ensure that the result isn't greater than 100 due to rounding
var ratio = Math.min( ( ( current / max ) * 100 ), 100 );
The key piece is dividing the current amount by the total amount, where the total amount (whatever it may be) represents 100%. That division operation should yield a value less than 1. To convert that to a 1-100 percentage, multiply by 100.
In my above example, if current = 125, and max = 250, then we have 125 / 250 = 0.5. Multiplying 0.5 * 100 gives 50. 125 is 50% of 250.
If you wanted to get both percentages, you could simply subtract the first result from 100.
Here is a complete working example of a HTML/CSS/jQuery progress bar for managing the maxlength of a textbox: http://jsfiddle.net/QfZPt/1/

Related

Distance formula calculation with ordinal positions

I'm following one of BQ courses from Google's Skill Boost program. Using a dataset with football (soccer) stats, they're calculating the impact of shot distance on the likelihood of scoring a goal.
I don't quite get how the shot distance is calculated in this part:
SQRT(
POW(
(100 - positions[ORDINAL(1)].x) * 105/100,
2) +
POW(
(50 - positions[ORDINAL(1)].y) * 68/100,
2)
) AS shotDistance
I know the distance formula is used (d=√((x_2-x_1)²+(y_2-y_1)²)) but:
why use ORDINAL(1)? How does it work in this example?
why detract first from 100 and then from 50?
For the record, positions is a repeated field, with x,y int64 nested underneath. x and y have values between 1 and 100, demonstrating the % of the pitch where an event (e.g. a pass) was initiated or terminated.
The whole code is as follows:
WITH
Shots AS
(
SELECT
*,
/* 101 is known Tag for 'goals' from goals table */
(101 IN UNNEST(tags.id)) AS isGoal,
/* Translate 0-100 (x,y) coordinate-based distances to absolute positions
using "average" field dimensions of 105x68 before combining in 2D dist calc */
SQRT(
POW(
(100 - positions[ORDINAL(1)].x) * 105/100,
2) +
POW(
(50 - positions[ORDINAL(1)].y) * 68/100,
2)
) AS shotDistance
FROM
`soccer.events`
WHERE
/* Includes both "open play" & free kick shots (including penalties) */
eventName = 'Shot' OR
(eventName = 'Free Kick' AND subEventName IN ('Free kick shot', 'Penalty'))
)
SELECT
ROUND(shotDistance, 0) AS ShotDistRound0,
COUNT(*) AS numShots,
SUM(IF(isGoal, 1, 0)) AS numGoals,
AVG(IF(isGoal, 1, 0)) AS goalPct
FROM
Shots
WHERE
shotDistance <= 50
GROUP BY
ShotDistRound0
ORDER BY
ShotDistRound0
Thanks
why use ORDINAL(1)? How does it work in this example?
As per the BigQuery array documentation
To access elements from the arrays in this column, you must specify
which type of indexing you want to use: either OFFSET, for zero-based
indexes, or ORDINAL, for one-based indexes.
So taking a sample array to access the first element you would do the following:
array = [7, 5, 8]
array[OFFSET(0)] = 7
array[ORDINAL(1)] = 7
So in this example it is used to get the coordinates of where the shot took place (which in this data is the first set of x,y coordinates).
why detract first from 100 and then from 50?
The difference between 100 and 50 represents the position of the goals on the field.
So the end point of the shot is assumed to be in the middle of the goals which along the x axis from 0 - 100, 100 is the endline of the field, while on the y axis the goals is in the middle of the field equal distance from each sideline, so therefore 50 is the middle point of the goals.

How to increase two values to match a ratio of 17:8 in Google Sheets

If I have two values with a calculated ratio for example:
Value 1 = 5000
Value 2 = 100
Calculated Ratio = 50:1
How do I distribute a value of 500 between value 1 and value 2 so I can get to a 17:8 ratio or as close as possible to 17:8 ratio without decreasing any of the values.
I tried adding all the values and then splitting them into 17:8 ratio but this will in some cases decrease one value to get to another.
Incorrect example as value one has decreased from its original value of 5000:
Value 1 = 3808
Value 2 = 1792
Calculated Ratio = 17:8
You have two equations and two unknowns. The two unknowns are the adjustment values a and b such as the ratio below is known (17/8)
aspect = (value1+a)/(value2+b)
but the combined value of the adjustments has to be a fixed amount (500)
sum = a + b
Soution 1
The solution if the aspect ratio is float type value 17/8=2.125, then the solution is
a = (aspect*(value2+sum) - value1)/(aspect+1)
b = (value1 - aspect*value2+sum)/(aspect+1)
In your case I get a = -1192 and b = 1692 for
value1 + a = 3808
value2 + b = 1792
The ratio 3808/1792 = 17/8 and the sum (1692) + (-1192) = 500
Solution 2
The solution if the aspect ratio is a rational number aspect = num/den is:
a = (num*(value2+sum) - den*value1)/(den + num)
b = (den*(value1+sum) - num*value2)/(den + num)
and again the sample calculation is (num=17, den=8)
a = (17*(100+500) - 8*5000)/(8 + 17) = -1192
b = (8*(5000+500) - 17*100)/(8 + 17) = +1692
Adjustments
If you constrain a>=0 and a<=sum as well as b>=0 and b<=sum then you would not reach the aspect ratio.
You can do this will the following code adjusting a and b
if (a<0)
{
a = 0;
b = sum;
}
else if(b<0)
{
a = sum;
b = 0;
}
Graph
Graphically this problem is a follows:
The blue line is the combination of Value 1 and Value 2 that have the aspect ratio desired.
The pink dot is the starting value (5000,100).
The slanted lines are the adjusted Value 1 and Value 2 for a given sum amount to adjust by. I have included lines for 500, 1000, 2000, and 4000.
Where the slanted lines intersect the blue line is the ideal solution. The solution
The red dot is where the above solution(s) lead you before adjustments. After adjusting for non-negative a and b you will end up at the black dot.
In google sheets, you need some extra columns to implement the above
This is not specific to sheets and is a basic math cross multiplication problem
So, 17 is to 8 as 500 is to x
17/8 = 500/x
Cross multiplying give us
8 * 500 = 4,000
17 * x = 17x
solving for x
x = 4,000/17
x = 235.29
This was a really fun problem thanks for sharing it. Solution
Spoiler alert! The integers are 5302 and 298 with a final ratio of 17.79 which can be found in row 303.
Edit 1:
I misunderstood the question. A 17:8 ratio can be simplified to 2.125:1. The spreadsheet lists all of the possible combinations, where the smallest ratio is 8.35:1. Thus it doesn't seem there is a solution close to a 17:8 ratio.

Mathematical game wondering

Imagine an arm that is 50 px long.
It is placed at 100,100.
The rotation center is at 100, 100.
The arm rotates all the time.
On the arm there is a hook that travels back and forth the full distance of the arm.
My variables:
X = 100;
Y = 100;
RotationAngel = 120; // Loops up to 360.
HookDistanceFromCenter = 25; // Goes 0 -> 50 -> 0 by a loop.
How do I get the position (x,y) of the hook?
From your specific data:
x = 100 - HookDistanceFromCenter * cos(180 - RotationAngle)
y = 100 + HookDistanceFromCenter * sin(180 - RotationAngle)
but it changes depending on which quadrant you are in. This is basic trigonometry. You should be able to use the info here: http://en.wikipedia.org/wiki/Unit_circle except that the radius of your circle is HookDistanceFromCenter and you have to add your rotation center coordinates to the result to get the actual (x,y).

Math - Getting Maximum Proportionate Image Scale

I need an algorithm which will determine the maximum scale increase that is possible for an image.
The rules (size limitation of a BitmapData object for the Flash Player, but this is not a Flash question):
both the width and length of the image must be less than 8,191 pixels
the maximum number of pixels in the image can not exceed 16,777,215
therefore, as mentioned in the documentation:
if a BitmapData object is 8,191 pixels
wide, it can only be 2,048 pixels
high.
In my code, I first determine if any of these rules are broken and throw and error if they are. this lets me know that any image that is loaded and does not throw an error has scalability.
The image I'm using is 2514 width x 1029 height. This image will not throw an error since both width and height are less than 8,191 and it's pixel count, or width multiplied by height, is less than 16,777,215.
I identify as being right-brained and don't have much confidence in my math skills, but the following is what I've come up with to determine the maximum allowed scale for the image.
private static const MAX_BITMAP_MEASUREMENT:uint = 8191;
private static const MAX_BITMAP_PIXELS:uint = 16777215;
var imageWidth:uint = 2514;
var imageHeight:uint = 1029;
var roughScaleUp:Number = 1.0 / Math.max(imageWidth, imageHeight) * MAX_BITMAP_MEASUREMENT;
var scaleBack:Number = Math.max(Math.min(imageWidth, imageHeight) * roughScaleUp - MAX_BITMAP_PIXELS / MAX_BITMAP_MEASUREMENT, 0);
var maxScale:Number = 1.0 / (Math.max(imageWidth, imageHeight) + scaleBack) * MAX_BITMAP_MEASUREMENT;
This code outputs the maximum scale for my image as 2.145144435977516, but I tested it and there is still a lot of pixel space remaining, so it should be able to be scaled up more and I'm pretty sure my code is terribly wrong.
Any math wizards on here care to help out a lowly art school graduate? I'm fully ready to accept that there is probably a much more simplistic solution to this problem and I'm prepared for the lashings.
You have to multiply both the width and the height by a constant, and the scaled result of the multiplication should be less than 16777215.
So
a^2 * w * h == 16,777,215
Which yields, for your values of w and h
a = 2.5466520486244177 [= Sqrt(16,777,215 / (w*h)) ]
So , for your values for the new w and h, you get:
NewW = a * w = 6402.283250241786
NewH = a * h = 2620.5049580345258
... just round them down :)
Well, here is an ugly solution. I couldn't get the rounding quite right, so I brute forced over the 4 possibilities to get the optimal value. The code should be straightforward enough to understand:
from math import *
def opt_image(w, h):
aspect = w / h
if aspect >= 1:
v = min(sqrt(1677215 / aspect), 8191)
a, b = floor(aspect * v), floor(v)
area, nw, nh = max([ ( (a+x)*(b+y), (a+x), (b+y) ) for x in range(2) for y in range(2) if (a+x)*(b+y) < 1677215 ])
return nw, nh
a, b = opt_image(w, h)
return b, a
For your example with width 2514, height 1029; I got:
(1831.0, 916.0)

How do I determine whether a number is within a percentage of another number

I'm writing iPhone code that fuzzily recognizes whether a swiped line is straight-ish. I get the bearing of the two end points and compare it to 0, 90, 180 and 270 degrees with a tolerance of 10 degrees plus or minus. Right now I do it with a bunch of if blocks, which seems super clunky.
How to write a function that, given the bearing 0..360, the tolerance percentage (say 20% = (-10° to +10°)) and a straight angle like 90 degrees, returns whether the bearing is within the tolerance?
Update: I am, perhaps, being too specific. I think a nice, general function that determines whether a number is within a percentage of another number has utility in many areas.
For instance: Is the number swipeLength within 10% of maxSwipe? That would be useful.
BOOL isNumberWithinPercentOfNumber(float firstN, float percent, float secondN) {
// dunno how to calculate
}
BOOL result;
float swipeLength1 = 303;
float swipeLength2 = 310;
float tolerance = 10.0; // from -5% to 5%
float maxSwipe = 320.0;
result = isNumberWithinPercentOfNumber(swipeLength1, tolerance, maxSwipe);
// result = NO
result = isNumberWithinPercentOfNumber(swipeLength2, tolerance, maxSwipe);
// result = YES
Do you see what I'm getting at?
int AngularDistance (int angle, int targetAngle)
{
int diff = 0;
diff = abs(targetAngle - angle)
if (diff > 180) diff = 360 - diff;
return diff;
}
This should work for any two angles.
20% as a decimal is equal to 0.2. Just divide by 100.0 to get the decimal. Divide by 2.0 to get half of the acceptable range. (Combined into 200.0 divisor)
From there, add and subtract from 1.0 to get the 90%, and 110% values.
If the first number is between the ranges, then there you have it.
BOOL isNumberWithinPercentOfNumber(float firstN, float percent, float secondN) {
float decimalPercent = percent / 200.0;
float highRange = secondN * (1.0 + decimalPercent);
float lowRange = secondN * (1.0 - decimalPercent);
return lowRange <= firstN && firstN <= highRange;
}
Note: there's no error checking here for NaN or negative values. You'll want to add that for production code.
Update: to make percent to include both +/- range.
Answer to your refined/new question:
bool isNumberWithinPercentOfNumber (float n1, float percentage, float n2)
{
if (n2 == 0.0) //check for div by zero, may not be necessary for float
return false; //default for a target value of zero is false
else
return (percentage > abs(abs(n2 - n1)/n2)*100.0);
}
To explain, you take the absolute difference between your test and target value, and divide it by the target value (the two 'abs'olute calls make sure this works with negative target and test numbers too, but not with negative percentages/tolerances). This gives you the percentage of the difference expressed as decimal fraction, multiplies it with 100 to give the 'common' expression of percentage (10% = 0.10),

Resources