I'm trying to generate a random number between two ranges in Objective-C.
For example between [-50;-30] and [30,50].
I achieved to do it between [-50,50] but I need to eliminate all the values between [-30,30].
int rads = -50 + arc4random() % (50 - (-50));
Thanks for your help.
To build on the previous answer (which has been removed):
use arc4random_uniform
use correct upper bounds and correct arithmetics
Regarding 1: arc4random_uniform(50) will yield a number between 0 and 49 inclusive. It will yield that value with a correct unfirom distribution. Using only arc4random % something introduces modulo bias.
Regarding 2: You are trying not to retrieve 40 values but 42 since you want to be able to retrieve the upper a nd the lower bound values as well. If we simplify the bounds we can see the error better, assume [-5;-3] and [3;5]: you want the numbers -5,-4,-3,3,4,5 six values, not 4.
Solution:
int rads = arc4random_uniform(42) - 20; // values between -20 and 21 inclusive, 42 different numbers
if (rads <= 0) { // subtract from the lower 21 values [-20;0]
rads = rads - 30; // [-50;-30]
} else { // add to the upper 21 values [1;21]
rads = rads + 29; // [30;50]
}
More general for symmetric upper and lower bounds
int lower = 30;
int upper = 50;
int diff = upper - lower;
int rads = arc4random_uniform((diff + 1) * 2) - diff; // values between -diff and (diff+1) inclusive, ((diff+1)*2) different numbers
if (rads <= 0) { // subtract from the lower (diff+1) values [-diff;0]
rads = rads - lower; // [-upper;-lower]
} else { // add to the upper 21 values [1;diff+1]
rads = rads + lower - 1; // [lower;upper]
}
Note that you can simplfy the code a bit by moving the conditional substraction up to the initial rads calculation and changing the later addition and the condition for adding. BUT that would make the code a bit less readable and intutive.
One thing to try would be choosing randomly either 1 or -1. Then multiplying that by another random number between 30-50 would work.
Related
I have 2 sliders, both sliders have a minimum and maximum value set to 0 and 1. In the pic, they simulate changing ramp values at a maximum of 300 total frames combined.
For the first slider, I get the range of 0-150 frames correctly with
int selectedFrameCount = 300;
int currentSelectedFrameValue = sender.value * (selectedFrameCount/2);
I'd like to know how to get a range of 150-300 frames with the second slider without changing the minimum and maximum UISlider values because I need those values for a separate calculation.
For a separate function, I'll need to convert that value back to from selected 150-300 value into a float based on the 0-1 value selected.
example: 285 = x * (300/2) + 150;
Isn't it as simple as
int currentSelectedFrameValue = (sender == firstSlider ? 0 : selectedFrameCount/2)
+ sender.value * (selectedFrameCount/2);
?
You have to imagine your calc as a function (it is, so you haven't to imagine it :D )
y is the int you want
x is the sender.vale
y(x) = x * (selectedFrame/2)
If you want to translate your line on y-axis by selectedFrame/2 you just have to add it to as q value on linear equation y(x) = mx + q
So, the solution is
int value = sender.value * (selectedFrame/2) + (selectedFrame/2)
To convert the int value into a float value in 0-1 range, use this
multipliedMaxValue = selectedFrame
multipliedSelectedValue = value
multipliedMaxValue : 1 = multipliedSelectedValue : x
if you want x, just do
float toRangeValue = (float)multipliedSelectedValue / (float)multipliedMaxValue;
I searched and couldn't find a solution to this (maybe I'm using the wrong terms?), and I feel a bit silly because I believe I'm overlooking something simple. Here's what I'd like to do:
I have an object in my game that needs to travel a specific x distance in a specified number of frames. But, I'd like to have it ease into the target point instead of moving the same distance/velocity every frame.
So rather than just dividing the number of frames by the distance, and applying that velocity each frame, I'd I'd like to slowly ease itself into the target coordinate in a specified number of frames.
So for example (I'm terrible at explaining, perhaps an example could help)... say I have a spaceship, and he needs to travel 32 pixels to the right. I'd like to input a value that specifies he'll travel 32 pixels in... say, 4 frames. In a linear system, he'd travel 8 pixels each frame, but I want him to ease into it, so maybe on frame 1 (and I'm using completely random values) he'd move 16 pixels, frame 2 he'd move 10, frame 3 he'd move 4, and frame 4 he'd move 2, and he'll end up traveling the 32 pixels distance in those 4 frames, slowly easing into the target point.
The first thing that came to mind was using exponent/logarithms somehow, but I'd like some suggestions. Any help would be greatly appreciated, thanks! :D
The general solution is the following:
You have a value (distanceTravelled) which has a range from 0.0 to 1.0.
You have a function (fancyCurve) which takes in a float from 0.0 to 1.0 and remaps it from 0.0 to 1.0, except in a curve.
Every frame, you increase distanceTravelled by a linear amount. But you get the actual value by calling fancyCurve(distanceTravelled).
Here's a pseudo-code example
float linearFunction(float t) { return t; }
float speedUpFunction(float t) { return t*t; }
float slowDownFunction(float t)
{
//do your own research. Theres plenty of curves from http://easings.net/
}
float easingCurve(float t) {
//choose one.
//return linearFunction(t);
//return speedUpFunction(t);
return slowDownFunction(t);
}
int main() {
//setting up a spaceship with starting x coordinate
spaceshipX = 2;
spaceshipTargetX = 34;
animationFrames = 8;
//Below is the actual algorithm
distanceTravelled = 0;
startValue = spaceshipX;
animRange = spaceshipTargetX - startValue; // 32
distancePerFrame = 1.0f / animationFrames; // 0.125, since 8 frames
while (distanceTravelled < 1.0f) {
WaitForEndOfFrame();
distanceTravelled += distancePerFrame;
spaceshipX = startValue + (easingCurve(distanceTravelled) * animRange);
}
}
I need to calculate the standard deviation on an image I have inside a UIImage object.
I know already how to access all pixels of an image, one at a time, so somehow I can do it.
I'm wondering if there is somewhere in the framework a function to perform this in a better and more efficient way... I can't find it so maybe it doensn't exist.
Do anyone know how to do this?
bye
To further expand on my comment above. I would definitely look into using the Accelerate framework, especially depending on the size of your image. If you image is a few hundred pixels by a few hundred. You will have a ton of data to process and Accelerate along with vDSP will make all of that math a lot faster since it processes everything on the GPU. I will look into this a little more, and possibly put some code in a few minutes.
UPDATE
I will post some code to do standard deviation in a single dimension using vDSP, but this could definitely be extended to 2-D
float *imageR = [0.1,0.2,0.3,0.4,...]; // vector of values
int numValues = 100; // number of values in imageR
float mean = 0; // place holder for mean
vDSP_meanv(imageR,1,&mean,numValues); // find the mean of the vector
mean = -1*mean // Invert mean so when we add it is actually subtraction
float *subMeanVec = (float*)calloc(numValues,sizeof(float)); // placeholder vector
vDSP_vsadd(imageR,1,&mean,subMeanVec,1,numValues) // subtract mean from vector
free(imageR); // free memory
float *squared = (float*)calloc(numValues,sizeof(float)); // placeholder for squared vector
vDSP_vsq(subMeanVec,1,squared,1,numValues); // Square vector element by element
free(subMeanVec); // free some memory
float sum = 0; // place holder for sum
vDSP_sve(squared,1,&sum,numValues); sum entire vector
free(squared); // free squared vector
float stdDev = sqrt(sum/numValues); // calculated std deviation
Please explain your query so that can come up with specific reply.
If I am getting you right then you want to calculate standard deviation of RGB of pixel or HSV of color, you can frame your own method of standard deviation for circular quantities in case of HSV and RGB.
We can do this by wrapping the values.
For example: Average of [358, 2] degrees is (358+2)/2=180 degrees.
But this is not correct because its average or mean should be 0 degrees.
So we wrap 358 into -2.
Now the answer is 0.
So you have to apply wrapping and then you can calculate standard deviation from above link.
UPDATE:
Convert RGB to HSV
// r,g,b values are from 0 to 1 // h = [0,360], s = [0,1], v = [0,1]
// if s == 0, then h = -1 (undefined)
void RGBtoHSV( float r, float g, float b, float *h, float *s, float *v )
{
float min, max, delta;
min = MIN( r, MIN(g, b ));
max = MAX( r, MAX(g, b ));
*v = max;
delta = max - min;
if( max != 0 )
*s = delta / max;
else {
// r = g = b = 0
*s = 0;
*h = -1;
return;
}
if( r == max )
*h = ( g - b ) / delta;
else if( g == max )
*h=2+(b-r)/delta;
else
*h=4+(r-g)/delta;
*h *= 60;
if( *h < 0 )
*h += 360;
}
and then calculate standard deviation for hue value by this:
double calcStddev(ArrayList<Double> angles){
double sin = 0;
double cos = 0;
for(int i = 0; i < angles.size(); i++){
sin += Math.sin(angles.get(i) * (Math.PI/180.0));
cos += Math.cos(angles.get(i) * (Math.PI/180.0));
}
sin /= angles.size();
cos /= angles.size();
double stddev = Math.sqrt(-Math.log(sin*sin+cos*cos));
return stddev;
}
I need to know how to calculate the positions of the QR Code alignment patterns as defined in the table of ISO/IEC 18004:2000 Annex E.
I don't understand how it's calculated. If you take the Version 16, for example, the positions are calculated using {6,26,50,74} and distance between the points are {20,24,24}. Why isn't it {6,28,52,74}, if the distances between the points, {22,24,22}, is distributed more equally?
I would like to know how this can be generated procedurally.
While the specification does provide a table of the alignment, this is a reasonable question (and one I found myself with :-)) - the possibility of generating the positions procedurally has its merits (less typo-prone code, smaller code footprint, knowing pattern/properties of the positions).
I'm happy to report that, yes, a procedure exists (and it is even fairly simple).
The specification itself says most of it:
[The alignment patterns] are spaced as evenly as possible between the Timing Pattern and the opposite side of the symbol, any uneven spacing being accommodated between the timing pattern and the first alignment pattern in the symbol interior.
That is, only the interval between the first and second coordinate may differ from the rest of the intervals. The rest must be equal.
Another important bit is of course that, for the APs to agree with the timing patterns, the intervals must be even.
The remaining tricky bit is just getting the rounding right.
Anyway - here's code printing the alignment position table:
def size_for_version(version):
return 17 + 4 * version
def alignment_coord_list(version):
if version == 1:
return []
divs = 2 + version // 7
size = size_for_version(version)
total_dist = size - 7 - 6
divisor = 2 * (divs - 1)
# Step must be even, for alignment patterns to agree with timing patterns
step = (total_dist + divisor // 2 + 1) // divisor * 2 # Get the rounding right
coords = [6]
for i in range(divs - 2, -1, -1): # divs-2 down to 0, inclusive
coords.append(size - 7 - i * step)
return coords
for version in range(1, 40 + 1): # 1 to 40 inclusive
print("V%d: %s" % (version, alignment_coord_list(version)))
Here's a Python solution which is basically equivalent to the C# solution posted by #jgosar, except that it corrects a deviation from the thonky.com table for version 32 (that other solution reports 110 for the second last position, whereas the linked table says 112):
def get_alignment_positions(version):
positions = []
if version > 1:
n_patterns = version // 7 + 2
first_pos = 6
positions.append(first_pos)
matrix_width = 17 + 4 * version
last_pos = matrix_width - 1 - first_pos
second_last_pos = (
(first_pos + last_pos * (n_patterns - 2) # Interpolate end points to get point
+ (n_patterns - 1) // 2) # Round to nearest int by adding half
# of divisor before division
// (n_patterns - 1) # Floor-divide by number of intervals
# to complete interpolation
) & -2 # Round down to even integer
pos_step = last_pos - second_last_pos
second_pos = last_pos - (n_patterns - 2) * pos_step
positions.extend(range(second_pos, last_pos + 1, pos_step))
return positions
The correction consists of first rounding the second last position (up or down) to the nearest integer and then rounding down to the nearest even integer (instead of directly rounding down to the nearest even integer).
Disclaimer: Like #jgosar, I don't know whether the thonky.com table is correct (I'm not going to buy the spec to find out). I've simply verified (by pasting the table into a suitable wrapper around the above function) that my solution matches that table in its current version.
sorry about my English.
I hope this can help you, and not to later reply.
first things, the standard forget a important thing is that the top left is define with (0,0).
the { 6, 26, 50, 74 } means the alignment points row coordinate and col coordinate, and I don't
know why they do like this, maybe for save space. but we combine all the values for example the:
{ 6, 26, 50, 74 }
and we get :
{ 6 , 6 } ---> ( the x coordinate is 6, and the y is 6, from top/left )
{ 6 , 26 }
{ 6 , 50 }
{ 6 , 74 }
{ 26, 26 }
{ 26, 50 }
{ 26, 74 }
{ 50, 50 }
{ 50, 74 }
{ 74, 74 }
those point's are the actual coordinate of alignment patterns center.
Ps: if a position has the position detection patterns, we ignore output alignment, like the position
(6, 6).
I also have this question before, but now, I solve it, so I hope you can solve it too.
good luck~
There are some comments on the top rated answer that suggest it isn't 100% accurate, so i'm contributing my solution as well.
My solution is written in C#. It should be easy to translate it to a language of your choice.
private static int[] getAlignmentCoords(int version)
{
if (version <= 1)
{
return new int[0];
}
int num = (version / 7) + 2;//number of coordinates to return
int[] result = new int[num];
result[0] = 6;
if (num == 1)
{
return result;
}
result[num - 1] = 4 * version + 10;
if (num == 2)
{
return result;
}
result[num - 2] = 2 * ((result[0] + result[num - 1] * (num - 2)) / ((num - 1) * 2)); //leave these brackets alone, because of integer division they ensure you get a number that's divisible by 2
if (num == 3)
{
return result;
}
int step = result[num - 1] - result[num - 2];
for (int i = num - 3; i > 0; i--)
{
result[i] = result[i + 1] - step;
}
return result;
}
The values i get with it are the same as shown here: http://www.thonky.com/qr-code-tutorial/alignment-pattern-locations/
To sum it up, the first coordinate is always 6.
The last coordinate is always 7 less than the image size. The image size is calculated as 4*version+17, therefore the last coordinate is 4*version+10.
If the coordinates were precisely evenly spaced, the position of one coordinate before the last would be (first_coordinate+(num-2) * last_coordinate)/(num-1), where num is the number of all coordinates.
But the coordinates are not evenly spaced, so this position has to be reduced to an even number.
Each of the remaining coordinates is spaced the same distance from the next one as the last two are from each other.
Disclaimer: I didn't read any of the documentation, i just wrote some code that generates a sequence of numbers that's the same as in the table i linked to.
Starting with #ericsoe's answer, and noting it's incorrect for v36 and v39 (thanks to #Ana's remarks), I've developed a function that returns the correct sequences. Pardon the JavaScript (fairly easy to translate to other languages, though):
function getAlignmentCoordinates(version) {
if (version === 1) {
return [];
}
const intervals = Math.floor(version / 7) + 1;
const distance = 4 * version + 4; // between first and last alignment pattern
const step = Math.ceil(distance / intervals / 2) * 2; // To get the next even number
return [6].concat(Array.from(
{ length: intervals },
(_, index) => distance + 6 - (intervals - 1 - index) * step)
);
}
I don't know if this is a useful question to ask. It just is the way it is, and it doesn't really matter much if it were {22,24,22}. Why are you asking?
My guess it that the spacing should be multiples of 4 modules.
It seems like most answers aren't correct for all versions (especially v32, v36 and v39) and/or are quite convoluted.
Based on #MaxArt's great solution (which produces wrong coordinates for v32), here's a C function which calculates the correct coordinates for all versions:
#include <math.h>
int getAlignmentCoordinates(int version, int *coordinates) {
if (version <= 1) return 0;
int intervals = (version / 7) + 1; // Number of gaps between alignment patterns
int distance = 4 * version + 4; // Distance between first and last alignment pattern
int step = lround((double)distance / (double)intervals); // Round equal spacing to nearest integer
step += step & 0b1; // Round step to next even number
coordinates[0] = 6; // First coordinate is always 6 (can't be calculated with step)
for (int i = 1; i <= intervals; i++) {
coordinates[i] = 6 + distance - step * (intervals - i); // Start right/bottom and go left/up by step*k
}
return intervals+1;
}
The key is to first round the division to the nearest integer (instead of up) and then round it to the next largest even number.
The C program below uses this function to generate the same values as in the table of ISO/IEC 18004:2000 Annex E linked by OP and the (updated) list found on thonky.com:
#include <stdio.h>
void main() {
for (int version = 2; version <= 40; version++) {
int coordinates[7];
int n = getAlignmentCoordinates(version, coordinates);
printf("%d:", version);
for (int i = 0; i < n; i++) {
printf(" %d", coordinates[i]);
}
printf("\n");
}
}
I have a number in actionscript, arrived at via some arbitrary math:
var value:Number = 45 * (1 - (1 /3));
trace(value);//30.00000000004
Now, I would like to take the ceiling of this number, except in cases where the amount it is greater than the next lower integer is smaller than some epsilon. In the above example, I really want to round to 30, but only in the case where I know I'm getting a rounding error:
Math.ceil(value); //I want 30, but get 31
Math.ceil(30.1); //In this case, it's reasonable to get 31
Is there an elegant way to truncate a Number in actionscript? Or easily discard any part of the number that is less than some epsilon?
Is this method is of any help to you?
var precision:int = 4;
var isActualCeilingValRequred:Boolean;
var thresholdValForCeiling:int = 100;
private function getCeilingValue(num:Number):Number
{
var tempNum = num * Math.pow(10, precision);
var decimalVal = tempNum % Math.pow(10, precision);
if(decimalVal < thresholdValForCeiling) {
return Math.floor(num);
} else {
return Math.Ceil(num);
}
}
var value:Number = 45 * (1 - (1 /3));
trace(value);//30.00000000004
// Play with arbitraryPrecision until you are satisfied with
// the accuracy of your results
var arbitraryPrecision:int = 3;
var fixed:Number = value.toFixed(arbitraryPrecision);
trace(Math.ceil(fixed));
The basic way to round a number to a specified number of fractional digits is to multiply the number to 10^DIGITS to shift the decimal point DIGITS digits to the left, perform the rounding, and divide by the same 10^DIGITS to shift the decimal point back to the right.
var value:Number = 45 * (1 - (1 / 3));
trace(value); // 30.000000000000004
trace(Math.ceil(value)); // 31
// Round the number to 13 decimal digits.
const POWER:Number = 1e13;
value = Math.round(value * POWER) / POWER;
trace(value); // 30
// Compute number's ceiling.
value = Math.ceil(value);
trace(value); // 30`
It works for your example, but there's a big gotcha. If you change your value to be 450 * (1 - (1 / 3));, your original problem will appear again. Now to get rid of it, you would have to round to 12 decimal digits. Basically, the significand of a double-precision format (Number) can hold about 15 significant digits. This means as the value increases by a factor of ten, the decimal points moves to the left and that last "4" digit you want to get rid of becomes closer and closer to the decimal point. So the code becomes more complicated.
var value:Number = 450 * (1 - (1 / 3));
trace(value); // 30.000000000000004
trace(Math.ceil(value)); // 31
var exp:Number = Math.floor(Math.log(Math.abs(value)) * Math.LOG10E);
trace('exp=' + exp); // exp=2
const POWER:Number = Math.pow(10, 14 - exp);
value *= POWER;
trace(value); // 300000000000000.06
value = Math.round(value);
trace(value); // 300000000000000
value /= POWER;
trace(value); // 300
As you can see, it now works regardless of the value's magnitude.
First, I find the number's exponent by taking a base-10 logarithm of the number's absolute value, then rounding it down. If you calculate a = value * Math.pow(10, exp);, then value could be represented as a * 10^b, where (1 ≤ |a| < 10), known as normalized scientific notation. But that's not what we're doing here. Now that we know how many digits are on the left of the decimal point, we will shift the decimal point right, but not too far, to keep one 0 and this error digit we want to get rid of, on the right side of the decimal point. So, multiply by 10^(14-exp), round, then divide by the same power.