Subversion Repositories AndroidProjects

Rev

Blame | Last modification | View Log | RSS feed

package com.gebauz.bauzoid.math.collision;

import com.gebauz.bauzoid.graphics.Graphics;
import com.gebauz.bauzoid.graphics.RenderUtil;
import com.gebauz.bauzoid.graphics.sprite.SpriteTransform;
import com.gebauz.bauzoid.math.Line2;
import com.gebauz.bauzoid.math.MathUtil;
import com.gebauz.bauzoid.math.Vector2;
import com.gebauz.bauzoid.math.Vector4;

public class EllipseElement extends BaseShapeElement
{
        // Constants========================================================================================
       
        public static final int NUM_LINE_SEGMENTS = RenderUtil.NUM_ELLIPSE_STEPS;

        // Embedded Types===================================================================================

        // Fields===========================================================================================
       
        public float x;
        public float y;
        public float radiusX;
        public float radiusY;
       
        private Vector2 mTempA = new Vector2();
        private Vector2 mTempB = new Vector2();
       
        // Methods==========================================================================================
       
        public EllipseElement(Shape shape, float initX, float initY, float initRadiusX, float initRadiusY, int startFrame, int endFrame)
        {
                super(shape, startFrame, endFrame);
                x = initX; y = initY;
                radiusX = initRadiusX; radiusY = initRadiusY;
        }
       
        public EllipseElement(Shape shape, float initX, float initY, float initRadiusX, float initRadiusY)
        {
                this(shape, initX, initY, initRadiusX, initRadiusY, -1, -1);
        }
       
        @Override
        public BaseShapeElement copy(Shape newOwner)
        {
                return new EllipseElement(newOwner, x, y, radiusX, radiusY);           
        }
       
        @Override
        public void renderDebug(Graphics graphics, SpriteTransform t)
        {
                RenderUtil.drawEllipse(graphics, (x-radiusX) * t.w, (y-radiusY) * t.h, (x+radiusX) * t.w, (y+radiusY) * t.h, t, new Vector4(1, 0, 0, 1));
        }
       
        @Override
        public boolean isInside(float _x, float _y)
        {
                if (radiusX == 0)
                        return false;
                if (radiusY == 0)
                        return false;
               
                float px = _x/getOwner().transform.w;
                float py = _y/getOwner().transform.h;
                               
                float dx = (px - x);
                float dy = (py - y);
               
                return (((dx*dx)/(radiusX*radiusX) + (dy*dy)/(radiusY*radiusY)) <= 1);         
        }
       
        @Override
        public Vector2[] getUntransformedPoints()
        {
                final float angleStep = 360.0f / NUM_LINE_SEGMENTS;
               
                if (mUntransformedPoints == null)
                {
                        mUntransformedPoints = new Vector2[NUM_LINE_SEGMENTS];
                        for (int i = 0; i < mUntransformedPoints.length; i++)
                                mUntransformedPoints[i] = new Vector2();                               
                }
               
                for (int i = 0; i < NUM_LINE_SEGMENTS; i++)
                {
                        mUntransformedPoints[i].set(x + MathUtil.sin(angleStep * i) * radiusX, y + MathUtil.cos(angleStep * i) * radiusY);             
                }
               
                return mUntransformedPoints;
        }
       
        @Override
        public Vector2[] getPoints()
        {
                final float angleStep = 360.0f / NUM_LINE_SEGMENTS;
               
                if (mPoints == null)
                {
                        mPoints = new Vector2[NUM_LINE_SEGMENTS];
                        for (int i = 0; i < mPoints.length; i++)
                                mPoints[i] = new Vector2();
                }
               
                SpriteTransform t = getOwner().transform;
               
                for (int i = 0; i < NUM_LINE_SEGMENTS; i++)
                {
                        //mPoints[i] = t.spriteToWorld(x + MathUtil.sin(angleStep * i) * radiusX, y + MathUtil.cos(angleStep * i) * radiusY);
                        t.spriteToWorld(x + MathUtil.sin(angleStep * i) * radiusX, y + MathUtil.cos(angleStep * i) * radiusY, mPoints[i]);
                        mPoints[i].x *= t.w;
                        mPoints[i].y *= t.h;
                }
               
                return mPoints;
        }
       
        @Override
        public Line2[] getUntransformedLineSegments()
        {
                final float angleStep = 360.0f / NUM_LINE_SEGMENTS;
               
                if (mUntransformedLines == null)
                {
                        mUntransformedLines = new Line2[NUM_LINE_SEGMENTS];
                        for (int i = 0; i < mUntransformedLines.length; i++)
                                mUntransformedLines[i] = new Line2();
                }
               
                SpriteTransform t = getOwner().transform;
               
                for (int i = 0; i < NUM_LINE_SEGMENTS; i++)
                {
                        float x1 = x + MathUtil.sin(angleStep * i) * radiusX;
                        float y1 = y + MathUtil.cos(angleStep * i) * radiusY;
                       
                        float x2 = x + MathUtil.sin(angleStep * (i + 1)) * radiusX;
                        float y2 = y + MathUtil.cos(angleStep * (i + 1)) * radiusY;
                       
                        x1 *= t.w;
                        x2 *= t.w;
                        y1 *= t.h;
                        y2 *= t.h;
                       
                        //mUntransformedLines[i] = new Line2(x1, y1, x2, y2);
                        mUntransformedLines[i].set(x1, y1, x2, y2);
                }
               
                return mUntransformedLines;
        }      
       
        @Override
        public Line2[] getLineSegments()
        {
                final float angleStep = 360.0f / NUM_LINE_SEGMENTS;
               
                if (mLines == null)
                {
                        mLines = new Line2[NUM_LINE_SEGMENTS];
                        for (int i = 0; i < mLines.length; i++)
                                mLines[i] = new Line2();
                }
               
                SpriteTransform t = getOwner().transform;
               
                for (int i = 0; i < NUM_LINE_SEGMENTS; i++)
                {
                        float x1 = x + MathUtil.sin(angleStep * i) * radiusX;
                        float y1 = y + MathUtil.cos(angleStep * i) * radiusY;
                       
                        float x2 = x + MathUtil.sin(angleStep * (i + 1)) * radiusX;
                        float y2 = y + MathUtil.cos(angleStep * (i + 1)) * radiusY;
                       
                        //mLines[i] = new Line2(t.spriteToWorld(x1 * t.w, y1 * t.h), t.spriteToWorld(x2 * t.w, y2 * t.h));
                        t.spriteToWorld(x1 * t.w, y1 * t.h, mTempA);
                        mLines[i].setPointA(mTempA.x, mTempA.y);
                       
                        t.spriteToWorld(x2 * t.w, y2 * t.h, mTempA);
                        mLines[i].setPointB(mTempA.x, mTempA.y);
                }
               
                return mLines;
        }
       
        /*
        @Override
        public Line2[] getSweepLineSegments(Vector2 move)
        {
                final float angleStep = 360.0f / NUM_LINE_SEGMENTS;
               
                if (mSweepLines == null)
                        mSweepLines = new Line2[NUM_LINE_SEGMENTS*2];
               
                SpriteTransform t = getOwner().transform;
               
                for (int i = 0; i < NUM_LINE_SEGMENTS; i++)
                {
                        float x1 = x + MathUtil.sin(angleStep * i) * radiusX;
                        float y1 = y + MathUtil.cos(angleStep * i) * radiusY;
                       
                        float x2 = x + MathUtil.sin(angleStep * (i + 1)) * radiusX;
                        float y2 = y + MathUtil.cos(angleStep * (i + 1)) * radiusY;
                       
                        mSweepLines[i] = new Line2(t.spriteToWorld(x1 * t.w, y1 * t.h), t.spriteToWorld(x2 * t.w, y2 * t.h));                  
                }
               
                for (int i = 0; i < NUM_LINE_SEGMENTS; i++)
                {
                        float x1 = x + MathUtil.sin(angleStep * i) * radiusX + move.x;
                        float y1 = y + MathUtil.cos(angleStep * i) * radiusY + move.y;
                       
                        float x2 = x + MathUtil.sin(angleStep * (i + 1)) * radiusX + move.x;
                        float y2 = y + MathUtil.cos(angleStep * (i + 1)) * radiusY + move.y;
                       
                        mSweepLines[i + NUM_LINE_SEGMENTS] = new Line2(t.spriteToWorld(x1 * t.w, y1 * t.h), t.spriteToWorld(x2 * t.w, y2 * t.h));                      
                }
               
                return mSweepLines;
        }*/

       
        @Override
        public Vector2[] getProjectionAxes()
        {
                final float angleStep = 360.0f / NUM_LINE_SEGMENTS;
               
                if (mProjectionAxes == null)
                {
                        mProjectionAxes = new Vector2[NUM_LINE_SEGMENTS/2];
                        for (int i = 0; i < mProjectionAxes.length; i++)
                                mProjectionAxes[i] = new Vector2();
                }
               
                SpriteTransform t = getOwner().transform;
               
                // half suffice
                for (int i = 0; i < (NUM_LINE_SEGMENTS/2); i++)
                {
                        float x1 = x + MathUtil.sin(angleStep * i) * radiusX;
                        float y1 = y + MathUtil.cos(angleStep * i) * radiusY;
                       
                        float x2 = x + MathUtil.sin(angleStep * (i + 1)) * radiusX;
                        float y2 = y + MathUtil.cos(angleStep * (i + 1)) * radiusY;
                       
                        /*Vector2 a = t.spriteToWorld(x1 * t.w, y1 * t.h);
                        Vector2 b = t.spriteToWorld(x2 * t.w, y2 * t.h);
                       
                        mProjectionAxes[i] = new Vector2(b.x-a.x, b.y-a.y);*/

                       
                        t.spriteToWorld(x1 * t.w, y1 * t.h, mTempA);
                        t.spriteToWorld(x2 * t.w, y2 * t.h, mTempB);
                        mProjectionAxes[i].set(mTempB.x - mTempA.x, mTempB.y - mTempA.y);
                       
                }
               
                for (int i = 0; i < mProjectionAxes.length; i++)
                {
                        mProjectionAxes[0].set(mProjectionAxes[0].y, -mProjectionAxes[0].x);
                }
               
                return mProjectionAxes;
        }
       
        // Getters/Setters==================================================================================
}