Slick Forums
http://slick.ninjacave.com/forum/

HollowCircle
http://slick.ninjacave.com/forum/viewtopic.php?f=9&t=624
Page 1 of 1

Author:  quixote_arg [ Wed Sep 12, 2007 2:13 pm ]
Post subject:  HollowCircle

I was needing a hollow circle that acts as an arena, so that other shapes can be either in or out, but not across it, so I implemented it, it's just an extension to Circle that redefines touches

In case someone finds it useful:

Code:
package net.phys2d.raw.shapes;

/**
 * A hollow circle, only collides with another circles on the border
 *
 * @author Tulsi
 */
public strictfp class HollowCircle extends Circle {

   /**
    * @param radius
    */
   public HollowCircle(float radius) {
      super(radius);
   }

   /**
    * Check if this circle touches another
    *
    * @param x
    *            The x position of this circle
    * @param y
    *            The y position of this circle
    * @param other
    *            The other circle
    * @param ox
    *            The other circle's x position
    * @param oy
    *            The other circle's y position
    * @return True if they touch
    */
   public strictfp boolean touches(float x, float y, Circle other, float ox,
         float oy) {
      float totalRad2 = getRadius() + other.getRadius();
      float dx = Math.abs(ox - x);
      float dy = Math.abs(oy - y);

      float radDiff = getRadius() - other.getRadius();

      // outside
      if (dx > totalRad2 || dy > totalRad2) {
         return false;
      }

      // inside
      if (radDiff * radDiff >= dx * dx + dy * dy) {
         return false;
      }

      // in between
      totalRad2 *= totalRad2;
      return totalRad2 >= ((dx * dx) + (dy * dy));
   }
}


The modified CircleCircleCollider:

Code:
package net.phys2d.raw.collide;

import net.phys2d.math.MathUtil;
import net.phys2d.math.Vector2f;
import net.phys2d.raw.Body;
import net.phys2d.raw.Contact;
import net.phys2d.raw.shapes.Circle;
import net.phys2d.raw.shapes.HollowCircle;

/**
 * A collider for circle 2 circle collisions
 *
 * The create() method is used as a factory just in case this class becomes
 * stateful eventually.
 *
 * @author Kevin Glass
 */
public strictfp class CircleCircleCollider implements Collider {
   /**
    * @see net.phys2d.raw.collide.Collider#collide(net.phys2d.raw.Contact[],
    *      net.phys2d.raw.Body, net.phys2d.raw.Body)
    */
   public int collide(Contact[] contacts, Body bodyA, Body bodyB) {
      float x1 = bodyA.getPosition().getX();
      float y1 = bodyA.getPosition().getY();
      float x2 = bodyB.getPosition().getX();
      float y2 = bodyB.getPosition().getY();

      boolean touches = bodyA.getShape().getBounds().touches(x1, y1,
            bodyB.getShape().getBounds(), x2, y2);
      if (!touches) {
         return 0;
      }

      Circle circleA = (Circle) bodyA.getShape();
      Circle circleB = (Circle) bodyB.getShape();

      touches = circleA.touches(x1, y1, circleB, x2, y2);
      if (!touches) {
         return 0;
      }

      Vector2f normal = MathUtil
            .sub(bodyB.getPosition(), bodyA.getPosition());
      float sep = (circleA.getRadius() + circleB.getRadius())
            - normal.length();
      normal.normalise();

      Vector2f pt = MathUtil.scale(normal, circleA.getRadius());
      pt.add(bodyA.getPosition());

      contacts[0].setPosition(pt);
      if (sep < circleB.getRadius() || !(circleA instanceof HollowCircle)) {
         contacts[0].setNormal(normal);
         contacts[0].setSeparation(-sep);
      } else {
         // we're on the inside
         contacts[0].setNormal(normal.negate());
         contacts[0].setSeparation(-(circleB.getRadius() - sep));
      }

      FeaturePair fp = new FeaturePair();
      contacts[0].setFeature(fp);

      return 1;
   }
}


And finally a HollowCircleDemo:

Code:
package net.phys2d.raw.test;

import net.phys2d.raw.Body;
import net.phys2d.raw.StaticBody;
import net.phys2d.raw.World;
import net.phys2d.raw.shapes.Circle;
import net.phys2d.raw.shapes.HollowCircle;

/**
 * A simple demo with HollowCircle
 *
 * @author Tulsi
 */
public class HollowCircleDemo extends AbstractDemo {
   /**
    * Create the demo
    */
   public HollowCircleDemo() {
      super("Phys2D HollowCircle Demo");
   }

   /**
    * @see net.phys2d.raw.test.AbstractDemo#init(net.phys2d.raw.World)
    */
   protected void init(World world) {
      Body body1 = new StaticBody("bounds", new HollowCircle(200));
      body1.setPosition(250, 250);
      body1.setRestitution(1);
      world.add(body1);

      Body body2 = new Body(new Circle(20), 10);
      body2.setPosition(300, 200);
      body2.setRestitution(1);
      world.add(body2);

      Body body3 = new Body(new Circle(5), 10);
      body3.setPosition(200, 150);
      body3.setRestitution(1);
      world.add(body3);

      Body body4 = new Body(new Circle(30), 10);
      body4.setPosition(222, 111);
      body4.setRestitution(1);
      world.add(body4);
   }

   /**
    * Entry point for tetsing
    *
    * @param argv
    *            The arguments to the test
    */
   public static void main(String[] argv) {
      HollowCircleDemo demo = new HollowCircleDemo();
      demo.start();
   }
}



kev, jon or anybody, if you want a diff patch, just let me know

Author:  TriggerThirst [ Wed Sep 12, 2007 5:49 pm ]
Post subject: 

Instead of making it a stricly hollow circle it might be good for someone to create a torus shape instead.

http://en.wikipedia.org/wiki/Torus

Author:  kevglass [ Wed Sep 12, 2007 6:05 pm ]
Post subject: 

Isn't a Torus a 3 dimensional shape? Do you mean a ring?

Kev

Author:  Jon [ Wed Sep 12, 2007 6:13 pm ]
Post subject: 

I think he means a donut shape in which hollow circle is the special case where r1 and r2 are the same.

- Jon

Author:  TriggerThirst [ Wed Sep 12, 2007 7:47 pm ]
Post subject: 

Yea, what Jon said. I guess donut would be a better name for it since we arent 3D...

http://en.wikipedia.org/wiki/Doughnut

Page 1 of 1 All times are UTC
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/