User Tools

Site Tools


4rpl:commands:signalgenerator

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
4rpl:commands:signalgenerator [2019/04/29 11:19] – edits for ctyle and clarity Karsten754rpl:commands:signalgenerator [2024/05/29 15:57] (current) Grabz
Line 1: Line 1:
-~~NOTOC~~+<=[[4rpl:start| Index]] \\ 
 +<=[[4rpl:start#math_utility| Math Utility]] 
  
 ====== SignalGenerator ====== ====== SignalGenerator ======
-SignalGenerator(<-interval <-sigFrequency <-phaseShift false <-signalType) ->sigValue+SignalGenerator(<-time <-frequency <-phaseShift <-invert <-signalType) ->sigValue
  
 ===== Description ===== ===== Description =====
 Computes the value for a given signal waveform and pushes it to the stack. Computes the value for a given signal waveform and pushes it to the stack.
  
-A function to derive the y-coordinate for a given x-co-ordiante on a graph line following one of the indicated wave patterns. Uselful to animate an object or to a given pattern over time. Could be used for instance to vary output from an emitter. Oscillating rightness of light source or beacon; Oscillating strength of an emitter over time - both of these can be thought of as a a use case for this function.+A function to derive the y-coordinate for a given x-coordinate on a graph line following one of the indicated wave patterns.
  
-Arguments and type in order:  +Useful to animate an object or to produce a pattern over time. For instance, could be used  to vary the strength of an emitter over time, or to "pulse" (oscillate) the brightness of light source or beacon
-  - Integer. the X coordinate in the waveform (Eg. time  +
-  - Float. Frequency of the waveform   +
-  - Float. Phase Shift of the waveform   +
-  - Boolinvert the waveform +
-  - Integer. Signal type (0 to 6 in types, below)  +
  
-Signal types.  +Arguments and type in order: 
-  * 0 = NONE  +  * time: (float) Current step in the waveform. For a wave duration of 10.0, a step of 2.5 is a quarter of the way into a pattern
-  * 1 = SINE  +  * frequency: (float) The frequency dictates the duration of each repeating pattern. A duration of 10.0 must set the frequency to 0.1 (1/10.0) 
-  * 2 = SQUARE  +  * phaseShift: (float) A starting offset, between 0 and 1, where 0 will start the pattern at the beginning, and 1 will start it at the end. For sine wave, 0.25 will begin the wave at the peak, and 0.75 will begin at the valley. 
-  * 3 = TRIANGLE  +  * invert: (0/1) inverts the waveform 
-  * 4 = SAW-TOOTH  +  * signalType: (0 to 6) 
-  * 5 = RANDOM +     * 0 = NONE 
-  * 6 = CONSTANT +     * 1 = SINE 
 +     * 2 = SQUARE 
 +     * 3 = TRIANGLE 
 +     * 4 = SAW-TOOTH 
 +     * 5 = RANDOM 
 +     * 6 = CONSTANT
  
-=== Notes ===+The resulting variable sigValue contains a float value between -1 and 1 which represents the current state of the wave at the provided step (time) given its provided frequency and other factors.
  
-== Phase Shift== +===== Example ===== 
-The phase difference or phase shift as it is also called of Sinusoidal Waveform is the angle Φ (Greek letter Phi), in degrees or radians that the waveform has shifted from a certain reference point along the horizontal zero axis. In other words phase shift is the lateral difference between two or more waveforms along a common axis and sinusoidal waveforms of the same frequency can have a phase difference.+To create sine wave that should start at its peak and run for 80 frames until it repeats, we should set the frequency to (1.0/80.0), phase shift to 0.25, start the time value at 0 and add 1 to it every frame.
  
-The phase difference, Φ of an alternating waveform can vary from between 0 to its maximum time period, T of the waveform during one complete cycle and this can be anywhere along the horizontal axis between, Φ = to 2π (radians) or Φ  = to 360o depending upon the angular units used.+Play the following example in the editor console to spawn a continuous stream of creeper using the sine wave at the bottom of the map. 
 +<code 4RPL> 
 +$time:0 
 +$duration:80.0 
 +$phaseShift:0.25 
 +$invert:0 
 +$signalType:1
  
-===== Examples =====+SignalGenerator(<-time <-frequency <-phaseShift <-invert <-signalType) ->sigValue 
 +<-time 1 add ->time 
 + 
 +#Let's use the result to spawn some creeper in a range of cells: 
 +AddCreeper(<-time <-mapX mod, <-sigValue 20.0 mul 20 add, 1) 
 + 
 +:Once 
 +   1.0 <-duration div ->frequency 
 +   GetMapSize ->mapZ ->mapX 
 +</code> 
 + 
 +===== Patterns ===== 
 +[{{cw4_signalgenerator_1.png|1 - SINE, Pattern repeated every 60 cells}}] \\ 
 +[{{cw4_signalgenerator_2.png|2 - SQUARE, Pattern repeated every 60 cells}}]  
 +[{{cw4_signalgenerator_3.png|3 - TRIANGLE, Pattern repeated every 60 cells}}] \\ 
 +[{{cw4_signalgenerator_4.png|4 - SAW-TOOTH, Pattern repeated every 60 cells}}]  
 +[{{cw4_signalgenerator_5.png|5 - RANDOM, Pattern repeated every 5 cells}}] \\ 
 + 
 +===== Extra Notes ===== 
 +This is how each wave is produced in the game's source code: 
 +==== Sine wave function ==== 
 +<code C#> 
 +float t = frequency * time + phase; 
 +value = (float)Mathf.Sin(2f * Mathf.PI * t); 
 +</code> 
 +==== Square wave function ==== 
 +<code c#> 
 +value = Mathf.Sign(Mathf.Sin(2f * Mathf.PI * t));  
 +</code> 
 +==== For triangle wave function ==== 
 +<code c#> 
 +value = 1f - 4f * (float)Mathf.Abs(Mathf.Round(t - 0.25f) - (t - 0.25f)); 
 +</code> 
 +==== Saw-tooth wave function ==== 
 +<code c#> 
 +value = 2f * (t - (float)Mathf.Floor(t + 0.5f)); 
 +</code> 
 +==== Random wave function ==== 
 +The function will output the same number for a given interval.  Interval is 1/frequency.  It only changes to a new value on the next interval.  Hence a random number per interval, or a random number at a given frequency.  Otherwise, just use the rand functions to get a new value on each call. 
 + 
 +<code c#> 
 +float interval = 1 / frequency; 
 +int slot = (int)(time / interval) ; 
 +slot = (slot * 1431655781) + (slot * 1183186591) + (slot * 622729787) + (slot * 338294347); 
 +if (slot < 0) slot = -slot; 
 +value = (float)GameSpace.instance.RandDoubleInput(randSeed + slot)*2-1; 
 +</code> 
 + 
 +===== Extra examples ===== 
 +==== Sine Wave Creeper on Terrain ====
 <code 4rpl> <code 4rpl>
- On a map with terrain of 200 in X direction and at least 150 in Z direction (3D coordinates)+# On a map with terrain of 200 in X direction and at least 150 in Z direction (3D coordinates)
 # generate a sine wave of creeper across the map. # generate a sine wave of creeper across the map.
-200    ->numFrames +# On a map with terrain of 200 in X direction and at least 150 in Z direction (3D coordinates) 
-      ->frequency (div (AsFloat (<-numFrames))) +# generate a sine wave of creeper across the map. 
-    ->phaseShift+ 
 +180 ->numFrames  # at 30 frames a sec, cycle every 6 seconds. 
 +1 <-numFrames asFloat div ->frequency #stepsize 
 +0 ->phaseShift
 false ->invert false ->invert
-    ->signalType #sine+1 ->signalType  #sine
  
-do  (<-numFrames 0) +do (<-numFrames 0) 
-    SignalGenerator(I <-frequency <-phaseShift <-invert <-signalType )  ->sigValue +    SignalGenerator(I <-frequency <-phaseShift <-invert <-signalType) ->sigValue 
-    round (<-sigValue2) ->sigValue +    Round(<-sigValue 2) ->sigValue 
-    print3 (I " : " <-sigValue ) +    TraceAllSp (I " : " <-sigValue) 
-    SetCreeper(I 75 add (<-sigValue mul (50)) 15 true)+    SetCreeper(I 75 add(<-sigValue mul(50)) 15 true)
 loop loop
 </code> </code>
  
 +The above command generated this sinusoidal creeper pattern on a map 
 +
 +{{sine_creeper.png?450}}
 +
 +==== Make a Unit Move or "Float" Above Terrain ====
 +
 +<code 4RPL> 
 +# Oscillate
 +$UID:1
 +
 +GetUnitMoveCell(<-UID) ->cellZ ->cellX
 +if (<-cellz  -1 EQ)
 + SignalGenerator(<-time , <-frequency , <-phaseShift , <-invert , <-signaltype) ->sigValue
 + <-time 1 + ->time
 + <-sigvalue 1 + <-scale * ->sigvalue
 + GetUnitPosition(<-UID) ->pos
 + GetExactTerrain(<-pos.X <-pos.Z false) ->exactTerrainHeight
 + SetUnitPosition(<-UID V3(<-pos.x , <-exactTerrainHeight <-sigvalue + , <-pos.z)) # Buil-in unit
 + # SetObjPosition(2  "" V3(0 <-sigValue 0) false)          # for custom unit
 +else
 + 0 ->time
 +endIf
 +
 +:Once
 + # Parameters for SignalGenerator
 + 1.0  180 / ->frequency  # we cycle over 180 frames
 + 0.0 ->phaseShift # offset from zero-time
 + false ->invert # Invert the waveform
 + 1 ->signalType # type of signal generated
 + 0.5 ->scale # control the maximum size of movement
 +</code>
 +
 +<=[[4rpl:start| Index]]
4rpl/commands/signalgenerator.1556551151.txt.gz · Last modified: 2019/04/29 11:19 by Karsten75