# Tutorial Create a sphere/hemisphere off of particles.

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

1. ### MuqsitChicken

Messages:
1,549
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() * 2 - 1;        \$y = rand()/getrandmax() * 2 - 1;        \$z = rand()/getrandmax() * 2 - 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 &\$location, bool \$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() * 2 - 1;        \$y = rand()/getrandmax() * 2 - 1;        \$z = rand()/getrandmax() * 2 - 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->y = 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);        }    } ```

Last edited: Jul 29, 2017
BEcraft, SkySeven, Skullex and 2 others like this.
2. Absolutely amazing... I thought this was only possible on Nukkit!

Messages:
1,968
GitHub:
sof3
Why is this not in Resources forum?

jasonwynn10 and Muqsit like this.

Messages:
1,968
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 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. ### MuqsitChicken

Messages:
1,549
GitHub:
muqsit

Messages:
1,968
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. ### MuqsitChicken

Messages:
1,549
GitHub:
muqsit
my baa.d

Last edited: Jun 16, 2017
8. It dosn't work

9. Why? Any error or why

10. No i join at my Server with the Code

11. WTF and what dont work show your code

12. 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 &\$location, bool \$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() * 2 - 1;        \$y = (float)rand()/(float)getrandmax() * 2 - 1;        \$z = (float)rand()/(float)getrandmax() * 2 - 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->y = 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. and have you registred task in main file?

Ayush and RousselCrft like this.
14. No, how can i register tasks?