# Tutorial Creating a helix / 3d spiral out of particles

Discussion in 'Resources' started by Skionz, Sep 28, 2014.

Not open for further replies.
1. Offline

### Skionz

This is my first tutorial so here goes. Basically I am going to teach you how to create a helix out of particles. A helix is just a 3d spiral like this:

First we are going to create a method that creates a helix at the players location
Code:java
`public void createHelix(Player player) {}`

Then we get the players location and get the coordinates for where the particle should be created
Code:java
`public void createHelix(Player player) {    Location loc = player.getLocation();    int radius = 2;    for(double y = 0; y <= 50; y+=0.05) {        double x = radius * Math.cos(y);        double z = radius * Math.sin(y);    }}`

Next we will create the particle packet and send it to everyone
Code:java
`public void createHelix(Player player) {    Location loc = player.getLocation();    int radius = 2;    for(double y = 0; y <= 50; y+=0.05) {        double x = radius * Math.cos(y);        double z = radius * Math.sin(y);        PacketPlayOutWorldParticles packet = new PacketPlayOutWorldParticles("fireworksSpark", (float) (loc.getX() + x), (float) (loc.getY() + y), (float) (loc.getZ() + z), 0, 0, 0, 0, 1);        for(Player online : Bukkit.getOnlinePlayers()) {            ((CraftPlayer)online).getHandle().playerConnection.sendPacket(packet);        }    }}`

This will send the particles to every online player. The end result would look something like this

This can be used for some badass teleportation effects especially if you randomize the particle effects

#1
2. Offline

### ChipDev

*First.
Such awesome...

#2
Skionz likes this.
3. Offline

### Skionz

ChipDev Using this method instead of "fireworksSpark" creates a pretty badass effect
Code:java
`public String randParticle() {        Random r = new Random();        int rNumb = r.nextInt(5) + 1;        if(rNumb == 1)            return "fireworksSpark";        else if(rNumb == 2)            return "happyVillager";        else if(rNumb == 3)            return "witchMagic";        else if(rNumb == 4)            return "flame";        else if(rNumb == 5) {            return "blockcrack_152_0";        }        return null;    }`

#3
gal0511Dev and ChipDev like this.
4. Offline

### 97WaterPolo

Skionz
Great post, very interesting!

#4
Skionz likes this.
5. Offline

### Skionz

#5
ChipDev likes this.
6. Offline

### 97WaterPolo

Skionz
lol, I kinda forgot about that plugin

#6
7. Offline

### jensdeboom

Skionz Fantastic tutorial! Am I able to do this with a repeating task (at 1-2 ticks) instead of a for loop so you can see the helix being created?

#7
8. Offline

### Skionz

jensdeboom You could add an incrementing delay when you send the particle packets.

#8
9. Offline

K thx.

#9
10. Offline

### d3v1n302418

Skionz Nice post! Definitely going to use this in a plugin

#10
Skionz likes this.
11. Offline

### Funergy

Skionz
Reached level: Pro. next level: Master
Achievements for Master: use Reflection.

Great tutorial

#11
12. Offline

### Forge_User_12768433

Funergy Challenge accepted.
Code:java
`public void createHelixWithReflection(Player player) throws Exception {        Location loc = player.getLocation();        int radius = 2;        for (double y = 0; y <= 50; y += 0.05) {            double x = radius * Math.cos(y);            double z = radius * Math.sin(y);            Object packet = getNMSClass(player, "PacketPlayOutWorldParticles").newInstance();            packet = packet.getClass().getConstructor(String.class, float.class, float.class, float.class, float.class, float.class, float.class, float.class, int.class).newInstance("fireworksSpark", (float) (loc.getX() + x), (float) (loc.getY() + y), (float) (loc.getZ() + z), 0, 0, 0, 0, 1);            for (Player online : Bukkit.getOnlinePlayers()) {                Object nmsPlayer = online.getClass().getMethod("getHandle").invoke(online);                Object playerConnection = nmsPlayer.getClass().getDeclaredField("playerConnection").get(nmsPlayer);                playerConnection.getClass().getMethod("sendPacket", getNMSClass(online, "Packet")).invoke(playerConnection, packet);            }        }    }     public Class<?> getNMSClass(Player player, String className) throws Exception {        Field field = Bukkit.getServer().getClass().getDeclaredField("console");        field.setAccessible(true);        return (Class.forName(field.get(Bukkit.getServer()).getClass().getPackage().getName() + "." + className));    }`

Funergy likes this.
13. Offline

### Skionz

DJSkepter bahh you beat me to it No fair I was at school

#13
DJSkepter and Funergy like this.
14. Offline

### xTrollxDudex

...

#14
_Filip, Avygeil and Hawktasard like this.
15. Offline

### Cirno

rip performance.

You might want to create all the packets ahead of time and then send it.

#15
MrShnig, rbrick, Hawktasard and 2 others like this.
16. Offline

### Forge_User_12768433

Skionz Don't worry, you still get the majority of the credit since you wrote the original thing. There's no way I could possibly know how to make a helix. Ever.

Cirno Thanks for the tip, I'll try that next time

Skionz likes this.
17. Offline

#17
18. Offline

### xTrollxDudex

I'm not kidding. Reflection is slow. Look at Cirno's comment.

#18
19. Offline

### Cirno

#19
rbrick likes this.
20. Offline

### TheLexoPlexx

Slikey did it this way:
Code:
```package de.slikey.effectlib.effect;

import de.slikey.effectlib.EffectManager;
import de.slikey.effectlib.EffectType;
import de.slikey.effectlib.util.ParticleEffect;
import org.bukkit.Location;

public class HelixLocationEffect extends LocationEffect {
/**
* Particle to form the helix
*/
public ParticleEffect particle = ParticleEffect.FLAME;

/**
* Amount of strands
*/
public int strands = 8;

/**
* Particles per strand
*/
public int particles = 80;

/**
*/

/**
* Factor for the curves. Negative values reverse rotation.
*/
public float curve = 10;

/**
* Rotation of the helix (Fraction of PI)
*/
public double rotation = Math.PI / 4;

public HelixLocationEffect(EffectManager effectManager, Location location) {
super(effectManager, location);
type = EffectType.REPEATING;
period = 10;
iterations = 8;
}

@Override
public void onRun() {
for (int i = 1; i <= strands; i++) {
for (int j = 1; j <= particles; j++) {
float ratio = (float) j / particles;
double angle = curve * ratio * 2 * Math.PI / strands + (2 * Math.PI * i / strands) + rotation;
double x = Math.cos(angle) * ratio * radius;
double z = Math.sin(angle) * ratio * radius;
particle.display(location, visibleRange, 0, 0, 0, 0, 0);
location.subtract(x, 0, z);
}
}
}

}
```
Full Code: https://github.com/Slikey/EffectLib

#20
21. Offline

### rbrick

Simple math functions create amazing stuff.

#21
MrShnig and Skionz like this.
22. Offline

### ChipDev

This is why bukkit is so awesome.
You are sitting in class. Geometry.. thinking "Im never going to use this.."
well, bukkit is a great way to use cos and sin and other math stuff. and you are proud of it

Cool! Do raidus+=0.1 and it will make a tornado :O

EDIT by Moderator: merged posts, please use the edit button instead of double posting.

Last edited by a moderator: Jun 14, 2016
#22
23. Offline

#23
24. Offline

### ChipDev

no.. ;P
Code:java
`for(double y = 0; y <= 60; y += 0.1) {double x = l.getX() + (raidus * Math.cos(y));double z = l.getZ() + (raidus * Math.sin(y));raidus += 0.01;if(y >= 50){//other code :p}}`

#24
25. Offline

### _Filip

Cirno Where is the proof? Not meaning to start an argument, this is from non biased view point. The first solution is debunked in the comments of it. I know that reflection is slower, I'm just not sure that it is so much slower that it would really create that big of an effect.

http://stackoverflow.com/a/547847

#25
26. Offline

### Cirno

http://docs.oracle.com/javase/tutorial/reflect/index.html
"Because reflection involves types that are dynamically resolved, certain Java virtual machine optimizations can not be performed. Consequently, reflective operations have slower performance than their non-reflective counterparts, and should be avoided in sections of code which are called frequently in performance-sensitive applications."

Oracle themselves have stated that Reflection can be slow. It will typically be slow for the first couple iterations because the JIT needs to analyze it; but once that's done, your mileage may vary.

I'm biased towards not using Reflection for several reasons:
• As previously stated, it can be slow. With the amount of reflection being used within the loop that they made, you might as well just release multiple versions or use interfaces and then, on startup, generate a proper implementation class.
• If you/someone else changes the variable/method signature, you pretty much screw up the entire code.
• Environments are different. Some environments may use a security manager on top of Java, which is a major concern since the security manager can actually block reflection, along with other features of Java.
• Might be compounded with the second point; it allows theoretically illegal code to execute without error. Because we're on Bukkit and that usually implies Minecraft (unless you're tampering with Bukkit; in that case, go ahead and tamper all the Simple* classes), NMS tends to be volatile in terms of field names. In 1.6.x, a field can be named "a" and have the type of int, and is used for, say, position. In 1.7.x, the variables type and name could be the same, but be completely used for another purpose.
I will say that Reflection is fun toying with; you can toy with the integer cash and make 1+1 = 3 (and possibly screw up something as a result), but I don't think it belongs in an environment where performance is relatively important (considering the fact that Minecraft isn't exactly the "fastest server software".)

#26
27. Offline

### _Filip

Cirno I'm sure people will find your post interesting. Thank you for this

#27
28. Offline

### feff890

Skionz
Always the exact same error on:
((CraftPlayer)online)
Says CraftPlayer cannot be resolved to a type
Pls help!! Anyone!

#28
29. Offline

### Forge_User_60359873

feff890 You need to build against CraftBukkit

30. Offline

### feff890

Ok thanks! Now that it works this is really awesome.
I was wondering if anyone knows how to make the shape where to rings cross over each other? Like an atom.

#30