Harmonic Effects On A Sine Wave
I had posted a portion of this a couple of days ago but thought I would post the rest in case it might be useful. I hope all the code gets attached. It is helpful for demonstrating the effects of harmonic content in a power system on the sine wave. The individual harmonic percentages are expressed as a percentage of the fundamental (sine wave). I am attaching the script in parts because Attach Code will not let me attach it all in one go.
Here are the first 400 lines
Attach Code
//This is designed for MX 2004
//I think the movie works best at about 30 fps
fscommand("allowscale",true);
fscommand("fullscreen",true);
mouse_listener = new Object();
mouse_listener.onMouseDown = function() {
recalculate_THD();
movesliders();
}
Mouse.addListener(mouse_listener);
//update the harmonics array based on the digital input
//redisplay that digital input with the correct number of decimal places
//calculate the sum of the individual harmonics and update the display
//update the THD display value
//
function recalculate_THD() {
total_harmonic_distortion = 0;//initialize this variable
for(var i = 1; i < harmonics.length; i++) {
harmonics[i]["myamount"] = Number(this.sliders["digital" + i].text_holder.harmonic_percent.text)/100;
this.sliders["digital" + i].text_holder.harmonic_percent.text = String(limit_decimals(Number(harmonics[i]["myamount"])*100));
total_harmonic_distortion = total_harmonic_distortion + Number(harmonics[i]["myamount"]) * Number(harmonics[i]["myamount"]);
}
total_harmonic_distortion = Math.round(Math.sqrt(total_harmonic_distortion)*10000)/100;
this.harmonicsdata["harmonics_value"].text = String(total_harmonic_distortion);
}
//resposition the slider buttons according the the harmonic percentages currently contained in the array
function movesliders() {
for(var i = 0;i < harmonics.length; i++) {
this.sliders["button" + i]._y = -harmonics[i]["myamount"]*100;
}
}
function update_digital_input() {
for(var i = 1; i < harmonics.length; i++) {
this.sliders["digital" + i].text_holder.harmonic_percent.text = String(limit_decimals(Number(harmonics[i]["myamount"])*100));
}
}
function sinewaves_defined_enterframe() {
this._parent._parent.sine.sinewave.onEnterFrame = function() {
if(this.i >= this._parent._parent.res*10) {
this.i = 0;
}
var current_x = this.i;
update_xy_array (current_x);
this._parent._y + add_harmonics(current_x) * my_yscale / 100;
this.i++;
}
}
function add_harmonics(i_value) {
my_yvalue = 0;
for(var k = 0; k < harmonics.length; k++) {
my_yvalue = my_yvalue + 100 * Math.sin(2*Math.PI*i_value*Number(harmonics[k]["myorder"])/res)*Number(harmonics[k]["myamount"]);
}
my_yvalue = my_yvalue * 0.8;
return(my_yvalue);
}
function update_xy_array (currentvalue) {
//push the latest value onto the array
calculated_xy_pairs.push({myx:String(currentvalue),myy:String(add_harmonics(currentvalue))});
//if the length of the array is longer thanthe display area is wide, knock off the first element of the array
if(calculated_xy_pairs.length*my_xscale > oscope._width) {
calculated_xy_pairs.shift({myx:String(currentvalue),myy:String(add_harmonics(currentvalue))});
}
//clear the line and redraw it
sine.sinewave.clear();
sine.sinewave.lineStyle(1,0x00FF00,100);
for(var i = 0; i < calculated_xy_pairs.length-1; i++) {
sine.sinewave.moveTo((-calculated_xy_pairs.length+i)*(my_xscale),Number(calculated_xy_pairs[i]["myy"]));
sine.sinewave.lineTo((-calculated_xy_pairs.length+i+1)*(my_xscale),Number(calculated_xy_pairs[i+1]["myy"]));
}
}
function makeslider(mypath,number_of_sliders,color1,color2,linecolor,slotcolor,leftmargin,mylabels) {
var mylabels,slotcolor;
var mypath,number_of_sliders,mywidth,leftside,rightside,topside,bottomside,slider_x,color1,color2,linecolor,leftmargin;
var my_format:TextFormat = new TextFormat();
my_format.color = linecolor;
my_format.font = "Arial";
my_format.size = 14;
my_format.align = "center";
my_digital_format = new TextFormat();
my_digital_format.bold = true;
my_digital_format.align = "right";
my_digital_format.font = "Arial";
my_digital_format.color = 0x000000;
my_digital_format.underline = false;
my_digital_format.size = 14;
my_digital_format.italic = false;
mypath._xscale = 60;
mypath._yscale = 50;
mypath.createEmptyMovieClip("scale",mypath.getNextHighestDepth());
pixels_between_sliders = 40;
leftside = -10-leftmargin;
rightside = -10 + pixels_between_sliders*number_of_sliders;
topside = -125;
bottomside = 55;
slider_x = 0;
with (mypath.scale) {
//left side
colors = [color1, color2];
alphas = [100, 100];
ratios = [0, 0xFF];
matrix = {matrixType:"box", x:0, y:-120, w:30, h:150, r:(90/180)*Math.PI};
beginGradientFill("linear", colors, alphas, ratios, matrix);
moveTo(leftside-leftmargin,bottomside-5);
lineTo(leftside-leftmargin,-120);
curveTo(leftside-leftmargin,topside,leftside-leftmargin+5,topside);
lineTo(rightside-5,topside);
curveTo(rightside,topside,rightside,topside+5);
lineTo(rightside,bottomside-5);
curveTo(rightside,bottomside,rightside-5,bottomside);
lineTo(leftside-leftmargin+5,bottomside);
curveTo(leftside-leftmargin,bottomside,leftside-leftmargin,bottomside-5);
endFill();
for(var j = 1; j < number_of_sliders; j++) {
slider_x = slider_x + pixels_between_sliders;
lineStyle(0,linecolor,0);
beginFill(slotcolor,100);
moveTo(slider_x-1,0);
lineTo(slider_x-1,-100);
lineTo(slider_x+1,-100);
lineTo(slider_x+1,0);
lineTo(slider_x-1,0);
endFill();
lineStyle(0,linecolor,100);
moveTo(slider_x-1,0);
lineTo(slider_x-1,-100);
moveTo(slider_x+1,0);
lineTo(slider_x+1,-100);
for(var i = 0; i <= 10; i++) {
lineStyle(1.5,linecolor,100);
moveTo(slider_x+6,-i*10);
lineTo(slider_x+12,-i*10);
}
for(var i = 0; i <= 9; i++) {
lineStyle(1,linecolor,100);
moveTo(slider_x+6,-i*10-5);
lineTo(slider_x+10,-i*10-5);
}
}
}
for(var j = 1; j < number_of_sliders; j++) {
mypath.createTextField("buttonlabel" + j,mypath.getNextHighestDepth(),j*pixels_between_sliders-15,-120,33,23);
mypath["buttonlabel" + j].setNewTextFormat(my_format);
mypath["buttonlabel" + j].selectable = false;
mypath["buttonlabel" + j].text = mylabels[j];
my_format.size = 13;
mypath["buttonlabel" + j].setTextFormat(mypath["buttonlabel" + j].text.length - 2,mypath["buttonlabel" + j].text.length,my_format);
my_format.size = 16;
mypath.createEmptyMovieClip("digital"+j,mypath.getNextHighestDepth());
mypath.createEmptyMovieClip("button"+j,mypath.getNextHighestDepth());
mypath["digital" + j]._x = j*pixels_between_sliders;
mypath["digital" + j]._y = 40;
mypath["button" + j]._x = j*pixels_between_sliders;
with (mypath["digital" + j]) {
//make_a_rectangle(this,0x000000,CAF9CC,100,100,0,-10,10,-5,1);
lineStyle(0,0x000000,100);
beginFill(0xCAF9CC,100);
mywidth = 38;
myheight = 20;
moveTo(-mywidth/2,-myheight/2);
lineTo(-mywidth/2,myheight/2);
lineTo(mywidth/2,myheight/2);
lineTo(mywidth/2,-myheight/2);
lineTo(-mywidth/2,-myheight/2);
createEmptyMovieClip("text_holder",1);
text_holder._x = -4;
text_holder._xscale = 90;
text_holder._yscale = 120;
text_holder.createTextField("harmonic_percent",1,-mywidth/2,-myheight/2,mywidth+6,myheight);
text_holder.harmonic_percent.setNewTextFormat(my_digital_format);
text_holder.harmonic_percent.text = "0.00";
}
with (mypath["button" + j]) {
my_button_number = j;
//left side
colors = [0xEEEEEE, 0x666666];
alphas = [100, 100];
ratios = [0, 0xFF];
matrix = {matrixType:"box", x:0, y:0, w:8, h:36, r:(90/180)*Math.PI};
beginGradientFill("linear", colors, alphas, ratios, matrix);
//lineStyle(0,0xFF0000,100);
moveTo(-4,-18);
curveTo(-4,-22,-5.5,-25);
lineTo(-5.5,25);
curveTo(-4,22,-4,18);
curveTo(-6,0,-4,-18);
endFill();
//right side
colors = [0x999999, 0x222222];
alphas = [100, 100];
ratios = [0, 0xFF];
matrix = {matrixType:"box", x:0, y:0, w:8, h:36, r:(90/180)*Math.PI};
beginGradientFill("linear", colors, alphas, ratios, matrix);
//lineStyle(0,0xFF0000,100);
moveTo(4,-18);
curveTo(4,-22,5.5,-25);
lineTo(5.5,25);
curveTo(4,22,4,18);
curveTo(6,0,4,-18);
endFill();
//lineStyle(0,0xFF0000,0);
colors = [0x666666, 0xD5D5D5];
alphas = [100, 100];
ratios = [0, 0xFF];
matrix = {matrixType:"box", x:0, y:-20, w:8, h:36, r:(90/180)*Math.PI};
beginGradientFill("linear", colors, alphas, ratios, matrix);
moveTo(-4,-18);
lineTo(4,-18);
curveTo(6,0,4,18);
lineTo(-4,18);
curveTo(-6,0,-4,-18);
endFill();
colors = [0x666666, 0xCCCCCC];
alphas = [100, 100];
ratios = [0, 0xFF];
matrix = {matrixType:"box", x:0, y:-25, w:8, h:4, r:(90/180)*Math.PI};
beginGradientFill("linear", colors, alphas, ratios, matrix);
lineStyle(0,0xCCCCCC,100);
moveTo(-4,-18);
curveTo(-4,-22,-5.5,-25);
lineStyle(0,0x666666,100);
lineTo(5.5,-25);
lineStyle(0,0xFFFFFF,100);
curveTo(4,-22,4,-18);
lineStyle(0,0x666666,100);
lineTo(-4,-18);
endFill();
colors = [0x999999, 0x000000];
alphas = [100, 100];
ratios = [0, 0xFF];
matrix = {matrixType:"box", x:0, y:21, w:8, h:6, r:(90/180)*Math.PI};
beginGradientFill("linear", colors, alphas, ratios, matrix);
lineStyle(0,0xFFFFFF,100);
moveTo(-4,18);
curveTo(-4,22,-5.5,25);
lineStyle(0,0x000000,100);
lineTo(5.5,25);
lineStyle(0,0x666666,100);
curveTo(4,22,4,18);
lineStyle(0,0xCCCCCC,100);
lineTo(-4,18);
endFill();
lineStyle(0,0x999999,0);
beginFill(0x333333,100);
moveTo(-4,-1);
lineTo(4,-1);
lineTo(4,1);
lineTo(-4,1);
lineTo(-4,-1);
endFill();
lineStyle(0,0xFFFFFF,100);
moveTo(-4,1);
lineTo(4,1);
lineTo(4,-1);
lineStyle(0,0x999999,100);
moveTo(-4,-18);
lineTo(4,-18);
curveTo(6,0,4,18);
lineTo(-4,18);
curveTo(-6,0,-4,-18);
colors = [0x000000, 0x000000];
alphas = [40, 10];
ratios = [0, 0x66];
matrix = {matrixType:"box", x:0, y:15, w:2, h:60, r:(90/180)*Math.PI};
beginGradientFill("linear", colors, alphas, ratios, matrix);
lineStyle(0,0xFF0000,0);
moveTo(-5.5,25);
lineTo(5.5,25);
lineTo(5.5,-25);
curveTo(8,-20,10,-6);
curveTo(8,-6,8,2);
lineTo(8,30);
curveTo(7,32,6,32);
lineTo(0,32);
curveTo(-6.5,29,-5.5,25);
endFill();
lineStyle(0,0x666666,80);
moveTo(-5.5,25);
lineTo(5.5,25);
lineTo(5.5,-25);
_xscale = 100;
_yscale = 100;
}
}
my_format.align = "center";
my_format.size = 12;
my_format.color = 0x000000;
mypath.createTextField("percentage",mypath.getNextHighestDepth(),-32,24,55,50);
mypath["percentage"].setNewTextFormat(my_format);
mypath["percentage"].selectable = false;
mypath["percentage"].wordWrap = true;
mypath["percentage"].text = "harmonic
percentage";
text1 = "harmonic";
text2 = "order";
text1_y = -100;
text2_y = -80;
my_format.align = "center";
my_format.bold = true;
my_format.color = 0xFFFFFF;
my_format.size = 14;
for(var i = 0; i < text1.length; i++) {
mypath.createTextField("mylabel1" + i,mypath.getNextHighestDepth(),-20,text1_y,14,20);
mypath["mylabel1" + i].setNewTextFormat(my_format);
mypath["mylabel1" + i].selectable = false;
mypath["mylabel1" + i].text = text1.substring(i, i+1);
text1_y += 12;
}
for(var i = 0; i < text1.length; i++) {
mypath.createTextField("mylabel2" + i,mypath.getNextHighestDepth(),-5,text2_y,14,20);
mypath["mylabel2" + i].setNewTextFormat(my_format);
mypath["mylabel2" + i].selectable = false;
mypath["mylabel2" + i].text = text2.substring(i, i+1);
text2_y += 12;
}
}
//function to make a (filled) rectangle based on four input corners and color info
function make_a_rectangle(mypath,linecolor,fillcolor,linealpha,fillalpha,linewidth,left_x,right_x,top_y,bottom_y) {
mypath.lineStyle(linewidth, linecolor, linealpha);
mypath.beginFill(fillcolor,fillalpha);
mypath.moveTo(left_x,top_y);
mypath.lineTo(right_x,top_y);
mypath.lineTo(right_x,bottom_y);
mypath.lineTo(left_x,bottom_y);
mypath.lineTo(left_x,top_y);
mypath.endFill();
}
function displaydelay(mypath){
mypath.solidbox._visible = 1;
mypath.solidbox._alpha = 0;
mypath.fadingbox._visible = 1;
mypath.myhint._visible = 1;
mypath.fadingbox._alpha = 90;
//after the initial delay has elapsed, now make the fade in
fadedelay = setInterval(gradualfade,10,mypath);
clearInterval(initialdelay);
}
function gradualfade(mypath) {
mypath.solidbox._alpha += 4;
mypath.fadingbox._alpha -= 4;
if(mypath.solidbox._alpha >= 100) {
clearInterval(fadedelay);
}
}
function limit_decimals(myinput) {
return_for_display = String(Math.round(myinput*100)/100);
return_for_display = return_for_display.split("").reverse().join("");
//trace(return_for_display.indexOf("."));
if(return_for_display.indexOf(".") <> -1) {
for(var i=2; i> return_for_display.indexOf("."); i--) {
return_for_display = "0" + return_for_display;
}
} else {
return_for_display = "00." + return_for_display;
}
return_for_display = return_for_display.split("").reverse().join("");
return(return_for_display);
}
//create movie clips to fill
//"sinewave" is nested /in "sine" in a previous version that was required but technically is
//no longer. I went ahead and left it this way because it is so easy to reverse the direction
//of the wave travel this way just by setting the _xscale of its parent ("sine")
this.createEmptyMovieClip("oscope",this.getNextHighestDepth());
this.createEmptyMovieClip("sine",this.getNextHighestDepth());
this.sine.createEmptyMovieClip("sinewave",this.sine.getNextHighestDepth());
this.createEmptyMovieClip("sliders",this.getNextHighestDepth());
this.createEmptyMovieClip("harmonicsdata",this.getNextHighestDepth());
this.createEmptyMovieClip("sine_masker",this.getNextHighestDepth());
mylabels = new Array();
topcolor = 0x990000;
bottomcolor = 0xFFCC00;
linecolor = 0xFFFFFF;
leftmargin = 10;
slotcolor = 0x000000;
sliders._x = 10;
sliders._y = 65;
mylabels = ["1st","5th","7th","11th","13th","17th","19th","23rd","25th","29th","31st","35th","37th","41st","43rd","47th","49th"];
//number_of_buttons = mylabels.length;
makeslider(sliders,mylabels.length,topcolor,bottomcolor,linecolor,slotcolor,leftmargin,mylabels);
harmonics = new Array();
//set initial values for the array. In this case, since there are zero harmonics, the result will be a sine wave
harmonics.push ({myorder:1,myamount:1.0,mysuffix:"st"});
harmonics.push ({myorder:5,myamount:0.0,mysuffix:"th"});
harmonics.push ({myorder:7,myamount:0.0,mysuffix:"th"});
harmonics.push ({myorder:11,myamount:0.0,mysuffix:"th"});
harmonics.push ({myorder:13,myamount:0.0,mysuffix:"th"});
View Replies !
View Related