If you're seeing this message, it means we're having trouble loading external resources on our website.

Եթե գտնվում ես վեբ զտիչի հետևում, խնդրում ենք համոզվել, որ *.kastatic.org և *.kasandbox.org տիրույթները հանված են արգելափակումից։

Հիմնական նյութ

Մասնիկների համակարգերն ուժերով

Առայժմ այս բաժնում փորձել ենք կոդը օբյեկտային կողմնորոշվածությամբ կառուցել, որպեսզի մասնիկների համախումբը կարողանանք կառավարել։ Միգուցե նկատել ես, որ այդ ընթացքում մի քանի քայլով հետ ենք գնացել մյուս բաժիններում մեր կատարած աշխատանքից։ Ուսումնասիրենք պարզ Particle օբյեկտի կառուցող ֆունկցիան.
var Particle = function(position) {
  this.acceleration = new PVector(0, 0,05);
  this.velocity = new PVector(random(-1, 1), random(-1, 0));
  this.position = new PVector(position.x, position.y);
  this.timeToLive = 255,0;
};
Ուսումնասիրենք նաև update() մեթոդը.
Particle.prototype.update = function(){
  this.velocity.add(this.acceleration);
  this.position.add(this.velocity);
  this.timeToLive -= 2;
};
Ուշադրություն դարձրու, որ արագացումը հաստատուն է, կառուցողում արժեք ընդունելուց հետո չի փոխվում։ Շատ ավելի լավ մոտեցում կլիներ Նյուտոնի երկրորդ օրենքին հետևելը՝ F=MA, և «Ուժեր» բաժնում մեր գրած ուժերի կուտակման ալգորիթմը կիրառելը։
Առաջին քայլը applyForce() մեթոդ ավելացնելն է։ Հիշիր, որ զանգվածի վրա բաժանելուց առաջ պետք է PVector-ը պատճենենք։
Particle.prototype.applyForce = function(force) {
  var f = force.get();
  f.div(this.mass);
  this.acceleration.add(f);
};
Այսքանը գրելուց հետո կարող ենք ևս մեկ տող ավելացնել՝ update() մեթոդի վերջում արագացումը զրոյացնելու համար։
Particle.prototype.update = function() {
  this.velocity.add(this.acceleration);
  this.position.add(this.velocity);
  this.acceleration.mult(0);
  this.timeToLive -= 2,0;
};
Արդեն ունենք Particle օբյեկտ, որի վրա կարող ենք ուժ գործադրել։ Իսկ որտե՞ղ կանչենք applyForce() ֆունկցիան։ Որտե՞ղ ճիշտ կլինի մասնիկի վրա ուժ գործադրել։ Իրականում ճիշտ կամ սխալ պատասխան չկա, պատասխանը կախված է տվյալ ծրագրի նպատակից։ Այնուամենայնիվ, կարող ենք ընդհանրական ծրագիր գրել, որը կհամապատասխանի հնարավոր դեպքերի մեծ մասին, և դրա հիման վրա համակարգի անհատական մասնիկների վրա ուժ գործադրելու մոդելը զարգացնել։

Քամու ավելացում

Պատկերացրու, որ մեր նպատակն է draw() ցիկլում ամեն անգամ բոլոր մասնիկների վրա ընդհանրական ուժ գործադրել։ Դրա համար կսկսենք պարզ ուժով, որը քամու նման մասնիկները հրում է դեպի աջ.
var wind = new PVector(0,4, 0);
Քանի որ այս ուժը պետք է միշտ գործադրվի, օրինակ՝ draw()-ում, ուսումնասիրենք այս պահին մեր ունեցած draw() ֆունկցիան։
draw = function() {
  background(168, 255, 156);
  particleSystem.addParticle();
  particleSystem.run();
};
Կարծես մի փոքր խնդիր ունենք։ applyForce()Particle օբյեկտում գրված է մեթոդ, բայց մենք draw() ֆունկցիայում անհատական մասնիկներին հղում չենք կատարում։ Հղում ենք կատարում միայն ParticleSystem օբյեկտին՝ particleSystem փոփոխականին։
Այնուամենայնիվ, քանի որ ուզում ենք, որ ուժը բոլոր մասնիկների վրա գործադրվի, կարող ենք ուժը գործադրել մասնիկների համակարգի վրա և թողնել, որ անհատական մասնիկների վրա ուժի գործադրմամբ զբաղվի արդեն համակարգը։
draw = function() {
  background(168, 255, 156);
  particleSystem.applyForce(wind);
  particleSystem.addParticle();
  particleSystem.run();
};
Իհարկե, եթե draw()-ում ParticleSystem օբյեկտի համար նոր ֆունկցիա կանչենք, պետք է այդ ֆունկցիան հենց ParticleSystem օբյեկտում էլ գրենք։ Փորձենք հասկանալ, թե ինչ պետք է անի այդ ֆունկցիան. այն պետք է ստանա PVector տեսակի ուժ և այդ ուժը գործադրի բոլոր մասնիկների վրա։
Այժմ նույնը՝ կոդով.
ParticleSystem.prototype.applyForce = function(f){
  for(var i = 0; i < this.particles.length; i++){
    this.particles[i].applyForce(f);
  }
};
Այս ֆունկցիան գրելն անիմաստ է թվում. մասնիկների համակարգին ուժ ենք փոխանցում, որպեսզի համակարգն այդ ուժը գործադրի բոլոր մասնիկների վրա։ Այնուամենայնիվ, իրականում շատ ճիշտ է ֆունկցիան գրելը։ Վերջիվերջո, մասնիկները համակարգելու պատասխանատուն ParticleSystem-ն է, հետևաբար, եթե ուզում ենք դրանց վրա որևէ փոփոխություն կատարել, պետք է մասնիկների համակարգի միջոցով դա անենք։
Ահա ամբողջական ծրագիրը։ Փոփոխիր քամու ուժը, որ տեսնես՝ ինչպես է դա ազդում մասնիկների շարժման վրա։ Ուշադրություն դարձրու, որ տարբեր զանգված ունեցող մասնիկների վրա ուժը տարբեր ազդեցություն է ունենում. ինչի՞ց է։

Ծանրության ուժի ավելացում

Այժմ ավելի բարդ ուժ գործադրենք՝ ծանրության ուժ. այս ուժը քամուց տարբերվում է նրանով, որ ուժի մեծությունը կախված է մասնիկների զանգվածից։
Վերհիշենք զանգված ունեցող երկու մասնիկների միջև ձգողականության ուժը հաշվելու հավասարումը՝ Fg=Gm1m2||r||2r^։
Հիշիր, որ Երկրի վրա ձգողականության ուժ մոդելավորելիս Երկրի ձգողական ուժն այնքան մեծ է, որ մնացած բոլոր ձգողական ուժերը կարելի է հաշվի չառնել։ Հետևաբար, պետք է հաշվել ընդամենը Երկրի և տվյալ մարմնի միջև առկա ձգողականության ուժը։ G-ն ու m1-ը բոլոր մասնիկների համար նույնն են, Երկրի շառավիղը՝ r-ը, նույնպես նույնն է, քանի որ Երկրի շառավիղը շատ ավելի մեծ է, քան շարժվող մասնիկների հեռավորությունները։ Այդ պատճառով սովորաբար այս հաստատունների փոխարեն կիրառում ենք g-ն՝ Երկրի ձգողականության հաստատունը.
g=Gm1||r||2
Ստացվում է, որ ծանրության ուժը հավասար է հաստատուն g-ի, մասնիկի զանգվածի և ուժի ուղղությունը ցուցադրող, միշտ դեպի ներքև ուղղված միավոր վեկտորի արտադրյալին։
Fg=gm2r^
Նշանակում է՝ կոդի մեջ պետք է յուրաքանչյուր մասնիկի վրա տարբեր ծանրության ուժ գործադրենք՝ կախված մասնիկի զանգվածից։ Ինչպե՞ս կարող ենք անել դա։ Չենք կարող applyForce ֆունկցիան կիրառել, քանի որ այն բոլոր մասնիկների վրա նույն ուժն է գործադրում։ Կարող ենք փորձել applyForce-ին արգումենտ փոխանցել, որի միջոցով այն կիմանա, որ պետք է ստացված ուժը յուրաքանչյուր մասնիկի զանգվածով բազմապատկի, բայց ավելի լավ կլինի այդ ֆունկցիան կիրառելու փոխարեն նոր ֆունկցիա ստեղծենք։ Գրենք applyGravity ֆունկցիան, որը կհաշվի ուժը՝ հիմնվելով ընդհանրական հաստատուն վեկտորի վրա.
// Վերևում հայտարարված, դեպի ներքև ուղղված հաստատուն վեկտոր
var gravity = new PVector(0, 0{,}2);
ParticleSystem.prototype.applyGravity = function() {
    for(var i = 0; i < this.particles.length; i++) {
        var particleG = gravity.get();
        particleG.mult(this.particles[i].mass);
        this.particles[i].applyForce(particleG);
    }
};
Եթե այս պահի դրությամբ ամեն ինչ ճիշտ ենք արել, ստորև ներկայացված նմանակչում բոլոր մասնիկները պետք է նույն արագությամբ ընկնեն։ Դրա պատճառն այն է, որ ծանրության ուժը հաշվելիս բազմապատկում ենք զանգվածով, իսկ արագացումը հաշվելիս բաժանում ենք զանգվածի վրա, հետևաբար արդյունքում զանգվածը ազդեցություն չի ունենում։ Տպավորություն է ստեղծվում, որ եթե ոչինչ չի փոխվելու, իմաստ չունի այդքան մանրամասն ծրագիր գրել, սակայն երբ սկսենք տարբեր ուժեր միացնել իրար, սա կարևոր կդառնա։

Վանողների ավելացում

Այժմ կարող ենք ևս մեկ քայլ առաջ կատարել ու փորձել չափազանց մոտիկ մասնիկներին իրարից հեռացնող վանող օբյեկտ ստեղծել։ Այս օբյեկտը նման կլինի մեր՝ ավելի շուտ ստեղծած ձգող մարմնին, կփոխվի ուղղությունը։ Այս դեպքում էլ, ինչպես ծանրության ուժի դեպքում, պետք է յուրաքանչյուր մասնիկի համար առանձին ուժ հաշվենք, սակայն, ի տարբերություն ծանրության ուժի, հաշվարկը հիմնված է ոչ թե զանգվածի վրա, այլ հեռավորության։ Ծանրության ուժի դեպքում բոլոր վեկտորներն ունեին նույն ուղղությունը, իսկ վանողի դեպքում ուժի վեկտորները կունենան տարբեր ուղղություններ.
Ծանրության ուժ. բոլոր վեկտորներն ունեն նույն ուղղությունը
Վանող ուժ. բոլոր վեկտորներն ունեն տարբեր ուղղություններ
Քանի որ վանող ուժի հաշվարկը ծանրության ուժի հաշվարկից բարդ է, և քանի որ հավանական է, որ վերջում մի քանի վանող կունենանք ծրագրում, մեր պարզ օրինակում կավելացնենք Repeller օբյեկտ։ Կոդի մեջ երկու կարևոր կետ ենք ավելացնելու.
  1. Repeller օբյեկտ, որը սահմանում ենք, նախնական արժեք փոխանցում և ցուցադրում։
  2. Repeller օբյեկտը ParticleSystem-ին փոխանցող ֆունկցիա, որպեսզի այն կարողանա ուժ գործադրել յուրաքնաչյուր մասնիկի վրա։
var particleSystem = new ParticleSystem(new PVector(width/2, 50));
var repeller = new Repeller(width/2-20, height/2);
var gravity = new PVector(0, 0{,}1);

draw = function() {
  background(214, 255, 171);

  // Բոլոր մասնիկների վրա ծանրության ուժ գործադրել
  particleSystem.applyForce(gravity);
  particleSystem.applyRepeller(repeller);
  repeller.display();
  particleSystem.addParticle();
  particleSystem.run();
};
Հեշտ է ցուցադրվող Repeller օբյեկտ ստեղծել. պետք է նախօրոք ստեղծած Attractor օբյեկտը կրկնօրինակել։
var Repeller = function(x, y) {
  this.position = new PVector(x, y);
};

Repeller.prototype.display = function() {
  stroke(255);
  strokeWeight(2);
  fill(127);
  ellipse(this.position.x, this.position.y, 32, 32);
};
Բարդ է applyRepeller() մեթոդը գրելը։ Ֆունկցիային PVector փոխանցելու փոխարեն, ինչպես անում էինք applyForce() ֆունկցիայի դեպքում, applyRepeller() ֆունկցիային Repeller օբյեկտ ենք փոխանցելու և այնպես անենք, որ այդ ֆունկցիան հաշվարկի վանողի ու բոլոր մասնիկների միջև առկա ուժերը.
ParticleSystem.prototype.applyRepeller = function(r) {
  for(var i = 0; i < this.particles.length; i++){
    var p = this.particles[i];
    var force = r.calculateRepelForce(p);
    p.applyForce(force);
  }
};
Հիմնական տարբերությունն այն է, որ յուրաքանչյուր մասնիկի համար նոր ուժ է հաշվարկվում, քանի որ, ինչպես տեսանք, կախված վանողի ու մասնիկի հարաբերությունից, ուժը կարող է փոխվել։ Ուժը հաշվելու համար կիրառում ենք calculateRepelForce ֆունկցիան, որը AttractorcalculateAttractionForce-ի հակադարձն է։
Repeller.prototype.calculateRepelForce = function(p) {
  // Օբյեկտների միջև առաջացող ուժի վեկտորը հաշվել
  var dir = PVector.sub(this.position, p.position); 
  // Օբյեկտների հեռավորությունները հաշվել
  var dist = dir.mag();
  // Հեռավորությունը տրամաբանական սահմաններում պահել
  dist = constrain(dist, 1, 100);    
  // Վանող ուժը հաշվել,
  // որը հեռավորության քառակուսուն հակադարձ համեմատական է
  var force = -1 * this.power/ (dist * dist);     
  // Ուղղության վեկտորը նորմավորել
  // (հեռավորության մասին տեղեկությունը չեղարկել)
  dir.normalize();
  // Հաշվել ուժի վեկտորը՝ ուղղության և մեծության արտադրյալ
  dir.mult(force);                                  
  return dir;
};
Ուշադրություն դարձրու, որ վանողն ավելացնելիս ոչ մի պահի Particle օբյեկտի հետ գործ չենք արել։ Այսինքն՝ մասնիկն իրականում իր միջավայրի մասին տեղեկություն չունի, այն պետք է ընդամենը իր դիրքի, արագության ու արագացման հետ աշխատի ու կարողանա արտաքին ուժ ընդունել և, ըստ դրա, իր շարժումը փոխել։
Ահա ամբողջական օրինակը։ Փորձիր մասնիկների վրա ազդող ուժերի՝ ծանրության ուժի ու վանողի մեծությունները փոխել, որպեսզի տեսնես, թե ինչպես են ազդում մասնիկների վրա.

Ուզո՞ւմ ես միանալ խոսակցությանը։

Առայժմ հրապարակումներ չկան։
Անգլերեն հասկանո՞ւմ ես: Սեղմիր այստեղ և ավելի շատ քննարկումներ կգտնես «Քան» ակադեմիայի անգլերեն կայքում: