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
Last revisionBoth sides next revision
4rpl:commands:signalgenerator [2019/04/29 11:19] – edits for ctyle and clarity Karsten754rpl:commands:signalgenerator [2024/05/29 15:56] 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 ==== 
 +===  Time and Frequency === 
 +<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.txt · Last modified: 2024/05/29 15:57 by Grabz