I have this code
if ($('input#grommet').is(':checked')) {
if (width <= 96) {
var grommetQTY = 4;
} else if (width > 96) {
grommetQTY = (Math.floor(width / 24));
grommetQTY = grommetQTY - 4;
grommetQTY = grommetQTY * 2;
grommetQTY = grommetQTY +4;
}
}
and I need to add 2 to the grommetQTY for each whole 24 inches (2 feet) over 96 width. Is there a way to do this?
What this is attempting to accomplish is giving the pricing for a banner. We add 2 more grommets at 2 feet intervals, but because this is custom sizing, it could be 96 feet wide, and I don't want to have to write an else if statement for each two foot interval. I am hoping there is a way to only add two to the quantity everytime the width goes another 24 inches over the standard 96 inch width so if width is 96 or less, qty is 4, at 120 its 6, at 144 its 8, etc
Rather than coming up with the equation for this, here is a for loop that will do what you need:
var grommetQTY = 0;
for(var i = 96; i < n; i++)
if(i%24 == 0)
grommetQTY += 2;
where n is the length. This is terrible inefficient and could be sped up by just doing:
var grommetQTY = 0;
for(var i = 96; i < n; i+=24)
grommetQTY += 2;
This is nicer but still not ideal. The ideal solution in your case would be an equation.
P.S - The equation is Math.floor( Math.max((n - 96), 0) / 24 ) * 2 + 4 if I understand you correctly.
You could do something like this:
var extra = width - 96
var grommetQTY = 4;
if (extra > 0) {
grommet += Math.floor((extra / 24)) * 2;
}
The variable extra holds, as the name implies, extra length that you would want to take into consideration. If it's 0 or below that means it's 96 and under.
Then, for extra > 0 you could alternatively change it to extra >= 24 as any extra value less than 24 will return 0.
Math.pow(2, grommetQTY) * (Math.floor(96 / 24))
2 to the grommetQTY for each whole 24 inches in 96. Is that what you need?
Math.pow(a, b) gives a to the power of b
Edit:
var qty = (Math.floor(n / 24)) * 2
Where n is the pixels (96 in your example).
Edit:
var qty = 4 + ((width > 96) ? ((Math.floor((width - 96) / 24) * 2) : 0);
Is that it?
Related
I have a 300px * 300px image. I also have some specific pixels every 100px in every direction (to 16 specific pixels in total).
0 1 2 <-- IntervalX
______ ______ ______
0 | | | |
|______|______|______|
1 | | | |
|______|______|______|
2 | | | |
|______|______|______|
^
IntervalY
I want to put every pixels (except the specific ones) in blocks bounded by the specific pixels, but defined by the pixels value in a 1D array, not 2D array.
const gridX = width / (trueX - 1);
const gridY = width / (trueY - 1);
//Loop for every pixel:
intervalX = Math.floor((pixel[inc].x) / gridX);
intervalY = Math.floor((pixel[inc].y) / gridY);
//Implementing formula for transforming from 1D array to 2D array : (y * width + x) = item number
//All leftmost known pixels start from a "zero" value, so we do not need to substract 1
let isNotFirstArray;
if (intervalX == 0)
isNotFirstArray = 0;
else
isNotFirstArray = 1;
p1 = pixel[intervalY * gridY * 299 + intervalX * gridX - isNotFirstArray];
p2 = pixel[intervalY * gridY * 299 + (intervalX + 1) * gridX - 1];
p3 = pixel[(intervalY + 1) * gridY * 299 + intervalX * gridX - isNotFirstArray];
p4 = pixel[(intervalY + 1) * gridY * 299 + (intervalX + 1) * gridX - 1];
pixel[inc].value = Math.round(bilinearInterpolate(p1, p2, p3, p4, j, i));
inc++;
The problem is the values for the specific pixels are not calculated correctly. The Y values are correct, but the X are not.
Later edit:
The error is like this: the coordinates of the specific pixels are correct on the Y axis, but not on the X axis. They are shifted for the inner intervals with 100px*(max intervals - current interval).
If I get that right, you would like to »filter-out« some of the pixels, which appear at some interval in x and y direction?
const img = <image array>,
imgWidth = 600,
gridX = 150,
gridY = 200;
let result = [];
for (let i = 0; i < input.length; i++) {
let x = i % imgWidth,
y = Math.floor(i / imgWidth);
if (!(x % gridX == 0 || y % gridY == 0)) {
result.push(input[i])
}
}
That should filter out all the indexes which are as special as you said. It remains an array of pixels of an image with the a width.
What is the percent change of this code reaching the number 200, 500 and 1000?
I created this code for 200 to be 50% but it keeps rolling numbers above 200, someone please help me if you understand :D.
var mainMultplier = 100;
var numerator = 99;
var denominator = 100;
for(;;) {
var randomInt = random.real(0, 1.0);
if ( numerator/denominator > randomInt ) {
numerator = numerator + 1;
denominator = denominator + 1;
mainMultplier = mainMultplier + 1;
} else {
break;
}
}
Edit
Based on the code you have posted, we can see these two base rules:
P(100) = 1 - 0.99 = 0.01
P(101) = (1 - P(100)) * (1 - (100 / 101)) = P(101) = (1 - P(100)) * (1 / 101)
The second rule can be generalized for any number X after 100:
P(X) = (1 - P(X - 1)) * (1 / X)
Now, I did learn how to do proofs by induction at Uni, which I'm sure would help my explanation here, but I can't remember it anymore :(. So instead, I've written some code to generate a lookup table p, from 100 to 1000:
var p = [];
p[100] = 0.01;
for (var x = 101; x <= 1000; x++)
p[x] = (1 - p[x - 1]) * (1 / x);
Edit 2
And that's as far as my help can go. You may want to post the generalized algorithm on the Software Engineering page.
So, I have a code that is rolling a random number from 1024 to 4096 and changing backgroundPosition to rolled number. (jsfiddle)
function slide()
{
var x = 1;
var y = 30;
var z = Math.floor((Math.random() * 4096) + 1024); // background offset
var zz = Math.floor((Math.random() * 14) + 0); // number
var clr = setInterval(function()
{
if(x >= z) x = 1;
document.getElementById("slide").style.backgroundPosition = x+"px 0px";
x+=y;
y-=0.1;
if (y<=0)
{
clearInterval(clr);
document.getElementById('rolledNumber').innerHTML = z;
}
}
,10);
}
"z" is a random number between 1024 and 4096, how can I check what number on image it is? I tried if (z >= 2285 && z <= 2210){var zz = 4;}, where "zz" is a number on image, but it's not working.
Hope you guys can understand it.
You have a few problems here:
1) if (z >= 2285 && z <= 2210)
is impossible. There is no number that satisfies both "larger than 2284" AND "smaller than 2211".
2) "z" is a random number between 1024 and 4096
var z = Math.floor((Math.random() * 4096) + 1024); will actually create a random number between 1024 and 5120. Imagine the case where Math.random() returns 1. Your result would be 1 * 4096 + 1024, or 5120.
3) Your background image is repeating - if you stick to one set of 15 numbers, you could access the number by mapping the pixel offset to an array.. something like this:
var boxWidth = 150;
var boxes = [1, 14, 2, 13, 3, 12, 4, 0, 11, 5, 10, 6, 9, 7, 8];
function getNumber (offset) {
var boxNumber = Math.floor(offset / boxWidth);
return boxes[boxNumber];
}
4) No one knows the application of this logic other than you, please reword your question such that it actually makes any sense and act like you've tried to find the problem yourself.
If anyone is interested - I figured out how to do this. I'm checking "x" value, and if it's between x and y, that means rolled number is z. Fragment of code:
if (x >= 410 && x <= 485){var rolledNumber = 1;}
if (x >= 335 && x <= 410){var rolledNumber = 14;}
if (x >= 260 && x <= 335){var rolledNumber = 2;}
I am visualising bubbles for cities, bigger if the city has a bigger value. Eg:
London: 14500
New York: 100
Tokyo: 1100
The values range from ~100-15000
I am having trouble creating a function that will return reasonable values, so that the 100 value bubbles aren't too small. The only way I could think to do this is to set a minimum size, eg:
if (size < 5) { size = 5 }
However, this causes the cities with values of ~100 to look very similar to cities with values of ~1000. I'd like the values of approx 0-15000 to return as values between 0.5 and 1 (or something similar). How would this be done?
Here's what I have so far, but like I said it's causing values of 100 and values of 1000 to both be under the min value:
var minBulletSize = 7.5;
var maxBulletSize = 20;
var maxSquare = maxBulletSize * maxBulletSize * 2 * Math.PI;
var minSquare = minBulletSize * minBulletSize * 2 * Math.PI;
// create circle for each location
for (var i = 0; i < mapData.length; i++) {
var dataItem = mapData[i];
var value = dataItem.value;
// calculate size of a bubble
var square = (value/1000 - minBulletSize) / (maxBulletSize - minBulletSize) * (maxSquare - minSquare) + minSquare;
if (square < minSquare) {
square = minSquare;
}
if (square > maxSquare) {
square = maxSquare;
}
var size = Math.sqrt(square / (Math.PI * 2));
var id = dataItem.code;
}
I have taken a look at how to make a logarithmic function to look "logarithmic" within the constraints of 0.5 and 1 :
Math.log10(x / 0.8 + 1) / 3 + 0.5 where x is in between 0 to 24.5.
This is purely a function that seems to look good for me where you can get very dynamic numbers early although a clear growth can be seen in larger numbers.
Feel free to mess around with the numbers, this is VERY subjective.
Next you will need to fit in your 100~15000 range within 0 to 24.5.
I would simply do a x = (x - 100) / 608.16 to get your range to be within 0 to 24.5.
var minBulletSize = 7.5;
var maxBulletSize = 20;
var maxSquare = maxBulletSize * maxBulletSize * 2 * Math.PI;
var minSquare = minBulletSize * minBulletSize * 2 * Math.PI;
// create circle for each location
for (var i = 0; i < mapData.length; i++) {
var dataItem = mapData[i];
var value = dataItem.value;
// assuming value is in between 100 and 15000
value = (value - 100) / 608.16;
value = Math.log10(value / 0.8 + 1) / 3.0 + 0.5;
// value will be in between 0.5 and 1 on a logarithmic scale.
// Do what you want with it :)
}
Tinker the values within the functions until you find a perfect curve for you.
I am working on changing a percentage value of a panel based on the screen size of a device.
I need to work out the following formula.
Starting at screen width 320 and ending at screen width 1200.
If screenWidth < 320 percentageWidth = 98
If screenWidth > 1200 percentageWidth = 65
From the above I can work out manually that:
If screenWidth = 760 percentageWidth = 82.
What is the formula I need so I can change percentageWidth on a screen width change?
That's just simple math:
You start with the minimum of 65 and add a relative amount depending on the screen width:
Demo
function getPercentageWidth(screenWidth) {
return 65 + 33 * (Math.min(Math.max(screenWidth, 320), 1200) - 320) / 880;
}
getPercentageWidth(0) // 65
getPercentageWidth(320) // 65
getPercentageWidth(1200) // 98
getPercentageWidth(2400) // 98
getPercentageWidth(760) // 81.5
Inverse version Demo
This version starts with 98 and subtracts the relative amount:
function getPercentageWidth(screenWidth) {
return 98 - 33 * (Math.min(Math.max(screenWidth, 320), 1200) - 320) / 880;
}
getPercentageWidth(0) // 98
getPercentageWidth(320) // 98
getPercentageWidth(1200) // 65
getPercentageWidth(2400) // 65
getPercentageWidth(760) // 81.5
The other answers use if/else but you can also use Math.min and Math.max:
Math.max(screenWidth, 320) // Will always return 320 or more
Math.min(screenWidth, 1200) // Will always return 1200 or less
So the result of (Math.min(Math.max(screenWidth, 320), 1200) - 320) / 880 will always be between 0 and 1.
Although you don't explicitly say so, it appears that you're predicting a linear correlation between screenWidth and percentageWidth. If so, here's an example of code that you can put into a function for the result:
minScreenWidth = 320;
maxScreenWidth = 1200;
diffScreenWidth = maxScreenWidth - minScreenWidth;
maxPercentageWidth = 98; // At screenWidth = 320
minPercentageWidth = 65; // At screenWidth = 1200
diffPercentageWidth = maxPercentageWidth - minPercentageWidth;
screenWidth = 760; // Change this as needed.
ratioScreenWidth = (screenWidth - minScreenWidth) / diffScreenWidth;
percentageWidth = maxPercentageWidth - (ratioScreenWidth * diffPercentageWidth);
// Since your example gave 82 as the desired result instead of 81.5,
// I infer that you want the answer rounded.
resultPercentageWidth = Math.round(percentageWidth);
#jantimon posted his answer first, with a very elegant one-line function (which I have upvoted). I kept working on this answer in the meantime because I had taken a different approach of breaking down the steps in the hope that it will help you analyze other math functions that you need to apply to JavaScript.
I see that you are a new user. Welcome. And when you return to view the answers, please remember to mark one of them as correct (whichever was most useful to you), and to upvote any that were useful to you, if your reputation points allow it.
Also, when you post questions in the future, please be aware that you're also expected to show examples of your own attempts and the results of those attempts.
You want something like:
function doCalc(sw) {
var pw;
if (sw < 320) {
pw = 98;
} else if (sw > 1200) {
pw = 65;
} else {
// pw = 98 - (98 - 65) * (sw - 320) / (1200 - 320);
pw = 98 - 33 * (sw - 320) / 880;
}
return Math.round(pw);
}
or if you like one liners:
function doCalc(sw) {
return Math.round(sw<320? 98 : sw>1200? 65 : 98 - 33*(sw-320)/880);
}
The first answer delivers opposite results, the second the wrong values for screenWidth < 320 and screenWidth > 1200. This one is hopefully correct and maybe a little more readable:
var calculatePercentageWidth = function(screenWidth) {
var MAX_SCREEN = {percentage: 65, width: 1200};
var MIN_SCREEN = {percentage: 98, width: 320};
if (screenWidth < MIN_SCREEN.width) {
return MIN_SCREEN.percentage;
} else if (screenWidth > MAX_SCREEN.width) {
return MAX_SCREEN.percentage;
} else {
var coefficient = (MIN_SCREEN.percentage - MAX_SCREEN.percentage) / (MAX_SCREEN.width - MIN_SCREEN.width);
return Math.round(MAX_SCREEN.percentage + (screenWidth - MIN_SCREEN.width) * coefficient);
}
}
If the values for the maximum and minimum width or percentage change, you only need to change the values in the constants at the top of the function.
To calculate the percentageWidth for screenWidth = 760, write:
calculatePercentageWidth(760);
jsfiddle
Corrected version:
var calculatePercentageWidth = function(screenWidth) {
var MAX_SCREEN = {percentage: 65, width: 1200};
var MIN_SCREEN = {percentage: 98, width: 320};
if (screenWidth < MIN_SCREEN.width) {
return MIN_SCREEN.percentage;
} else if (screenWidth > MAX_SCREEN.width) {
return MAX_SCREEN.percentage;
} else {
var coefficient = (MIN_SCREEN.percentage - MAX_SCREEN.percentage) / (MAX_SCREEN.width - MIN_SCREEN.width);
return Math.round(MIN_SCREEN.percentage - (screenWidth - MIN_SCREEN.width) * coefficient);
}
}
jsfiddle
What you are trying to do is called linear interpolation. For two points, (x0, y0) and (x1, y1) there exists a straight line. Linear interpolation takes any value x between x0 and x1 and calculates the y value that falls on that line. The general case is computed as:
y = y0 + (y1 - y0) * (x - x0) / (x1 - x0)
For your case, the two points are (320, 98) and (1200, 65). This results in the equation:
y = 98 - 33 * (x - 320) / 880
To validate your calculation, set x = 760:
y = 98 - 33 * (760 - 320) / 880
= 98 - 33 * 440 / 880
= 98 - 33 / 2
= 98 - 16.5
= 81.5