Tutorial Create a sphere/hemisphere off of particles.

Discussion in 'Resources' started by Muqsit, Feb 26, 2017.

  1. Muqsit

    Muqsit Chicken

    Messages:
    1,555
    GitHub:
    muqsit
    The last thread I made on creating a sphere of particles wasn't that good. It was based on lines and looked... well, not that good. (Also was a performance killer).
    About around 2 weeks ago, I and @Skullex were working on creating several particle effects by referring to mostly bukkit plugins. That day itself, I had figured out a much better way of making something what you can actually call a sphere.

    Firstly, we will be adding the particle on random places rather than in a line, like in my old post. I've already ported a function for it. This function will provide us the base of our sphere's circumference.
    PHP:
        public static function getRandomVector() : Vector3
        
    {
            
    $x 0$y 0$z 0;
            
    $x rand()/getrandmax() * 1;
            
    $y rand()/getrandmax() * 1;
            
    $z rand()/getrandmax() * 1;
            
    $v = new Vector3($x$y$z);
            return 
    $v->normalize();
        }
    Now that that's done, we need to select a region for our (hollow) sphere. This was easier than I'd ever expect. As simple as:
    PHP:
    Vector3::multiply(CircleRadius);
    To make it hollow, all you need to do is get the modulus of Vector3::$y.
    That's it. I've attached an image of what the result looks like.

    This code should be ran in a repeating task (delay: 1 tick, recommended).

    Arguments:
    Location $location:
    The center of the sphere.
    bool $sphere: Whether to create a sphere or a hemisphere. [true = sphere, false = hemisphere].

    PHP:
        private $radius 3;
        private 
    $particles 50;
        private 
    $location$level;
        private 
    $sphere false;

        public function 
    __construct(Location &$locationbool $sphere)
        {
            
    $this->level $location->getLevel();
            
    $this->location = &$location;
            
    $this->sphere $sphere;
        }

        private static function 
    getRandomVector() : Vector3
        
    {
            
    $x 0$y 0$z 0;
            
    $x rand()/getrandmax() * 1;
            
    $y rand()/getrandmax() * 1;
            
    $z rand()/getrandmax() * 1;
            
    $v = new Vector3($x$y$z);
            return 
    $v->normalize();
        }

        public function 
    onRun($tick) {
            for (
    $i 0$i $this->particles; ++$i) {
                
    $vector self::getRandomVector()->multiply($this->radius);
                if (!
    $this->sphere) {
                    
    $vector->abs($vector->getY());
                }
                
    $this->level->addParticle(new FlameParticle($this->location->add($vector->x$vector->y$vector->z)));
                
    $this->location->add($vector->x$vector->y$vector->z);
            }
        }

    wx.PNG
     
    Last edited: Jul 29, 2017
    BEcraft, SkySeven, Skullex and 2 others like this.
  2. WreckagePE / ZAYD

    WreckagePE / ZAYD Slime

    Messages:
    82
    Absolutely amazing... I thought this was only possible on Nukkit!
     
  3. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,898
    GitHub:
    sof3
    Why is this not in Resources forum?
     
    jasonwynn10 and Muqsit like this.
  4. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,898
    GitHub:
    sof3
    I doubt if randomness is really good... Isn't this entropy unnecessary?
    Moreover, your points are not uniformly distributed. The corners have higher probability of getting chosen and the places directly above, below, or to the east, south, west or north of the center have lower probability, because a random point in a cube is not necessarily a random point on a sphere. Use your imagination; if you can't, I'll prove it to you with a distorted absolute tangent graph and a cosine graph :D
    Instead, you may want to generate random yaw and pitch, and evaluate the respective coordinates according to these polar-uniform random values with a bit trigonometry.
    Also pay attention to the fact that circumference is directly proportional to radius. You may use this fact to help you create a sphere of appropriate density.
     
  5. Muqsit

    Muqsit Chicken

    Messages:
    1,555
    GitHub:
    muqsit
    True, should've had a thought about that.
     
  6. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,898
    GitHub:
    sof3
    PHP tips: you don't need to cast to float to carry out float division. An advantage of PHP (disadvantage of you look for performance) is that it is already float division even if you divide integer with integer.
    You could actually use lcg_value().
     
    RousselCrft and Muqsit like this.
  7. Muqsit

    Muqsit Chicken

    Messages:
    1,555
    GitHub:
    muqsit
    my baa.d
     
    Last edited: Jun 16, 2017
  8. Jonas

    Jonas Baby Zombie

    Messages:
    192
    It dosn't work
     
  9. kaliiks

    kaliiks Zombie

    Messages:
    250
    Why? Any error or why
     
  10. Jonas

    Jonas Baby Zombie

    Messages:
    192
    No i join at my Server with the Code
     
  11. kaliiks

    kaliiks Zombie

    Messages:
    250
    WTF:D and what dont work show your code
     
  12. Jonas

    Jonas Baby Zombie

    Messages:
    192
    This Code dosn't work
    PHP:
    use pocketmine\plugin\PluginBase;
    use 
    pocketmine\math\Vector3;
    use 
    pocketmine\level\particle\FlameParticle;;

    class 
    Main extends PluginBase {

        private 
    $radius 3;
        private 
    $particles 50;
        private 
    $location$level;
        private 
    $sphere false;

        public function 
    __construct(Location &$locationbool $sphere)
        {
            
    $this->level $location->getLevel();
            
    $this->location = &$location;
            
    $this->sphere $sphere;
        }

        private static function 
    getRandomVector() : Vector3
        
    {
            
    $x 0$y 0$z 0;
            
    $x = (float)rand()/(float)getrandmax() * 1;
            
    $y = (float)rand()/(float)getrandmax() * 1;
            
    $z = (float)rand()/(float)getrandmax() * 1;
            
    $v = new Vector3($x$y$z);
            return 
    $v->normalize();
        }

        public function 
    onRun($tick) {
            for (
    $i 0$i $this->particles; ++$i) {
                
    $vector self::getRandomVector()->multiply($this->radius);
                if (!
    $this->sphere) {
                    
    $vector->abs($vector->getY());
                }
                
    $this->level->addParticle(new FlameParticle($this->location->add($vector->x$vector->y$vector->z)));
                
    $this->location->add($vector->x$vector->y$vector->z);
            }
        }
    }
     
  13. kaliiks

    kaliiks Zombie

    Messages:
    250
    and have you registred task in main file?
     
    RousselCrft likes this.
  14. Jonas

    Jonas Baby Zombie

    Messages:
    192
    No, how can i register tasks?
     
  15. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,898
    GitHub:
    sof3
    This comment is definitely unreasonable... As long as it is a trivial programming language, no logic is impossible -- in fact very simple if you treat programming as something more than copying code.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.