interpolate animation value in flutter - flutter

If I want to convert a range from 0.0 to 1.0, into a range from 20.0 to 80.0, I can use lerpDouble(20.0, 80.0, animationValue).
How do I convert a range from 0.8 to 1.0, into a range from 0.0 to 1.0?

After some digging I found a simple solution to the problem:
final value = Interval(0.8, 1.0).transform(animationValue);

Dear you can use this plugging to animation in a flutter Here Link

You can use this:
(lerpDouble(0.8, 1.0, animationValue) * 1.0/0.2) - 4.0
When:
animationValue=0.8 => (0.8*5)-4.0 = 0.0
animationValue=1.0 => (1.0*5)-4.0 = 1.0
This is to do the other way round:
0.8 + 0.2 * lerpDouble(0.0, 1.0, animationValue)
When:
animationValue=0.0 => 0.8+(0.2*0) = 0.8
animationValue=1.0 => 0.8+(0.2*1) = 1.0

Related

In scene kit, SCNPhysicsField.noiseField seems to just terminate, end, after a few seconds

Have an SCNNode, add a physics body,
physicsBody = SCNPhysicsBody(type: .dynamic, shape: ..)
physicsBody?.isAffectedByGravity = false
Now add a physics field, for example
physicsField = SCNPhysicsField.noiseField(smoothness: 0.2, animationSpeed: 0.01)
physicsField?.strength = 0.05
It works perfectly. In this case, .noise , the object will jiggle around.
However after a few seconds (often 7 seconds, sometimes a different length of time), the object will simply stop moving.
(The three values, smoothness speed and strength, make no difference if you change them - it will still end after a few seconds.)
What's the solution to this mystery?
Just to be clear, I never used a SCNPhysicsField.noiseField, but I used one of type SCNPhysicsField.linearGravity and another of type SCNPhysicsField.customField and both of them are working correctly and do not stop unexpected as you describe.
here are my examples:
let attractionField = SCNPhysicsField.linearGravity()
attractionField.halfExtent = SCNVector3(250.0, 35.0, 60.0)
attractionField.direction = SCNVector3(-1.0, 0.0, 0.0)
attractionField.strength = 0.2 // 0.15
attractionNode.physicsField = attractionField
and the other one, (which I used to create a tornado):
private func addCustomVortexField() {
// Tornado Particles Field
let worldOrigin = stormNode.presentation.worldPosition
let worldAxis = simd_float3(0.0, 1.0, 0.0)
let customVortexField = SCNPhysicsField.customField(evaluationBlock: { position, velocity, mass, charge, time in
let l = simd_float3(worldOrigin.x - position.x, 1.0, worldOrigin.z - position.z)
let t = simd_cross(worldAxis, l)
let d2: Float = l.x * l.x + l.z * l.z
let vs: Float = 27 / sqrt(d2) // diameter, the bigger the value the wider it becomes
let fy: Float = 1.0 - Float((min(1.0, (position.y / 240.0)))) // rotations, a higher value means more turn arounds (more screwed)
return SCNVector3Make(t.x * vs + l.x * 10 * fy, 0, t.z * vs + l.z * 10 * fy)
})
customVortexField.halfExtent = SCNVector3Make(100, 100, 100)
stormNode.physicsField = customVortexField
stormNode.physicsField?.categoryBitMask = BitMasks.BitmaskTornadoField
}
I hope this is gonna help you in some way. You can also provide me your project, and I will have a look at it.

for (increase time delay) depending on object count

A math question. I am trying to animate objects sequentially, but I can't figure out formula which will allow me to set a delay smoothly. If I have, lets say, 2 object in my array I want them to animate almost normally with i*0.25 delay, but if I have 25 objects I want them to animate rather quickly. Yes I can try to set manual ratio switching the .count, but I think there should be a nice formula for this?
for (i,object) in objects.enumerated() {
object.animate(withDelay: (i * 0.25) / objects.count)
}
Your best bet is to choose an animation time that will happen EVERY time, no matter the # of variables.
let animateTime = 2 // 2 secs
let animateTimePerObject:Double = animateTime/objects.count
for (i,object) in objects.enumerated() {
object.animate(withDelay: (i * animateTimePerObject)
}
Say there are 10 objects, and you want to animate for 2 seconds. This will set animateTimePerObject = 2/10 = .2 Each item will be delayed by i (whatever position they are at) * the animatetime per object. So in order, 0, 0.2, 0.4, 0.6, 0.8, 0.1, 0.12, 0.14, 0.16, 0.18, 0.2.
Same could be done with 2 objects.
OR you could do a log function that would allow for growth but at a slower rate. Here are some functions you could look at using.
Add this function to create a custom log functionality
func logC(val: Double, forBase base: Double) -> Double {
return log(val)/log(base)
}
for (i,object) in objects.enumerated() {
let delay = i == 0 ? .25 : logC(Double(i)*10, forBase: 10) * 0.25
object.animate(withDelay: delay)
}
This will slow down your 0.25*i rate to a much slower one.
0 -> .25
1 -> Log(20, base: 10) = 1.3 * 0.25 = .325
...
25 -> Log(250, base: 10) = 2.3979 * 0.25 = .6
where it would have been
0 -> .25
1 -> .25 * 2 = .5
25 -> .25 * 25 = 6.25
You can play with the log function as you like, but these are just some ideas. It's not precise as to what kind of algorithm you are looking for.
NOTE: May be syntax issues in there slightly, with the Doubles and Ints but you can adjust! :)
Comparing Log and Sqrt:
func logC(val: Double, forBase base: Double) -> Double {
return log(val)/log(base)
}
for i in 0..<25 {
let delay = i == 0 ? 0.25 : pow(logC(val: Double(i)*10, forBase: 10) * 0.25, log(1/Double(i))) * 0.45
let delay2 = i == 0 ? 0.25 : sqrt(Double(i)) * 0.5
print(delay, delay2)
}
0.25 0.25
0.45 0.5
0.9801911408397829 0.7071067811865476
1.3443747821649137 0.8660254037844386
1.5999258430124579 1.0
1.7853405889097305 1.118033988749895
1.9234257236285595 1.224744871391589
2.0282300761096543 1.3228756555322954
2.1088308307833894 1.4142135623730951
2.1713433790123178 1.5
2.2200343505615683 1.5811388300841898
2.2579686175608598 1.6583123951777
2.2874024254699274 1.7320508075688772
2.3100316733059247 1.8027756377319946
2.32715403828525 1.8708286933869707
2.33977794890637 1.9364916731037085
2.348697701417663 2.0
2.3545463958925756 2.0615528128088303
2.357833976756366 2.1213203435596424
2.358975047645847 2.179449471770337
2.35830952737025 2.23606797749979
2.3561182050020992 2.29128784747792
2.35263460234384 2.345207879911715
2.348054124507179 2.3979157616563596
2.3425411926260447 2.449489742783178
You can go with the function below, which depends on the object count as you specified earlier and if the array will have more objects each animation will be executed with less delay but nonetheless first item's delay will be longer than latter:
for (i,object) in objects.enumerated() {
object.animate(withDelay: ((1/((i+1)*0.5)) * 0.25) / objects.count)
}
There are a lot of parantheses but I hope it will increase readability, also I applied i+1 so you wont have division by zero problem for the first item.
With this formula I hope the delay will diminish gradually and smoothly when your array has large amount of objects.
Note:
If you think delay is too much when there are not much elements in the array (which will lower the "objects.count" number. Try replacing objects.count with (2 * objects.count)
Also if you think the reverse (delay is not much) when there are a lot of elements in the array (which will increase the "objects.count" number. Try replacing objects.count with (objects.count / 2)

Is the Swift divide "/" operator not working or have I missed something?

I am trying to initialise the following array of fractions in a Swift playground
var probabilitiesX = Array(repeating: Double(1/36), count: 36)
but my output array is:
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
basically all zeros. If I type in the fraction as a decimal "0.02777777" then I get the correct output however I am using various fractions and ideally do not want to have to type them all out.
Any ideas?
Your problem is here: 1/36. Both 1 and 36 are Ints. Try this:
var probabilitiesX = Array(repeating: 1.0 / 36.0, count: 36)
It appears that you are aware of the fact that 1/36 produces 0 because of integer division. This is probably why you wrote Double(1/36) to make Swift treat 1/36 as a double.
However, Swift evaluates the expression in a different order than you think. Swift will evaluate 1/36 first, then evaluate Double(0).
If you want to use Double.init in your code, you can do it like this:
Double(1)/Double(36)
Now, both 1 and 36 are converted to a double before the division. Therefore, no integer division occurs.
In fact, you don't need Double at all, just do:
1.0 / 36.0
Both 1.0 and 36.0 are Double literals.
As other answers have noted, the problem is that the 1 and 36 are inferred to be of type Int, so 1/36 is performed using integer divide with a result of 0. That is then passed to Double() which creates a Double from the 0.
There are a number of ways you could fix this:
Use floating point literals which will be inferred to be Doubles:
var probabilitiesX = Array(repeating: 1.0/36.0, count: 36)
You can get away with only using a floating point literal for one of them because Swift will infer that the other has to be a Double for divide to work:
var probabilitiesX = Array(repeating: 1/36.0, count: 36)
or
var probabilitiesX = Array(repeating: 1.0/36, count: 36)
Convert either or both of 1 and 36 to Double:
var probabilitiesX = Array(repeating: Double(1)/36, count: 36)
or
var probabilitiesX = Array(repeating: 1/Double(36), count: 36)
or
var probabilitiesX = Array(repeating: Double(1)/Double(36), count: 36)
Cast 1/36 with as Double:
var probabilitiesX = Array(repeating: 1/36 as Double, count: 36)
In this case, since Swift knows the result of the division is a Double, it is able to infer that 1 and 36 are Doubles because the only version of division that results in a Double is the one that takes two Doubles as input.
Tell Swift you are creating a [Double]:
var probabilitiesX = [Double](repeating: 1/36, count: 36)
or
var probabilitiesX: [Double] = Array(repeating: 1/36, count: 36)
In this case, since Swift knows the array contains Double, then it is able to infer that 1/36 is a Double and like #3 it then infers that 1 and 36 are Doubles as well because the only version of division that results in a Double is the one that takes two Doubles as input.

Neural networks example using MXNet in Julia

I'm trying to build a neural network that can answer to the xor problem. My code is the following:
using MXNet
using Distributions
using PyPlot
xor_data = zeros(4,2)
xor_data[1:0] = 1
xor_data[1:1] = 1
xor_data[2:0] = 1
xor_data[2:1] = 0
xor_data[3:0] = 0
xor_data[3:1] = 1
xor_data[4:0] = 0
xor_data[4:1] = 0
xor_labels = zeros(4)
xor_labels[1] = 0
xor_labels[2] = 1
xor_labels[3] = 1
xor_labels[4] = 0
batchsize = 4
trainprovider = mx.ArrayDataProvider(:data => xor_data, batch_size=batchsize, shuffle=true, :label => xor_labels)
evalprovider = mx.ArrayDataProvider(:data => xor_data, batch_size=batchsize, shuffle=true, :label => xor_labels)
data = mx.Variable(:data)
label = mx.Variable(:label)
net = #mx.chain mx.Variable(:data) =>
mx.FullyConnected(num_hidden=2) =>
mx.Activation(act_type=:relu) =>
mx.FullyConnected(num_hidden=2) =>
mx.Activation(act_type=:relu) =>
mx.FullyConnected(num_hidden=1) =>
mx.Activation(act_type=:relu) =>
model = mx.FeedForward(net, context=mx.cpu())
optimizer = mx.SGD(lr=0.01, momentum=0.9, weight_decay=0.00001)
initializer = mx.NormalInitializer(0.0,0.1)
eval_metric = mx.MSE()
mx.fit(model, optimizer, initializer, eval_metric, trainprovider, eval_data = evalprovider, n_epoch = 100)
mx.fit(model, optimizer, eval_metric, trainprovider, eval_data = evalprovider, n_epoch = 100)
But I'm getting the following error:
LoadError: AssertionError: Number of samples in label is mismatch
with data
in expression starting on line 22 in #ArrayDataProvider#6428(::Int64,
::Bool, ::Int64, ::Int64, ::Type{T}, ::Pair{Symbol,Array{Float64,2}},
::Pair{Symbol,Array{Float64,1}}) at io.jl:324 in
(::Core.#kw#Type)(::Array{Any,1}, ::Type{MXNet.mx.ArrayDataProvider},
::Pair{Symbol,Array{Float64,2}}, ::Pair{Symbol,Array{Float64,1}}) at
:0 in include_string(::String, ::String) at loading.jl:441
in include_string(::String, ::String) at sys.dylib:? in
include_string(::Module, ::String, ::String) at eval.jl:32 in
(::Atom.##59#62{String,String})() at eval.jl:81 in
withpath(::Atom.##59#62{String,String}, ::String) at utils.jl:30 in
withpath(::Function, ::String) at eval.jl:46 in macro expansion at
eval.jl:79 [inlined] in (::Atom.##58#61{Dict{String,Any}})() at
task.jl:60
I want to feed to the network to values (0 or 1) and get a single value. Were is my error?
Dimensions of xor_data are wrong, it should have 4 columns, not 4 rows (and, by the way, you're not initialising it the way you think you do, since arrays in Julia are indexed from 1, not from 0).
Look:
julia> xor_data = [ [1. 1]; [0 1]; [1 0]; [0 0] ]
4×2 Array{Float64,2}:
1.0 1.0
0.0 1.0
1.0 0.0
0.0 0.0
julia> xor_labels
4-element Array{Float64,1}:
0.0
1.0
1.0
0.0
julia> mx.ArrayDataProvider(:data => xor_data, :labels => xor_labels)
ERROR: AssertionError: Number of samples in labels is mismatch with data
in #ArrayDataProvider#6428(::Int64, ::Bool, ::Int64, ::Int64, ::Type{T}, ::Pair{Symbol,Array{Float64,2}}, ::Pair{Symbol,Array{Float64,1}}) at /Users/alexey/.julia/v0.5/MXNet/src/io.jl:324
in MXNet.mx.ArrayDataProvider(::Pair{Symbol,Array{Float64,2}}, ::Pair{Symbol,Array{Float64,1}}) at /Users/alexey/.julia/v0.5/MXNet/src/io.jl:280
julia> xor_data = [ [1. 0 1 0]; [1 1 0 0] ]
2×4 Array{Float64,2}:
1.0 0.0 1.0 0.0
1.0 1.0 0.0 0.0
julia> mx.ArrayDataProvider(:data => xor_data, :labels => xor_labels)
MXNet.mx.ArrayDataProvider(Array{Float32,N}[
Float32[1.0 0.0 1.0 0.0; 1.0 1.0 0.0 0.0]],Symbol[:data],Array{Float32,N}[
Float32[0.0 1.0 1.0 0.0]],Symbol[:labels],4,4,false,0.0f0,0.0f0,MXNet.mx.NDArray[mx.NDArray{Float32}(2,4)],MXNet.mx.NDArray[mx.NDArray{Float32}(4,)])

Gate of float in swift

I have a piece of code as:
let gate = 0.0 // 1.4 1.3 1.2
let xGate = NSNumber(value: gate)
let xValue = Double(round(xGate.floatValue*100)/100)
switch xValue {
case _ where xValue > gate: print("large")
case _ where xValue < gate: print("little")
default: print("gate")
}
I want to make a float value as my Gate, and it works when I set gate such as 0.0 1.0 2.0, but it fails as 1.1, 1.2 etc.
My question is: is it really safe for 0,0 1.0, 1.5, 2.0 3.0, although these number pass the test?