Math formula for changing number between two range [closed] - swift

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
Here is my issue as an example:
I have two variables, minNumber = 12 & maxNumber = 24 and a maxLimit = 30
and I have a percentage between 1.0 - 0.0, I want the following result:
when the percentage decrease from 1.0 to 0.5, I want minNumber to increase to the maxLimit, and when the percentage decrease from 0.5 to 0.0, the maxLimit went down to maxNumber
so,
percentage = 1.0
var result = 0
while percentage >= 0 {
if percentage < 0.5 {
result = 12.1, 12.2, ..., 29.8, 29.9, 30 (what formula can produce this sequence)
} else {
result = 30, 29.9, ..., 24.1, 24.0 (what formula can produce this sequence)
}
percentage = percentage - 0.1
print("\(result)")
}

If I understand your question correctly, you want result value to "move" in an angle-like shape from minNumber via maxLimit to maxNumber. The basis behind this transformation is following formula. If you have a value X from a range Xmin to XMax and you want to map it to a range Ymin to Ymax then
Y = (Ymin * (Xmax - X) + Ymax * (X - Xmin)) / (Xmax - Xmin)
For you case you should apply this formula for two intervals:
mapping [0; 0.5] range to [minNumber; maxLimit]
mapping [0.5; 1.0] range to [maxLimit; maxNumber]
I think the code becomes more clear if you call:
leftNumber = minNumber
middleNumber = maxLimit
rightNumber = maxNumber
and use two while loops instead of one with inner if:
let leftNumber = 12.0 // minNumber
let middleNumber = 30.0 // maxLimit
let rightNumber = 23.0 // maxNumber
let leftPercentage = 0.0
let middlePercentage = 0.5
let rightPercentage = 1.0
let percentageStep = 0.1
var percentage = leftPercentage
var result = 0.0
while percentage <= middlePercentage {
result = ((percentage - leftPercentage) * middleNumber + (middlePercentage - percentage) * leftNumber)/(middlePercentage - leftPercentage)
percentage = percentage + percentageStep
print("\(result)")
}
while percentage <= rightPercentage {
result = ((rightPercentage - percentage) * middleNumber + (percentage - middlePercentage) * rightNumber)/(rightPercentage - middlePercentage)
percentage = percentage + percentageStep
print("\(result)")
}
You can see output of this code here
Update: Where the formula comes from?
When we say that "you have a value X from a range Xmin to XMax and you want to map it to a range Ymin to Ymax", what exactly do you mean by "map"? Usually what you want is that X splits the [Xmin, Xmax] range in the same proportion as Y splits the [Ymin, Ymax] range. Let's write that:
(X - Xmin)/(Xmax - Xmin) = (Y - Ymin)/(Ymax - Ymin)
If you try to solve it for Y you can see that:
(Y - Ymin) = (X - Xmin)/(Xmax - Xmin)*(Ymax - Ymin) =
= (Ymax * (X - Xmin) - Ymin * (X-Xmin))/(Xmax - Xmin)
so
Y = (Ymax * (X - Xmin) - Ymin * (X - Xmin))/(Xmax - Xmin) + Ymin =
= (Ymax * (X - Xmin) + Ymin * (Xmin - X) + Ymin * (Xmax - Xmin))/(Xmax - Xmin) =
= (Ymax * (X - Xmin) + Ymin * (Xmax - X))/(Xmax - Xmin)
which is exactly that formula.

Related

Wgs to Mercator

We have this function we have been using to convert Wgs coordinates to Mercator. The goal is to have a thin split in latitude towards the poles, and a large one close to the equator to make the 3d match the imagery of the texture, all in an equirectangular projection.
Currently our function looks like this:
WgsToMercator(coord)
{
yRadian = coord.y * Math.PI / 180.0;
sinLat = Math.Sin(yRadian);
y = 0.5 - Math.Log((1 + sinLat) / (1 - sinLat)) / (Math.PI * 4); /// valeur entre 0 et 1, 1 correspondant a -90 degres et 0 a 90 degres
return y;
}
Current result is:
WgsToMercator(90) = 0;
WgsToMercator(45) = 0.36
WgsToMercator(0) = 0.5;
WgsToMercator(-45) = 0.64
WgsToMercator(-90) = 1;
Expected result would be:
WgsToMercator(90) = 0;
WgsToMercator(45) = 0.14
WgsToMercator(0) = 0.5;
WgsToMercator(-45) = 0.86
WgsToMercator(-90) = 1;
My math are rusty and can't find a way to get the expected result. Thanks a lot by advance
I can get approximately your numbers with sine squared, after subtracting your input from 90, taking half of the result, and converting to radians.
Something like (in Octave/Matlab):
function output = WgsToMercator(coord)
rebased_angle = 90 - coord;
half_angle = 0.5 * rebased_angle;
angle_radians = half_angle * (3.1415/180.0);
output = sin(angle_radians)*sin(angle_radians);
end
Which gets:
>> WgsToMercator(90)
ans = 0
>> WgsToMercator(45)
ans = 0.14644
>> WgsToMercator(0)
ans = 0.49998
>> WgsToMercator(-45)
ans = 0.85353
>> WgsToMercator(-90)
ans = 1.00000
In C# it's:
public float WgsToMercator(float coord)
{
var rebasedAngle = 90.0f - coord;
var halfAngle = 0.5f * rebasedAngle;
var angleRadians = halfAngle * (Mathf.PI / 180.0f);
return Mathf.Sin(angleRadians) * Mathf.Sin(angleRadians);
}
:EDIT:
Here's a plot of the function I provided (in blue) and the points you've given (red circles).

how Can I make a Sine Function in swift [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I have tried the following but it gives me nan
func sin (x: Double) -> Void {
var z = 1000
var n = 1.0
var w = 0.0
var b = (2*n-1)+1
var c = 0.0
while (b > 2){
c *= (b-1)
b -= 1
}
while (z > 0){
w += (power(x:(-1), y:(n-1))*(power(x:x, y:(2*n-1)))/c)
z -= 1
n += 1
}
print(w)
} where
power(x:base, y: exponent)
Example:
func sin(_ x: Double) -> Double {
func factorial(_ number: Int) -> Int {
var result = 1
for i in 2...number {
result *= i
}
return result
}
let x2 = x * x
let x4 = x2 * x2
let t1 = x * (1.0 - x2 / Double(factorial(3)))
let x5 = x4 * x
let t2 = x5 * (1.0 - x2 / (6 * 7)) / Double(factorial(5))
let x9 = x5 * x4
let t3 = x9 * (1.0 - x2 / (10 * 11)) / Double(factorial(9))
let x13 = x9 * x4
let t4 = x13 * (1.0 - x2 / (14 * 15)) / Double(factorial(13))
let result = t1 + t2 + t3 + t4
return round(1000 * result) / 1000
}
Usage:
let test = sin(90 * Double.pi / 180) // 90 degrees
print(test) // 1.0
The bug is obviously the c = 0, which you then multiply with more and more numbers... That's one of the situations where you can say "I don't know what that code does, but it's wrong".
sin x = x - x^3 / 3! + x^5 / 5! - x^7 / 7! etc.
A not completely inefficient approach is to start with the term x, and then figuring out how you get from one term to the next. You don't add up 1000 terms, that's ridiculous. You add up terms until adding the next term doesn't change the sum anymore.
And when you have this working, print sin (0.1), sin (0.2), say to sin (100.) and tell us if you find something unusual.

Convert Fisheye Video into regular Video

I have a video stream coming from a 180 degree fisheye camera. I want to do some image-processing to convert the fisheye view into a normal view.
After some research and lots of read articles I found this paper.
They describe an algorithm (and some formulas) to solve this problem.
I used tried to implement this method in a Matlab. Unfortunately it doesn't work, and I failed to make it work. The "corrected" image looks exactly like the original photograph and there's no any removal of distortion and secondly I am just receiving top left side of the image, not the complete image but changing the value of 'K' to 1.9 gives mw the whole image, but its exactly the same image.
Input image:
Result:
When the value of K is 1.15 as mentioned in the article
When the value of K is 1.9
Here is my code:
image = imread('image2.png');
[Cx, Cy, channel] = size(image);
k = 1.5;
f = (Cx * Cy)/3;
opw = fix(f * tan(asin(sin(atan((Cx/2)/f)) * k)));
oph = fix(f * tan(asin(sin(atan((Cy/2)/f)) * k)));
image_new = zeros(opw, oph,channel);
for i = 1: opw
for j = 1: oph
[theta,rho] = cart2pol(i,j);
R = f * tan(asin(sin(atan(rho/f)) * k));
r = f * tan(asin(sin(atan(R/f))/k));
X = ceil(r * cos(theta));
Y = ceil(r * sin(theta));
for k = 1: 3
image_new(i,j,k) = image(X,Y,k);
end
end
end
image_new = uint8(image_new);
warning('off', 'Images:initSize:adjustingMag');
imshow(image_new);
This is what solved my problem.
input:
strength as floating point >= 0. 0 = no change, high numbers equal stronger correction.
zoom as floating point >= 1. (1 = no change in zoom)
algorithm:
set halfWidth = imageWidth / 2
set halfHeight = imageHeight / 2
if strength = 0 then strength = 0.00001
set correctionRadius = squareroot(imageWidth ^ 2 + imageHeight ^ 2) / strength
for each pixel (x,y) in destinationImage
set newX = x - halfWidth
set newY = y - halfHeight
set distance = squareroot(newX ^ 2 + newY ^ 2)
set r = distance / correctionRadius
if r = 0 then
set theta = 1
else
set theta = arctangent(r) / r
set sourceX = halfWidth + theta * newX * zoom
set sourceY = halfHeight + theta * newY * zoom
set color of pixel (x, y) to color of source image pixel at (sourceX, sourceY)

Splitting method algorithm

(x^3 - 2x^2 - 5) is my equation.First of all I have two values like x = 2 and x = 4. My first two values must be count for equation and them results must be negative and positive each time. And second step is (2 + 4) / 2 = 3 this time x = 3 in equation. And the math operation continue with last one positive value and one negative value. I try this
var x = 2.0
var equation = pow(x, 3) - 2 * pow(x, 2) - 5
switch x {
case x : 2
equation = pow(x, 3) - 2 * pow(x, 2) - 5
case x : 4
equation = pow(x, 3) - 2 * pow(x, 2) - 5
default:
0
}
print(equation)
How can I assign first two values like 2 and 4 for one var x ?
Apparently you want to implement the bisection method to find the (real) solution (“root”) of an equation. The first step is to define that equation as a function, so that it can be evaluated at various points:
func f(_ x: Double) -> Double {
return pow(x, 3) - 2 * pow(x, 2) - 5
}
Then you need two variables for the left and right boundary of the current interval. These must be chosen such that f(x) has opposite signs at the boundaries. In your example:
var xleft = 2.0 // f(xleft) < 0
var xright = 4.0 // f(xright) > 0
Now you can start the iteration: Compute f(x) at the midpoint of the current interval, and replace xleft of xright, depending on whether f(x) is negative or positive. Continue until the approximation is good enough for your purposes:
let eps = 0.0000001 // Desired precision
let leftSign = f(xleft).sign
repeat {
let x = (xleft + xright)/2.0
let y = f(x)
if y == 0 {
xleft = x
break
} else if y.sign == leftSign {
xleft = x
} else {
xright = x
}
// print(xleft, xright)
} while xright - xleft > eps
// Print approximate solution:
print(xleft)
The next step would be to implement the bisection method itself as a function:
func bisect(_ f: ((Double) -> Double), xleft: Double, xright: Double, eps: Double = 1.0e-6) -> Double {
let yleft = f(xleft)
let yright = f(xright)
precondition(yleft * yright <= 0, "f must have opposite sign at the boundaries")
var xleft = xleft
var xright = xright
repeat {
let x = (xleft + xright)/2.0
let y = f(x)
if y == 0 {
return x
} else if y.sign == yleft.sign {
xleft = x
} else {
xright = x
}
} while xright - xleft > eps
return (xleft + xright)/2.0
}
so that it can be used with arbitrary equations:
let sol1 = bisect({ x in pow(x, 3) - 2 * pow(x, 2) - 5 }, xleft: 2.0, xright: 4.0)
print(sol1) // 2.690647602081299
let sol2 = bisect({ x in cos(x/2)}, xleft: 3.0, xright: 4.0, eps: 1.0e-15)
print(sol2) // 3.1415926535897936

What is kAccelerometerMinStep?

I have been looking at the Accelerometer Graph example in the iOS Developer library and I have a question about one of the variables that is used...
#define kAccelerometerMinStep 0.02
What is the Accelerometer Min Step? and what role does it have?
Here is how it is being used in the Low Pass Filter...
-(void)addAcceleration:(UIAcceleration*)accel
{
double alpha = filterConstant;
if(adaptive)
{
double d = Clamp(fabs(Norm(x, y, z) - Norm(accel.x, accel.y, accel.z)) / kAccelerometerMinStep - 1.0, 0.0, 1.0);
alpha = (1.0 - d) * filterConstant / kAccelerometerNoiseAttenuation + d * filterConstant;
}
x = accel.x * alpha + x * (1.0 - alpha);
y = accel.y * alpha + y * (1.0 - alpha);
z = accel.z * alpha + z * (1.0 - alpha);
}
And here is how it is being used in the High Pass Filter...
-(void)addAcceleration:(UIAcceleration*)accel
{
double alpha = filterConstant;
if(adaptive)
{
double d = Clamp(fabs(Norm(x, y, z) - Norm(accel.x, accel.y, accel.z)) / kAccelerometerMinStep - 1.0, 0.0, 1.0);
alpha = d * filterConstant / kAccelerometerNoiseAttenuation + (1.0 - d) * filterConstant;
}
x = alpha * (x + accel.x - lastX);
y = alpha * (y + accel.y - lastY);
z = alpha * (z + accel.z - lastZ);
lastX = accel.x;
lastY = accel.y;
lastZ = accel.z;
}
If someone could tell me what the min step is responsible for I would be very grateful...
I would like to capture accelerations ranging in magnitude from 0.05 to 2.00 g force with a frequency response of 0.25-2.50 Hz
Thanks.!