Solved [Math Problem] Hollow sphere method returns full sphere.

Discussion in 'Plugin Development' started by megasaad44, Aug 5, 2014.

Thread Status:
Not open for further replies.
  1. Offline

    megasaad44

    So i was trying to do a bit of math... failed. Then i tried getting some help from friends and ended up with this method for a "hollow" sphere but it returns with a full sphere. Anyone know how to fix this math? Friends couldn't figure it out nor can I.
    code:
    Code:java
    1. public Set<Vector> genCircle(double radius, int vertLines, int dotsPerLine) {
    2. Location center = new Location(Bukkit.getWorlds().get(0), 0, 0, 0);
    3.  
    4. float pitchDelta = 180F / dotsPerLine;
    5. float yawDelta = 360F / vertLines;
    6.  
    7. Set<Vector> results = new HashSet<Vector>();
    8.  
    9. for (int i = 0; i < vertLines; i++) {
    10. for (int j = 0; j < dotsPerLine; j++) {
    11. Location loc = center.clone();
    12. loc.setYaw(-180 + (i * yawDelta));
    13. loc.setPitch(-90 + (j * pitchDelta));
    14. Vector v = loc.getDirection().normalize().multiply(radius);
    15. results.add(v);
    16. }
    17. }
    18.  
    19. return results;
    20. }
     
  2. Offline

    megasaad44

  3. Offline

    Bobit

    #vectors #i'mnotdoingthiscrap #hashtag
     
    hintss likes this.
  4. Offline

    megasaad44

    Bobit
    #helpful #yournothelping
     
  5. Offline

    Bobit

    #ikr #someonehadtosayit #hashtag #isaywhatiwant!!!!!1!!!one!!!
     
  6. Offline

    megasaad44

    Bobit
    I imagined everyone would try solving a math problem. lol.
    Anyone good at math?
     
  7. Offline

    Luke_Lax

    Slikey is good with this stuff :)
     
    hintss and megasaad44 like this.
  8. Offline

    AoH_Ruthless

    Why be so rude? Op is just simply asking for help. You offered nothing contributive to this thread.

    megasaad44
    Try looking at WorldEdit sphere code or google 3D geometry and creating a hollow sphere.
     
  9. Offline

    Bobit

    That wasn't mean, was it? I was trying to say in a joking way "People probably aren't going to answer this because it has vectors."
     
  10. Offline

    AoH_Ruthless

    Bobit
    It didn't come across that way to me or to OP (my bad for assuming you were being rude, I just read it with a different perspective I suppose)
    Whether it has vectors or not, it should be no different than any other thread in this category of forums. People should only answer if they believe they know what they are talking about and can offer some help in some sort of way. While vectors are mildly more complex than other topics (only due to the fact this is a higher algebra concept and many developers are quite young and haven't learned this stuff yet), there are enough people who can answer a vector question.
     
    hintss likes this.
  11. Offline

    Bobit

    That's true. I wasn't trying to stop people from answering him.
     
  12. Offline

    megasaad44

    AoH_Ruthless Thank you. I'll look into that worldedit code. Definitely seems neat.
     
  13. Offline

    Chiller

    megasaad44 All you need to do is check if the vector is the radius amount away from the center to get only the circumference of the sphere filled in.
     
    jollie000l likes this.
  14. Offline

    Slikey

    Code:java
    1. float radius = 2.5f;
    2. int amount = 80;
    3. Set<Vector> vectors = new HashSet<Vector>();
    4. Random random = new Random();
    5. for (int i = 0; i < amount; i++) {
    6. vectors.add(new Vector(
    7. random.nextFloat() * 2 - 1,
    8. random.nextFloat() * 2 - 1,
    9. random.nextFloat() * 2 - 1
    10. ).normalize().multiply(radius));
    11. }


    This will create a Set, containing all Vectors for the hollow sphere.
     
    HeavyMine13 likes this.
  15. Offline

    megasaad44

    Slikey That gave me a full sphere. Particles are showing on the inside as well.
     
  16. Offline

    HeavyMine13

    Post the code you have right now please, thanks.
     
  17. Offline

    biel

    Hey I see not everyone likes math, but if you don't like it, just don't comment lol.

    I'm now on a mobile device and don't have my code here. When I get to home I'll post my whole function to get the blocks of a fill or hollow sphere. Basically my way to do it have been getting a bigger sphere than the one you want and subtracting the inner blocks.

    Hope it helps!
     
  18. Offline

    Slikey

    Impossible. This is the code, I use to generate a sphere. Maybe you did something wrong? What is your code to display it?
     
  19. Offline

    biel

    Here is the code:
    Needed cuboid class:
    Code:java
    1. public class Cuboid implements Iterable<Block>, Cloneable, ConfigurationSerializable {
    2. protected final String worldName;
    3. protected final int x1, y1, z1;
    4. protected final int x2, y2, z2;
    5.  
    6. /**
    7.   * Construct a Cuboid given two Location objects which represent any two corners of the Cuboid.
    8.   * Note: The 2 locations must be on the same world.
    9.   *
    10.   * @param l1 - One of the corners
    11.   * @param l2 - The other corner
    12.   */
    13. public Cuboid(Location l1, Location l2) {
    14. if (!l1.getWorld().equals(l2.getWorld())) throw new IllegalArgumentException("Locations must be on the same world");
    15. this.worldName = l1.getWorld().getName();
    16. this.x1 = Math.min(l1.getBlockX(), l2.getBlockX());
    17. this.y1 = Math.min(l1.getBlockY(), l2.getBlockY());
    18. this.z1 = Math.min(l1.getBlockZ(), l2.getBlockZ());
    19. this.x2 = Math.max(l1.getBlockX(), l2.getBlockX());
    20. this.y2 = Math.max(l1.getBlockY(), l2.getBlockY());
    21. this.z2 = Math.max(l1.getBlockZ(), l2.getBlockZ());
    22. }
    23.  
    24. /**
    25.   * Construct a one-block Cuboid at the given Location of the Cuboid.
    26.   *
    27.   * @param l1 location of the Cuboid
    28.   */
    29. public Cuboid(Location l1) {
    30. this(l1, l1);
    31. }
    32.  
    33. /**
    34.   * Copy constructor.
    35.   *
    36.   * @param other - The Cuboid to copy
    37.   */
    38. public Cuboid(Cuboid other) {
    39. this(other.getWorld().getName(), other.x1, other.y1, other.z1, other.x2, other.y2, other.z2);
    40. }
    41.  
    42. /**
    43.   * Construct a Cuboid in the given World and xyz co-ordinates
    44.   *
    45.   * @param world - The Cuboid's world
    46.   * @param x1 - X co-ordinate of corner 1
    47.   * @param y1 - Y co-ordinate of corner 1
    48.   * @param z1 - Z co-ordinate of corner 1
    49.   * @param x2 - X co-ordinate of corner 2
    50.   * @param y2 - Y co-ordinate of corner 2
    51.   * @param z2 - Z co-ordinate of corner 2
    52.   */
    53. public Cuboid(World world, int x1, int y1, int z1, int x2, int y2, int z2) {
    54. this.worldName = world.getName();
    55. this.x1 = Math.min(x1, x2);
    56. this.x2 = Math.max(x1, x2);
    57. this.y1 = Math.min(y1, y2);
    58. this.y2 = Math.max(y1, y2);
    59. this.z1 = Math.min(z1, z2);
    60. this.z2 = Math.max(z1, z2);
    61. }
    62.  
    63. /**
    64.   * Construct a Cuboid in the given world name and xyz co-ordinates.
    65.   *
    66.   * @param worldName - The Cuboid's world name
    67.   * @param x1 - X co-ordinate of corner 1
    68.   * @param y1 - Y co-ordinate of corner 1
    69.   * @param z1 - Z co-ordinate of corner 1
    70.   * @param x2 - X co-ordinate of corner 2
    71.   * @param y2 - Y co-ordinate of corner 2
    72.   * @param z2 - Z co-ordinate of corner 2
    73.   */
    74. private Cuboid(String worldName, int x1, int y1, int z1, int x2, int y2, int z2) {
    75. this.worldName = worldName;
    76. this.x1 = Math.min(x1, x2);
    77. this.x2 = Math.max(x1, x2);
    78. this.y1 = Math.min(y1, y2);
    79. this.y2 = Math.max(y1, y2);
    80. this.z1 = Math.min(z1, z2);
    81. this.z2 = Math.max(z1, z2);
    82. }
    83.  
    84. /**
    85.   * Construct a Cuboid using a map with the following keys: worldName, x1, x2, y1, y2, z1, z2
    86.   * @param map - The map of keys.
    87.   */
    88. public Cuboid(Map<String, Object> map) {
    89. this.worldName = (String) map.get("worldName");
    90. this.x1 = (Integer) map.get("x1");
    91. this.x2 = (Integer) map.get("x2");
    92. this.y1 = (Integer) map.get("y1");
    93. this.y2 = (Integer) map.get("y2");
    94. this.z1 = (Integer) map.get("z1");
    95. this.z2 = (Integer) map.get("z2");
    96. }
    97.  
    98.  
    99. @Override
    100. public Map<String, Object> serialize() {
    101. Map<String, Object> map = new HashMap<String, Object>();
    102. map.put("worldName", this.worldName);
    103. map.put("x1", this.x1);
    104. map.put("y1", this.y1);
    105. map.put("z1", this.z1);
    106. map.put("x2", this.x2);
    107. map.put("y2", this.y2);
    108. map.put("z2", this.z2);
    109. return map;
    110. }
    111.  
    112. /**
    113.   * Get the Location of the lower northeast corner of the Cuboid (minimum XYZ co-ordinates).
    114.   *
    115.   * @return Location of the lower northeast corner
    116.   */
    117. public Location getLowerNE() {
    118. return new Location(this.getWorld(), this.x1, this.y1, this.z1);
    119. }
    120.  
    121. /**
    122.   * Get the Location of the upper southwest corner of the Cuboid (maximum XYZ co-ordinates).
    123.   *
    124.   * @return Location of the upper southwest corner
    125.   */
    126. public Location getUpperSW() {
    127. return new Location(this.getWorld(), this.x2, this.y2, this.z2);
    128. }
    129.  
    130. /**
    131.   * Get the blocks in the Cuboid.
    132.   *
    133.   * @return The blocks in the Cuboid
    134.   */
    135. public List<Block> getBlocks() {
    136. Iterator<Block> blockI = this.iterator();
    137. List<Block> copy = new ArrayList<Block>();
    138. while (blockI.hasNext())
    139. copy.add(blockI.next());
    140. return copy;
    141. }
    142.  
    143. /**
    144.   * Get the the centre of the Cuboid.
    145.   *
    146.   * @return Location at the centre of the Cuboid
    147.   */
    148. public Location getCenter() {
    149. int x1 = this.getUpperX() + 1;
    150. int y1 = this.getUpperY() + 1;
    151. int z1 = this.getUpperZ() + 1;
    152. return new Location(this.getWorld(), this.getLowerX() + (x1 - this.getLowerX()) / 2.0, this.getLowerY() + (y1 - this.getLowerY()) / 2.0, this.getLowerZ() + (z1 - this.getLowerZ()) / 2.0);
    153. }
    154.  
    155. /**
    156.   * Get the Cuboid's world.
    157.   *
    158.   * @return The World object representing this Cuboid's world
    159.   * @throws IllegalStateException if the world is not loaded
    160.   */
    161. public World getWorld() {
    162. World world = Bukkit.getWorld(this.worldName);
    163. if (world == null) throw new IllegalStateException("World '" + this.worldName + "' is not loaded");
    164. return world;
    165. }
    166.  
    167. /**
    168.   * Get the size of this Cuboid along the X axis
    169.   *
    170.   * @return Size of Cuboid along the X axis
    171.   */
    172. public int getSizeX() {
    173. return (this.x2 - this.x1) + 1;
    174. }
    175.  
    176. /**
    177.   * Get the size of this Cuboid along the Y axis
    178.   *
    179.   * @return Size of Cuboid along the Y axis
    180.   */
    181. public int getSizeY() {
    182. return (this.y2 - this.y1) + 1;
    183. }
    184.  
    185. /**
    186.   * Get the size of this Cuboid along the Z axis
    187.   *
    188.   * @return Size of Cuboid along the Z axis
    189.   */
    190. public int getSizeZ() {
    191. return (this.z2 - this.z1) + 1;
    192. }
    193.  
    194. /**
    195.   * Get the minimum X co-ordinate of this Cuboid
    196.   *
    197.   * @return the minimum X co-ordinate
    198.   */
    199. public int getLowerX() {
    200. return this.x1;
    201. }
    202.  
    203. /**
    204.   * Get the minimum Y co-ordinate of this Cuboid
    205.   *
    206.   * @return the minimum Y co-ordinate
    207.   */
    208. public int getLowerY() {
    209. return this.y1;
    210. }
    211.  
    212. /**
    213.   * Get the minimum Z co-ordinate of this Cuboid
    214.   *
    215.   * @return the minimum Z co-ordinate
    216.   */
    217. public int getLowerZ() {
    218. return this.z1;
    219. }
    220.  
    221. /**
    222.   * Get the maximum X co-ordinate of this Cuboid
    223.   *
    224.   * @return the maximum X co-ordinate
    225.   */
    226. public int getUpperX() {
    227. return this.x2;
    228. }
    229.  
    230. /**
    231.   * Get the maximum Y co-ordinate of this Cuboid
    232.   *
    233.   * @return the maximum Y co-ordinate
    234.   */
    235. public int getUpperY() {
    236. return this.y2;
    237. }
    238.  
    239. /**
    240.   * Get the maximum Z co-ordinate of this Cuboid
    241.   *
    242.   * @return the maximum Z co-ordinate
    243.   */
    244. public int getUpperZ() {
    245. return this.z2;
    246. }
    247.  
    248. /**
    249.   * Get the Blocks at the eight corners of the Cuboid.
    250.   *
    251.   * @return array of Block objects representing the Cuboid corners
    252.   */
    253. public Block[] corners() {
    254. Block[] res = new Block[8];
    255. World w = this.getWorld();
    256. res[0] = w.getBlockAt(this.x1, this.y1, this.z1);
    257. res[1] = w.getBlockAt(this.x1, this.y1, this.z2);
    258. res[2] = w.getBlockAt(this.x1, this.y2, this.z1);
    259. res[3] = w.getBlockAt(this.x1, this.y2, this.z2);
    260. res[4] = w.getBlockAt(this.x2, this.y1, this.z1);
    261. res[5] = w.getBlockAt(this.x2, this.y1, this.z2);
    262. res[6] = w.getBlockAt(this.x2, this.y2, this.z1);
    263. res[7] = w.getBlockAt(this.x2, this.y2, this.z2);
    264. return res;
    265. }
    266.  
    267. /**
    268.   * Expand the Cuboid in the given direction by the given amount. Negative amounts will shrink the Cuboid in the given direction. Shrinking a cuboid's face past the opposite face is not an error and will return a valid Cuboid.
    269.   *
    270.   * @param dir - The direction in which to expand
    271.   * @param amount - The number of blocks by which to expand
    272.   * @return A new Cuboid expanded by the given direction and amount
    273.   */
    274. public Cuboid expand(CuboidDirection dir, int amount) {
    275. switch (dir) {
    276. case North:
    277. return new Cuboid(this.worldName, this.x1 - amount, this.y1, this.z1, this.x2, this.y2, this.z2);
    278. case South:
    279. return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x2 + amount, this.y2, this.z2);
    280. case East:
    281. return new Cuboid(this.worldName, this.x1, this.y1, this.z1 - amount, this.x2, this.y2, this.z2);
    282. case West:
    283. return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x2, this.y2, this.z2 + amount);
    284. case Down:
    285. return new Cuboid(this.worldName, this.x1, this.y1 - amount, this.z1, this.x2, this.y2, this.z2);
    286. case Up:
    287. return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x2, this.y2 + amount, this.z2);
    288. default:
    289. throw new IllegalArgumentException("Invalid direction " + dir);
    290. }
    291. }
    292.  
    293. /**
    294.   * Shift the Cuboid in the given direction by the given amount.
    295.   *
    296.   * @param dir - The direction in which to shift
    297.   * @param amount - The number of blocks by which to shift
    298.   * @return A new Cuboid shifted by the given direction and amount
    299.   */
    300. public Cuboid shift(CuboidDirection dir, int amount) {
    301. return expand(dir, amount).expand(dir.opposite(), -amount);
    302. }
    303.  
    304. /**
    305.   * Outset (grow) the Cuboid in the given direction by the given amount.
    306.   *
    307.   * @param dir - The direction in which to outset (must be Horizontal, Vertical, or Both)
    308.   * @param amount - The number of blocks by which to outset
    309.   * @return A new Cuboid outset by the given direction and amount
    310.   */
    311. public Cuboid outset(CuboidDirection dir, int amount) {
    312. Cuboid c;
    313. switch (dir) {
    314. case Horizontal:
    315. c = expand(CuboidDirection.North, amount).expand(CuboidDirection.South, amount).expand(CuboidDirection.East, amount).expand(CuboidDirection.West, amount);
    316. break;
    317. case Vertical:
    318. c = expand(CuboidDirection.Down, amount).expand(CuboidDirection.Up, amount);
    319. break;
    320. case Both:
    321. c = outset(CuboidDirection.Horizontal, amount).outset(CuboidDirection.Vertical, amount);
    322. break;
    323. default:
    324. throw new IllegalArgumentException("Invalid direction " + dir);
    325. }
    326. return c;
    327. }
    328.  
    329. /**
    330.   * Inset (shrink) the Cuboid in the given direction by the given amount. Equivalent
    331.   * to calling outset() with a negative amount.
    332.   *
    333.   * @param dir - The direction in which to inset (must be Horizontal, Vertical, or Both)
    334.   * @param amount - The number of blocks by which to inset
    335.   * @return A new Cuboid inset by the given direction and amount
    336.   */
    337. public Cuboid inset(CuboidDirection dir, int amount) {
    338. return this.outset(dir, -amount);
    339. }
    340.  
    341. /**
    342.   * Return true if the point at (x,y,z) is contained within this Cuboid.
    343.   *
    344.   * @param x - The X co-ordinate
    345.   * @param y - The Y co-ordinate
    346.   * @param z - The Z co-ordinate
    347.   * @return true if the given point is within this Cuboid, false otherwise
    348.   */
    349. public boolean contains(int x, int y, int z) {
    350. return x >= this.x1 && x <= this.x2 && y >= this.y1 && y <= this.y2 && z >= this.z1 && z <= this.z2;
    351. }
    352.  
    353. /**
    354.   * Check if the given Block is contained within this Cuboid.
    355.   *
    356.   * @param b - The Block to check for
    357.   * @return true if the Block is within this Cuboid, false otherwise
    358.   */
    359. public boolean contains(Block b) {
    360. return this.contains(b.getLocation());
    361. }
    362.  
    363. /**
    364.   * Check if the given Location is contained within this Cuboid.
    365.   *
    366.   * @param l - The Location to check for
    367.   * @return true if the Location is within this Cuboid, false otherwise
    368.   */
    369. public boolean contains(Location l) {
    370. if (!this.worldName.equals(l.getWorld().getName())) return false;
    371. return this.contains(l.getBlockX(), l.getBlockY(), l.getBlockZ());
    372. }
    373.  
    374. /**
    375.   * Get the volume of this Cuboid.
    376.   *
    377.   * @return The Cuboid volume, in blocks
    378.   */
    379. public int getVolume() {
    380. return this.getSizeX() * this.getSizeY() * this.getSizeZ();
    381. }
    382.  
    383. /**
    384.   * Get the average light level of all empty (air) blocks in the Cuboid. Returns 0 if there are no empty blocks.
    385.   *
    386.   * @return The average light level of this Cuboid
    387.   */
    388. public byte getAverageLightLevel() {
    389. long total = 0;
    390. int n = 0;
    391. for (Block b : this) {
    392. if (b.isEmpty()) {
    393. total += b.getLightLevel();
    394. ++n;
    395. }
    396. }
    397. return n > 0 ? (byte) (total / n) : 0;
    398. }
    399.  
    400. /**
    401.   * Contract the Cuboid, returning a Cuboid with any air around the edges removed, just large enough to include all non-air blocks.
    402.   *
    403.   * @return A new Cuboid with no external air blocks
    404.   */
    405. public Cuboid contract() {
    406. return this.contract(CuboidDirection.Down).contract(CuboidDirection.South).contract(CuboidDirection.East).contract(CuboidDirection.Up).contract(CuboidDirection.North).contract(CuboidDirection.West);
    407. }
    408.  
    409. /**
    410.   * Contract the Cuboid in the given direction, returning a new Cuboid which has no exterior empty space.
    411.   * E.g. A direction of Down will push the top face downwards as much as possible.
    412.   *
    413.   * @param dir - The direction in which to contract
    414.   * @return A new Cuboid contracted in the given direction
    415.   */
    416. public Cuboid contract(CuboidDirection dir) {
    417. Cuboid face = getFace(dir.opposite());
    418. switch (dir) {
    419. case Down:
    420. while (face.containsOnly(0) && face.getLowerY() > this.getLowerY()) {
    421. face = face.shift(CuboidDirection.Down, 1);
    422. }
    423. return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x2, face.getUpperY(), this.z2);
    424. case Up:
    425. while (face.containsOnly(0) && face.getUpperY() < this.getUpperY()) {
    426. face = face.shift(CuboidDirection.Up, 1);
    427. }
    428. return new Cuboid(this.worldName, this.x1, face.getLowerY(), this.z1, this.x2, this.y2, this.z2);
    429. case North:
    430. while (face.containsOnly(0) && face.getLowerX() > this.getLowerX()) {
    431. face = face.shift(CuboidDirection.North, 1);
    432. }
    433. return new Cuboid(this.worldName, this.x1, this.y1, this.z1, face.getUpperX(), this.y2, this.z2);
    434. case South:
    435. while (face.containsOnly(0) && face.getUpperX() < this.getUpperX()) {
    436. face = face.shift(CuboidDirection.South, 1);
    437. }
    438. return new Cuboid(this.worldName, face.getLowerX(), this.y1, this.z1, this.x2, this.y2, this.z2);
    439. case East:
    440. while (face.containsOnly(0) && face.getLowerZ() > this.getLowerZ()) {
    441. face = face.shift(CuboidDirection.East, 1);
    442. }
    443. return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x2, this.y2, face.getUpperZ());
    444. case West:
    445. while (face.containsOnly(0) && face.getUpperZ() < this.getUpperZ()) {
    446. face = face.shift(CuboidDirection.West, 1);
    447. }
    448. return new Cuboid(this.worldName, this.x1, this.y1, face.getLowerZ(), this.x2, this.y2, this.z2);
    449. default:
    450. throw new IllegalArgumentException("Invalid direction " + dir);
    451. }
    452. }
    453.  
    454. /**
    455.   * Get the Cuboid representing the face of this Cuboid. The resulting Cuboid will be one block thick in the axis perpendicular to the requested face.
    456.   *
    457.   * @param dir - which face of the Cuboid to get
    458.   * @return The Cuboid representing this Cuboid's requested face
    459.   */
    460. public Cuboid getFace(CuboidDirection dir) {
    461. switch (dir) {
    462. case Down:
    463. return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x2, this.y1, this.z2);
    464. case Up:
    465. return new Cuboid(this.worldName, this.x1, this.y2, this.z1, this.x2, this.y2, this.z2);
    466. case North:
    467. return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x1, this.y2, this.z2);
    468. case South:
    469. return new Cuboid(this.worldName, this.x2, this.y1, this.z1, this.x2, this.y2, this.z2);
    470. case East:
    471. return new Cuboid(this.worldName, this.x1, this.y1, this.z1, this.x2, this.y2, this.z1);
    472. case West:
    473. return new Cuboid(this.worldName, this.x1, this.y1, this.z2, this.x2, this.y2, this.z2);
    474. default:
    475. throw new IllegalArgumentException("Invalid direction " + dir);
    476. }
    477. }
    478.  
    479. /**
    480.   * Check if the Cuboid contains only blocks of the given type
    481.   *
    482.   * @param blockId - The block ID to check for
    483.   * @return true if this Cuboid contains only blocks of the given type
    484.   */
    485. public boolean containsOnly(int blockId) {
    486. for (Block b : this) {
    487. if (b.getTypeId() != blockId) return false;
    488. }
    489. return true;
    490. }
    491.  
    492. /**
    493.   * Get the Cuboid big enough to hold both this Cuboid and the given one.
    494.   *
    495.   * @param other - The other cuboid.
    496.   * @return A new Cuboid large enough to hold this Cuboid and the given Cuboid
    497.   */
    498. public Cuboid getBoundingCuboid(Cuboid other) {
    499. if (other == null) return this;
    500.  
    501. int xMin = Math.min(this.getLowerX(), other.getLowerX());
    502. int yMin = Math.min(this.getLowerY(), other.getLowerY());
    503. int zMin = Math.min(this.getLowerZ(), other.getLowerZ());
    504. int xMax = Math.max(this.getUpperX(), other.getUpperX());
    505. int yMax = Math.max(this.getUpperY(), other.getUpperY());
    506. int zMax = Math.max(this.getUpperZ(), other.getUpperZ());
    507.  
    508. return new Cuboid(this.worldName, xMin, yMin, zMin, xMax, yMax, zMax);
    509. }
    510.  
    511. /**
    512.   * Get a block relative to the lower NE point of the Cuboid.
    513.   *
    514.   * @param x - The X co-ordinate
    515.   * @param y - The Y co-ordinate
    516.   * @param z - The Z co-ordinate
    517.   * @return The block at the given position
    518.   */
    519. public Block getRelativeBlock(int x, int y, int z) {
    520. return this.getWorld().getBlockAt(this.x1 + x, this.y1 + y, this.z1 + z);
    521. }
    522.  
    523. /**
    524.   * Get a block relative to the lower NE point of the Cuboid in the given World. This
    525.   * version of getRelativeBlock() should be used if being called many times, to avoid
    526.   * excessive calls to getWorld().
    527.   *
    528.   * @param w - The world
    529.   * @param x - The X co-ordinate
    530.   * @param y - The Y co-ordinate
    531.   * @param z - The Z co-ordinate
    532.   * @return The block at the given position
    533.   */
    534. public Block getRelativeBlock(World w, int x, int y, int z) {
    535. return w.getBlockAt(this.x1 + x, y1 + y, this.z1 + z);
    536. }
    537.  
    538. /**
    539.   * Get a list of the chunks which are fully or partially contained in this cuboid.
    540.   *
    541.   * @return A list of Chunk objects
    542.   */
    543. public List<Chunk> getChunks() {
    544. List<Chunk> res = new ArrayList<Chunk>();
    545.  
    546. World w = this.getWorld();
    547. int x1 = this.getLowerX() & ~0xf;
    548. int x2 = this.getUpperX() & ~0xf;
    549. int z1 = this.getLowerZ() & ~0xf;
    550. int z2 = this.getUpperZ() & ~0xf;
    551. for (int x = x1; x <= x2; x += 16) {
    552. for (int z = z1; z <= z2; z += 16) {
    553. res.add(w.getChunkAt(x >> 4, z >> 4));
    554. }
    555. }
    556. return res;
    557. }
    558.  
    559. public Iterator<Block> iterator() {
    560. return new CuboidIterator(this.getWorld(), this.x1, this.y1, this.z1, this.x2, this.y2, this.z2);
    561. }
    562.  
    563. @Override
    564. public Cuboid clone() {
    565. return new Cuboid(this);
    566. }
    567.  
    568. @Override
    569. public String toString() {
    570. return new String("Cuboid: " + this.worldName + "," + this.x1 + "," + this.y1 + "," + this.z1 + "=>" + this.x2 + "," + this.y2 + "," + this.z2);
    571. }
    572.  
    573. public class CuboidIterator implements Iterator<Block> {
    574. private World w;
    575. private int baseX, baseY, baseZ;
    576. private int x, y, z;
    577. private int sizeX, sizeY, sizeZ;
    578.  
    579. public CuboidIterator(World w, int x1, int y1, int z1, int x2, int y2, int z2) {
    580. this.w = w;
    581. this.baseX = x1;
    582. this.baseY = y1;
    583. this.baseZ = z1;
    584. this.sizeX = Math.abs(x2 - x1) + 1;
    585. this.sizeY = Math.abs(y2 - y1) + 1;
    586. this.sizeZ = Math.abs(z2 - z1) + 1;
    587. this.x = this.y = this.z = 0;
    588. }
    589.  
    590. public boolean hasNext() {
    591. return this.x < this.sizeX && this.y < this.sizeY && this.z < this.sizeZ;
    592. }
    593.  
    594. public Block next() {
    595. Block b = this.w.getBlockAt(this.baseX + this.x, this.baseY + this.y, this.baseZ + this.z);
    596. if (++x >= this.sizeX) {
    597. this.x = 0;
    598. if (++this.y >= this.sizeY) {
    599. this.y = 0;
    600. ++this.z;
    601. }
    602. }
    603. return b;
    604. }
    605.  
    606. public void remove() {
    607. }
    608. }
    609.  
    610. public enum CuboidDirection {
    611. North, East, South, West, Up, Down, Horizontal, Vertical, Both, Unknown;
    612.  
    613. public CuboidDirection opposite() {
    614. switch (this) {
    615. case North:
    616. return South;
    617. case East:
    618. return West;
    619. case South:
    620. return North;
    621. case West:
    622. return East;
    623. case Horizontal:
    624. return Vertical;
    625. case Vertical:
    626. return Horizontal;
    627. case Up:
    628. return Down;
    629. case Down:
    630. return Up;
    631. case Both:
    632. return Both;
    633. default:
    634. return Unknown;
    635. }
    636. }
    637.  
    638. }
    639.  
    640. }

    Functions: (just call getSphereLocations)
    Code:java
    1. public static ArrayList<Location> getSphereLocations(Location center, Double radius, boolean hollow){
    2. ArrayList<Location> locs = new ArrayList<Location>();
    3. World world = center.getWorld();
    4. Cuboid c = getSquareCuboid(center, radius);
    5. for (Block b : c.getBlocks()){
    6. if (isInSphere(center, radius, b)){
    7. // if (hollow){
    8. // ArrayList<BlockFace> arr = new ArrayList<BlockFace>();
    9. // arr.add(BlockFace.NORTH);
    10. // arr.add(BlockFace.SOUTH);
    11. // arr.add(BlockFace.EAST);
    12. // arr.add(BlockFace.WEST);
    13. // boolean valid = true;
    14. // for (BlockFace face : arr){
    15. // Block blk = b.getRelative(face);
    16. // if (isInSphere(center, radius, blk)){valid = false;}
    17. // }
    18. // if (valid == false){continue;}
    19. // }
    20. if(hollow && isInSphere(center, radius - 1, b)){
    21. continue;
    22. }
    23. locs.add(b.getLocation());
    24. }
    25. }
    26. return locs;
    27. }
    28. public static boolean isInSphere(Location center, Double radius, Block b) {
    29. return b.getLocation().distance(center) <= radius;
    30. }
    31. public static Cuboid getSquareCuboid(Location center, Double radius) {
    32. return new Cuboid(center.clone().subtract(radius, radius, radius), center.clone().add(radius, radius, radius));
    33. }
     
  20. Offline

    megasaad44

    Slikey
    Code:java
    1. public Set<Vector> circle(float r, int a) {
    2. float radius = (float) r;
    3. int amount = a;
    4. Set<Vector> vectors = new HashSet<Vector>();
    5. Random random = new Random();
    6. for (int i = 0; i < amount; i++) {
    7. vectors.add(new Vector(
    8. random.nextFloat() * 2 - 1,
    9. random.nextFloat() * 2 - 1,
    10. random.nextFloat() * 2 - 1
    11. ).normalize().multiply(radius));
    12. }
    13. return vectors;
    14. }

    then
    Code:java
    1. new BukkitRunnable() {
    2. int count = 100;
    3. public void run() {
    4. if (count != 0) {
    5. count--;
    6. } else {
    7. cancel();
    8. }
    9. for (Vector v : circle(20, 20)) {
    10. ParticleEffect.FLAME.display(loc2, (float)v.getX(), (float)v.getY(), (float)v.getZ(), 0, 3);
    11. }
    12. }
    13. }.runTaskTimer(Main.plugin, 30, 1);

    It's a pretty thing for a thing I'm doing.
     
  21. Offline

    Slikey

    Code:java
    1. ParticleEffect.FLAME.display(loc2, (float)v.getX(), (float)v.getY(), (float)v.getZ(), 0, 3);


    1. You create 3 Particles with every packet. (last parameter)
    2. You pass the values of the Vector to the gaussian random parameters.
    Try this:
    Code:java
    1. ParticleEffect.FLAME.display(loc2.add(v), 0, 0, 0, 0, 1);
    2. loc2.subtract(v);
     
  22. Offline

    megasaad44

    Slikey That worked out nicely! Thanks!
    On another problem, do you know how to make a particle move forward from the player's position? Kinda like a fireball being thrown. I don't know how to have the location increment every x ticks forwards.
     
  23. Offline

    Slikey

    No, that is not possible.. :/
     
  24. Offline

    hintss

    incrementally adding the vector from getDirection()?
     
  25. Offline

    biel

    A ParticleEffect isn't an entity, its just a packet that when is sent it plays the effect on the client on a specific location. To move the effect you have to replay it to the new locations.
     
    megasaad44 likes this.
  26. Offline

    hintss

    I didn't mention entities. I know how particle effects work.
     
    megasaad44 likes this.
  27. Offline

    Bobit



    Key word:
    incrementally
     
  28. Offline

    ChipDev

    Never thought that making other particle effects than the standard ones was possible...
     
Thread Status:
Not open for further replies.

Share This Page