Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
The solution to chasechocolates' question on spiraling effects.
How do I make an effect that spirals, becoming smaller as time goes on?
So, as we know a circle is defined by the equation:
r^2 = (x - a)^2 + (y - b)^2
So that gets us the general equation with which we will be working. As a result, we should also know that:
as a->∞ = translation in the x, right
as b->∞ = translation in the y, up
...and in the opposite directions when a or b ->-∞. The tricky part now is to fit this into a method, where a loop can be
used to expand and contract the circle, oscillating the r value and running around the perimeter to create the spiral effect.
To do this, we need to rewrite this equation to work in a loop.
To solve the oscillation of the r value, we could simply use a for loop, an example for the beginning of the method could be:
public void createSpiralingEffect(Location center, Effect effect, double maxR, double minR, double precision, byte data) {
for (double r = maxR; r >= minR; r -= precision) {
//do stuff...
}
}
Notice I included a "precision" argument. This is only required if you wish the user (or yourself) to be able to increase or
decrease the speed or choppiness of the oscillation of the spiral.
The next issue is the issue of getting the spiraling x and y. Using the equation we found earlier, we now know that:
x = sqrt(r^2 - (y - b)^2) + a
y = sqrt(r^2 - (x - a)^2) + b
Therefore, we can rewrite out code to oscillate the x, and find the y at the given x:
public void createSpiralingEffect(Location center, Effect effect, double maxR, double minR, double precision, byte data) {
for (double r = maxR; r >= minR; r -= precision) {
for (double x = center.getX() - r; x <= center.getX() + r; x += precision) {
double y = Math.sqrt(Math.pow(r, 2) - Math.pow(x - center.getX(), 2)) + center.getY();
//do stuff...
}
}
}
As you may notice, there is now one problem with this. The issue is that raising any number (negative or positive) to the
second (or an even) power results in a positive, preventing our current code from creating a spiral. The current code would
actually create more of a semi-circle shape.
To fix this, we have to create a second for loop, right after the first one. This second for loop should pick up right where
the other one left off, starting at the highest x (center.getX() + r), and ending at the lowest. The y value should also be
negated, to make it reflect over the x-axis (in the case of a circle with a center at (2, 2), the x-axis would be at y = 2).
public void createSpiralingEffect(Location center, Effect effect, double maxR, double minR, double precision, byte data) {
for (double r = maxR; r >= minR; r -= precision) {
for (double x = center.getX() - r; x <= center.getX() + r; x += precision) {
double y = Math.sqrt(Math.pow(r, 2) - Math.pow(x - center.getX(), 2)) + center.getY();
center.getWorld().playEffect(new Location(center.getWorld(), x, center.getY(), y), effect, data);
}
for (double x = center.getX() + r; x >= center.getX() - r; x -= precision) {
double y = -(Math.sqrt(Math.pow(r, 2) - Math.pow(x - center.getX(), 2)) + center.getY());
center.getWorld().playEffect(new Location(center.getWorld(), x, center.getY(), y), effect, data);
}
}
}
As you can see, I also added in the Bukkit method World.playEffect(), which should play the effect you passed as an argument
in the spiral motion.
There are a few problems with this code still, which I don't consider part of the answer. One of these problems is that this method will run very fast, causing a lot of lag if used a lot, and preventing the spiral from appearing as though it is spinning. You can fix this issue with a simple repeating task (Bukkit).
This concludes the "Spiraling Effect" Gist, I hope you found it useful and interesting. Please alert me of any issues that
may affect the performance of the code found in this Gist, or any spelling or grammar errors you find.
@chaseking

This comment has been minimized.

Copy link

chaseking commented Nov 26, 2013

<3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.