Skip to content
Forum Archive

Tips&Tricks in AVS

274 posts

mikm#
Originally posted by Raz_001
This isn't supposed to help anyone in particular, just anything that may be useful to anyone goes in here.
yeah...I see it as an FAQ for regulars and a good knowledge base of code.
NemoOrange#
you know what, I may not be a regular here at the forums, but I've been AVSing for 2 years now, & I'm just baffled by all those equations & whatnot.

when I think 'tips & tricks" i don't think multi-line formulas for some complicated effect.

alright, enough bitching.
anubis2003#
So then make your own tips and tricks for aesthetics. I would, but I'm not that good at aesthetics.
NemoOrange#
here I am with my foot in my mouth. I'm looking for some code that would treat a DynMove kinda like a basic sprite (if that makes sense, I'm no good with programming talk). All I want this DM to do is move around in a 3-D environment: move up & down, left & right, near & far. I tried looking here, but nothign really popped out. Does anyone have a uncomplicated way of doing this?
mikm#
hmm...I didn't know there were more than one flavors of Sprite 😛


So you want to move the AVS around and zoom in and out?

That's very easy:

frame:
Rectangular coordiantes on

xm=(insert x movement code here);
ym=(insert x movement code here);
zm=(insert x movement code here);
zoom=1/z;

pixel:
x=(x+xm)*zoom;
y=(y+ym)*zoom;
of course, this will not handle rotation...if you want that, there was a post a while back.

If you want to move a single object around against a static background, then you need to synchronize SSCs.

This can be achieved by using a pseudorandom number generator.

(search the forums for synchronzing superscopes, there will be a much better explanation than I can do here).
jheriko#
Well. As long as your sprite has a black border we can do this one fine with some cheaty psuedo 3D code. Here is a simple dm that I quickly wrote to demonstrate this.

Per Frame:

dz=sin(t)+1.2;
dx=cos(t);
dy=sin(2*t);
t=t+0.01;
z=1/(dz*0.5);

Per Point:

x=(x+dx)*z;
y=(y+dy)*z;

This works fine z for co-ordinates strictly greater than zero. Here dx, dy and dz represent the displacement of the sprite in the varying axes. A gridsize should be set for this, preferably large since it has to shrink the sprite sometimes. Set wrap to 'off' and we are done. If you want to draw the sprite over a background then simply chuck it in an effect list and use additive blending.

Unless you want your sprite to rotate in 3D too then this should be enough.
shreyas_potnis#
Conversion of polar co-ords. into rectangular ones and vice-versa:

to convert polar co-ords. into rectangular ones, use:

x=sin(r)*d
y=cos(r)*d

to convert rectangular co-ords. into polar ones, use:

d=sqrt(sqr(x)+sqr(y))
r=atan2(x,y)

I hope I am right, correct me if I am not.

I can explain, how d=sqrt(sqr(x)+sqr(y)) works.

So, here's the deal:

suppose x=.8 and y=.6, then the position of point point would be:


y-axis
^
|
|P Q
|.6- - - - - - -.(.8,.6)
| |
| |
|S |R
x-axis <- - - - - - - - - - - - - - - - >
|(0,0) .8
|
|
|
|
|
|

(this is an approximate figure)
PQRS is the quadrilaeral formed.
Now, we have to find l(SQ) or d(S,Q)
I will solve this as we solve our geomtery problems,
as this will give you a more clear idea.

Given:
1) line x is perpendicaular to line y.
2) d(S,R)=.8 , d(P,S)=.6
3) seg PQ is perpendicular to line y & seg RQ is perpendicular to line x.

to find: d(S,Q) i.e length of seg SQ.
Construction: Draw seg SQ ( I could'nt draw it here ) .
Sol'n:
Statement |Reason
1) In, quad. PQRS, |
m<S=m<P=m<Q=m<R=90 degrees |statement 1 & 3 of Given.
|
2) quad. PQRS is a rectangle. |Statement 1) and def'n of a rectangle.
|
3) seg PS is congreuent to seg QR |statement 2) and opposite sides of a
| rectangle are congruent.
|
4) In triangle SQR, |given statement 2) and statement 3)
seg SR = .8 and seg QR = .6 |
|
5) In triangle SQR, |

SQ^2 = SR^2 + SQ^2 |Pythagorus theorem.
<=> SQ = sqrt ( SR^2 + SQ^2 )
<=> SQ = sqrt ( .8^2 + .6^2 )
<=> SQ = sqrt ( .64 + .36 )
= sqrt ( 1.00 )
= 1
therefore SQ = 1

here, SQ = d
so sqr ( d ) = sqr ( SR ) + sqr ( RQ )
= sqr ( X ) + sqr ( Y ) ( not the lines, but the position of the point )
<=> d = sqrt ( sqr ( X ) + sqr ( Y )

It would be nice if someone explained how r=atan2(x,y) works.

NOte: my first experiment without smiley's *I smile*
anubis2003#
You just tried making that way too difficult.
first off:
x=d*cos(r)
y=d*sin(r)

you can get this merely by looking at the triangle. R is the angle and d is the hypotenuse(sp). Simple trig tells you that
cos(r)=x/d
sin(r)=y/d

so those two equations are easy to derive.
then, using pythagorean theorem
d^2=x^2+y^2
Also simple.
and then
tan(r)=y/x
simple again.
Jaheckelsafar#
Going up 2 posts here...

The grid size in a DM won't affect quality unless you're trying to bend the picture. Full pic zooming and rotation will only be slowed down by a larger grid size.

That and I like to reduce the movement speed when zoomed out. To do so, multiply the move values by the inverse of you zoom.

Now enough out of me.
dirkdeftly#
A couple tricks I'm playing around with...

The classic "floating squares" effect:
EL (ignore, every other pixel)
.Invert
[Optional: EL (ignore, evey other line)
.Invert]
Rotozoomer
can be enhanced with random coloring of the squares using this method:
Invert
Grain
EL (ignore, multiply)
.EL (ignore, every other pixel)
..Invert
.[Optional: EL (ignore, evey other line)
..Invert]
Colormap
Rotozoomer

Also, I've discovered a sort hack to make a cycling color palette using Colormap. It's rather cumbersome and it's not perfect, but here's how it works:
Custom BPM - invert
Custom BPM - skip x beats
Color map
The color map must have several rotating positions of a cyclic palette, and be set to "Onbeat cycle". A nice sort of hue shifter can be created this way.
It'd be rather neat if we could actually wheedle a real cycler out of ucd, with dynamic cycle position 'n' stuff.... 😁
AVS Axer#edited
somone asked how atan2 works:

in case you didnt already know.. asin, acos and atan are the inverse functions of sin cos and tan.

dont be confused however and think that asin(sin(x)), will neccessarily return x. Thnk of a circle and acknowledge that no matter how many times you got around the circle, sin(x) will always be the same at the same point of the circle. Now imagine that x is more than 2*pi (the circumference), this is just like going around a circle more than once, so all the values will be the same.

The trouble with asin, acos and atan is that they do not even return the right values of x all the way around a circle!! Dont get me wrong, they have their uses. Consider sin(x) again, this finction will return 0 in two different positions while 0>x>2pi. one at 0 and one at pi. Now you can see that asin(sin(x)) will definatly not return the right values of x, because sin(x) has a pattern, but x does not.

In reality, asin(sin(x)) will return x for only the first quadrant,
After that x is reset to 0 at the start of every new quadrant. And with these rules.
First quadrant: Asin(sin(x)) = x
second quadrant:Asin(sin(x)) = 2pi-x
third quadrant: Asin(sin(x)) = -x
fourth quadrant:Asin(sin(x)) = -2pi+x

Look at a unit circle or play around in avs and youll get how this works. Try this in a superscope:
y=atan(tan(i*acos(-1)*2))/5;
x=i/5
and try replacing atan and tan with asin and sin. etc.

To counter this, atan2 was invented.. pretty much you input two coordinates of a point (x,y) and it does something similar to atan(x/y) but it acknowledges that they are coodinates of the same point and works it out in some clever way that i dont yet know.

So, atan2(x,y) returns the angle of the point x,y in radians from center (0,0).
If you look at alot of code however, people in avs have tended to use atan2(x,-y). This is because the y axis in avs is fliped. In trig we start from the bottom and goto top. I dont know why..

It is also convention to start from the right at -1 and got anti clockwise around the circle.. (first quadrant is at top left). So i dont know why we arnt using atan2(-x,-y) but i wont argue because fsk and unconed use the other way, and they seem to know their shit.

Correct me on anyof this please.. cause i could have easily have got confused. Oh, and if someone knew exactly how the function is calculated, it would be most helpful.
AVS Axer#edited
XOR blending mode was also asked about somewhere..

Sadly itsnot as simple as you would hope.

Xor is computed at the binary level.
So, each pixel has the compondents r,g,b (depending on how old your comp is ho ho.)
And each r,g, or b, can be described as a binary digit. (or bit)
(0000,0000).

ok.. lets lets just look at one channel, say r. and just one pixel.
we have A=0010,1010, B=0101,0111

dont wory about what those colours are, or even what those numbers are, i dont know either.

For this demo, A is the old image, B is the blending image.

A XOR B means the same as (A OR B)NOT(A AND B)
in binary logic, 0 is false, 1 is true.

so it will return "TRUE"(1) if a OR b are 1, but "FALSE"(0) if a AND b are both 1, and 0 if neither a OR b are 1.

so:
a-----=(00111010)
b-----=(01010111)
aXORb-=(01101101)

you see now?

This is applied to all colour chanels and the same to every pixel.

Notice some things..

*if image A and B are the same, the whole screen would be black,

*two completely different solid colours (different in all r,g and b), the whole screen would be white.

*any identicle pixels would be shaded black
shreyas_potnis#
some friend of mine told that XOR is used in encryption.
e.g
if x XOR y = z
then y XOR z = x
( thats what he told me)
AVS Axer#
Well, xor is not just graphics, it is a logic operator just like AND, NOR, OR etc. It can be used in anything.
But i think your friend got that encryption idea wrong, i have also heard of it beign used for this, and i simply assumed that it uses the same binary xor method as mentioned above.
AVS Axer#
Well, as it often happens, i was wrong..
i looked at the idea more carefully and youre friend was right shreyas.
One of the outcomes of the xor operation is that it can be inverted easily.
yes,
if x XOR y = z
then y XOR z = x

so you can decrypt z(the encryption) to get x(the original) so long as you have y (which acts as a sort of mask).

This applied to avs.

if you were to XOR blend imageA with imageB, you would get imageC
you could then XOR blend image B with imageC and you would get youre original imageA back!!! wowee...
i didnt know that untill shreyas pointed it out.. very clever, but not very useful...
UnConeD#
About atan2... you got one detail wrong. In a mathematical coordinate system, the angle for (x,y) with regard to the positive x axis is atan(y/x), not atan(x/y).

By the way, you can imagine atan2 to be the same as this, except that atan2 can also handle the cases where x and/or y is 0:

alpha=atan(y/x)+below(x,0)*acos(-1);
mikm#
Transparencies

do your 'background stuff'
add a replace buffersave to #1

do the 'over stuff'
replace buffersave to #2
multiply --> infinite square
invert

effect list (ignore/multiply)
..buffer restore (replace) #1
[end effect list]
buffer restore (max) #2

(there might be a better way, this is what I have found to work)
AVS Axer#
switches:

---------------
binary: sw=1-sw
---------------
'sw' will switch from 1 to 0 every time the code is run. Because it is binary, you can use simple maths to get ANY two numbers from this switch:
sw2=sw*(difference between desired numbers)+(lowest desired number)

Superscope example (use dots, not lines):
sw=1-sw;
y=getosc(i,0,0)*0.2+(sw-0.5)*0.5;
x=2*i-1;

-------------------------------------
Other Switches: t=t+1; sw=t%ns;
Where ns is the number of switches.)
---------------------------------------
sw will progress through 0 to ns and then loop.

Superscope example:
t=t+1;
sw=(t%7);
v=getspec(sw/7+i/7,0,0);
x=v*0.2+((sw*0.2)-0.6)*1.5;
y=2*i-1;
UnConeD#
AVS axer: actually no. The line below the one you 'corrected' uses atan to imitate atan2. Therefore it should still be "You can imagine atan2 to be the same as this...." ('this' refers to that line of code).
AVS Axer#
Sorry, i should have checked with yu first... i thought 'this' was referring to the bit above, not the bit below..
Jaheckelsafar#
percent value

ll : lower limit
hl : higher limit
val : value

(val-ll)/(hl-ll)

gives a number between 0 and 1 for a number between the lower limit and the higher limit.
sidd#
uh, no.. not at all

his method keeps the scale linear.

(0.5*sin(val)+1) would return a soinsoid of val between 0 and 1. in other words it loops, and doesnt really produce a version of the variable 'val'.

(val-ll)/(hl-ll)
would return val exactly, only scaled between 1 and 0, instead of high limit and low limit. The variable remains linear
sidd#
I came up with this a while back and have been usingit heaps, thought it might be useful to everyone out there.

This converts hue,sat,lum color mode to r,g,b. So you can have more control over your color coding in superscopes. all hue sat and lum values are between 0 and 1. Hue, follows red-> green-> blue in 1/3 sections.

For all those who dont know, hue is the color, sat is the intensity of that color, and lum is the amount of black(0) or white(1) in that colour.

As you can imagin, the code is VERY useful, but unfortunatly isnt as small as one would like, it takes up 11 variables!!, i might be able to make that 8 but its tricky.

hue=1;
lum=0.5;
sat=t;
tm2=if(below(lum,0.5),lum*(1+sat),lum+sat-lum*sat);
tm1=2*lum-tm2;
tm3r=hue+1/3;
tm3g=hue;
tm3b=hue-1/3;
tm3r=if(above(tm3r,1),tm3r-1,if(below(tm3r,0),tm3r+1,tm3r));
tm3g=if(above(tm3g,1),tm3g-1,if(below(tm3g,0),tm3g+1,tm3g));
tm3b=if(above(tm3b,1),tm3b-1,if(below(tm3b,0),tm3b+1,tm3b));
rd=if(below(6*tm3r,1),tm1+(tm2-tm1)*6*tm3r,if(below(2*tm3r,1),
tm2,if(below(tm3r*3,2),tm1+(tm2-tm1)*((2/3)-tm3r)*6,tm1)));
gr=if(below(6*tm3g,1),tm1+(tm2-tm1)*6*tm3g,if(below(2*tm3g,1),
tm2,if(below(tm3g*3,2),tm1+(tm2-tm1)*((2/3)-tm3g)*6,tm1)));
bl=if(below(6*tm3b,1),tm1+(tm2-tm1)*6*tm3b,if(below(2*tm3b,1),
tm2,if(below(tm3b*3,2),tm1+(tm2-tm1)*((2/3)-tm3b)*6,tm1)));
green=if(sat,gr,lum);
blue=if(sat,bl,lum);
red=if(sat,rd,lum);
Montana#
hsv to rgb, fast version

init: tpi=acos(-1)*2; pit=tpi/6; tpit=pit*2;
pixel:
sat2=sat*0.5; hue2=hue*tpi;
red=abs(sin(hue2))*sat2+lum;
green=abs(sin(hue2+pit))*sat2+lum;
blue=abs(sin(hue2+tpit))*sat2+lum;
sidd#
nice work!! few problems with it obviously, cuz its simplifying a complicated process into only a few lines. luminuesence isnt scalar, nor is it dithered between colours correctly. Same deal with saturation. for example, 0 lum should make it black regarless.
all values should be between 0-1, or something else as long as it is finite. And the line 'hue2=hue*tpi' should be just hue*pi.

Im gonna use your code when i just need a nice color fading code, but ill stick with the other way for accuracy.