Difference between revisions of "User:Dsekercioglu/MEA"

From Robowiki
Jump to navigation Jump to search
(Wrote my MEA calculation)
 
(Changed Math.PI to PI (Java Reflexes) =))
 
(5 intermediate revisions by the same user not shown)
Line 1: Line 1:
:After brute force MEA calculations, I realised that moving fully orbital wasn't the best option to maximise the [[MEA]]. I found a function with polynomial regression which works very well.
+
After doing some tests with the code below I have found out that every [[MEA]] theory I have written was wrong.
 +
 
 +
==Code==
  
;Old Brute Force [[MEA]]
 
 
<pre>
 
<pre>
         double highestMea;
+
package dsekercioglu.mega.mea;
         for (int a = 0; a < 360000; a++) { // For higher accuracy. Normal value is 360.
+
 
             double angle = Math.toRadians(a / 1000.0);
+
import java.awt.geom.Point2D;
             double mea = Math.sin(angle) / (bulletSpeed / 8 - Math.cos(angle));
+
import java.util.ArrayList;
            if (mea > highestMea) {
+
 
                 highestMea = mea;
+
public class Test {
 +
 
 +
    static MEAFormula[] formulas = new MEAFormula[4];
 +
    static final double SIM_SENSITIVITY = 50000;
 +
    static final double DISTANCE = 500;
 +
    static final boolean LINEAR_MOVE = false;
 +
 
 +
    public static void main(String[] args) {
 +
        formulas[0] = new TraditionalMEA();
 +
         formulas[1] = new TraditionalMEAPlusSomeNumber(0);
 +
        formulas[2] = new DsekerciogluOldMEA();
 +
        formulas[3] = new DsekerciogluTestMEA(0.01);
 +
         for (int f = 0; f < formulas.length; f++) {
 +
            System.out.println("=================================" + formulas[f].getName() + "=================================");
 +
            int counter = 0;
 +
             double averageMEA = 0;
 +
             for (int i = 110; i <= 197; i++) {
 +
                double bulletSpeed = i * 0.1;
 +
                Bot b = new Bot(formulas[f].getRetreatAngle(bulletSpeed), formulas[f].getTurnPerTick(DISTANCE));
 +
                Wave w = new Wave(bulletSpeed);
 +
                Point2D.Double intersection;
 +
                if (!LINEAR_MOVE) {
 +
                    while (w.source.distance(b.location) > w.distanceTraveled) {
 +
                        w.update();
 +
                        b.update();
 +
                    }
 +
                    intersection = b.location;
 +
                } else {
 +
                    intersection = b.interceptWave(w);
 +
                }
 +
                 averageMEA += (absoluteBearing(w.source, intersection) - averageMEA) / (++counter);
 +
                System.out.println("Bullet Speed: " + bulletSpeed + ":");
 +
                System.out.println("Escape Angle: " + absoluteBearing(w.source, intersection));
 +
                System.out.println("Prediction: " + formulas[f].getMEA(bulletSpeed));
 +
                System.out.println("");
 
             }
 
             }
 +
            System.out.println("Average MEA:" + averageMEA);
 +
        }
 +
    }
 +
 +
    public static class Wave {
 +
 +
        Point2D.Double source = new Point2D.Double(0, 0);//starting from the origin
 +
        final double VELOCITY;
 +
        double distanceTraveled;
 +
 +
        public Wave(double velocity) {
 +
            this.VELOCITY = velocity;//We don't set distanceTraveled to velocity since the MEA calculations doesn't take that into account.
 +
        }
 +
 +
        public void update() {
 +
            distanceTraveled += VELOCITY / SIM_SENSITIVITY;
 +
        }
 +
    }
 +
 +
    public static class Bot {
 +
 +
        Point2D.Double location = new Point2D.Double(0, DISTANCE);
 +
        final double VELOCITY = 8;
 +
        final double TURN;
 +
        double angle;
 +
 +
        public Bot(double retreatAngle, double turnPerTick) {
 +
            angle = retreatAngle;
 +
            TURN = turnPerTick;
 +
 +
        }
 +
 +
        public void update() {
 +
            location = project(location, angle, VELOCITY / SIM_SENSITIVITY);
 +
            angle += TURN / SIM_SENSITIVITY;
 +
        }
 +
 +
        public Point2D.Double interceptWave(Wave w) {
 +
            return intercept(w.source, w.VELOCITY, location, angle, VELOCITY);
 +
        }
 +
    }
 +
 +
    //CREDIT: Chase-san
 +
    public static Point2D.Double intercept(Point2D pos, double vel, Point2D tPos, double tHeading, double tVel) {
 +
        double tVelX = Math.sin(tHeading) * tVel;
 +
        double tVelY = Math.cos(tHeading) * tVel;
 +
        double relX = tPos.getX() - pos.getX();
 +
        double relY = tPos.getY() - pos.getY();
 +
        double b = relX * tVelX + relY * tVelY;
 +
        double a = vel * vel - tVel * tVel;
 +
        b = (b + Math.sqrt(b * b + a * (relX * relX + relY * relY))) / a;
 +
        return new Point2D.Double(tVelX * b + tPos.getX(), tVelY * b + tPos.getY());
 +
    }
 +
 +
    public static abstract class MEAFormula {
 +
 +
        public abstract double getMEA(double bulletSpeed);
 +
 +
        public abstract double getRetreatAngle(double bulletSpeed);
 +
 +
        public abstract double getTurnPerTick(double distance);
 +
 +
        public abstract String getName();
 +
 +
    }
 +
 +
    public static class DsekerciogluOldMEA extends MEAFormula {
 +
 +
        @Override
 +
        public double getMEA(double bulletSpeed) {
 +
            double x = bulletSpeed;
 +
            double xx = x * x;
 +
            double xxx = xx * x;
 +
            double a = 4.626248824E-7;
 +
            double b = -4.203721619E-5;
 +
            double c = 1.571662957E-3;
 +
            double d = -3.085855208E-2;
 +
            double e = 3.337262571E-1;
 +
            double f = -2.893934846E-1;
 +
            double angle = a * xxx * xx + b * xx * xx + c * xxx + d * xx + e * x + f;
 +
            return Math.asin(Math.sin(angle) / (bulletSpeed / 8 - Math.cos(angle) / 2));
 +
        }
 +
 +
        @Override
 +
        public double getRetreatAngle(double bulletSpeed) {
 +
            double x = bulletSpeed;
 +
            double xx = x * x;
 +
            double xxx = xx * x;
 +
            double a = 4.626248824E-7;
 +
            double b = -4.203721619E-5;
 +
            double c = 1.571662957E-3;
 +
            double d = -3.085855208E-2;
 +
            double e = 3.337262571E-1;
 +
            double f = -2.893934846E-1;
 +
            return a * xxx * xx + b * xx * xx + c * xxx + d * xx + e * x + f;
 +
        }
 +
 +
        @Override
 +
        public double getTurnPerTick(double distance) {
 +
            return 0;
 +
        }
 +
 +
        @Override
 +
        public String getName() {
 +
            return "Dsekercioglu's Old MEA";
 
         }
 
         }
         return highestMea;
+
 
 +
    }
 +
 
 +
    public static class TraditionalMEA extends MEAFormula {
 +
 
 +
         @Override
 +
        public double getMEA(double bulletSpeed) {
 +
            return Math.asin(8 / bulletSpeed);
 +
        }
 +
 
 +
        @Override
 +
        public double getRetreatAngle(double bulletSpeed) {
 +
            return Math.PI / 2;
 +
        }
 +
 
 +
        @Override
 +
        public double getTurnPerTick(double distance) {
 +
            return 0;
 +
        }
 +
 
 +
        @Override
 +
        public String getName() {
 +
            return "Traditional MEA";
 +
        }
 +
 
 +
    }
 +
 
 +
    public static class TraditionalMEAPlusSomeNumber extends MEAFormula {
 +
 
 +
        private final double EXTRA;
 +
 
 +
        public TraditionalMEAPlusSomeNumber(double extra) {
 +
            EXTRA = extra;
 +
        }
 +
 
 +
        @Override
 +
        public double getMEA(double bulletSpeed) {
 +
            return Math.asin(8 / bulletSpeed);
 +
        }
 +
 
 +
        @Override
 +
        public double getRetreatAngle(double bulletSpeed) {
 +
            return Math.PI / 2 + EXTRA;
 +
        }
 +
 
 +
        @Override
 +
        public double getTurnPerTick(double distance) {
 +
            return 0;
 +
        }
 +
 
 +
        @Override
 +
        public String getName() {
 +
            return "Traditional MEA Plus " + EXTRA;
 +
        }
 +
 
 +
    }
 +
 
 +
    public static class DsekerciogluTestMEA extends MEAFormula {
 +
       
 +
        private final double RETREAT_FACTOR;
 +
       
 +
        public DsekerciogluTestMEA(double retreatFactor) {
 +
            RETREAT_FACTOR = retreatFactor;
 +
        }
 +
 
 +
        @Override
 +
        public double getMEA(double bulletSpeed) {
 +
            return 0;
 +
        }
 +
 
 +
        @Override
 +
        public double getRetreatAngle(double bulletSpeed) {
 +
            return Math.PI / 2;
 +
        }
 +
 
 +
        @Override
 +
        public double getTurnPerTick(double distance) {
 +
            return RETREAT_FACTOR / distance;
 +
        }
 +
 
 +
        @Override
 +
        public String getName() {
 +
            return "Dsekercioglu Test MEA";
 +
        }
 +
 
 +
    }
 +
 
 +
    public static Point2D.Double project(Point2D.Double source, double angle, double distance) {
 +
        return new Point2D.Double(source.x + Math.sin(angle) * distance, source.y + Math.cos(angle) * distance);
 +
    }
 +
 
 +
    public static double absoluteBearing(Point2D.Double p1, Point2D.Double p2) {
 +
        return Math.atan2(p2.x - p1.x, p2.y - p1.y);
 +
    }
 +
}
 +
 
 +
</pre>
 +
 
 +
 
 +
==Test Results==
 +
 
 +
;My Old MEA
 +
 
 +
<pre>
 +
Bullet Speed: 11.0:
 +
Escape Angle: 0.7443390319356681
 +
Prediction: 0.8958173020565081
 +
 
 +
Bullet Speed: 11.100000000000001:
 +
Escape Angle: 0.7373080257129179
 +
Prediction: 0.8829756036277365
 +
 
 +
Bullet Speed: 11.200000000000001:
 +
Escape Angle: 0.7304125890046199
 +
Prediction: 0.8706053037227797
 +
 
 +
Bullet Speed: 11.3:
 +
Escape Angle: 0.7236486178072312
 +
Prediction: 0.8586747798058824
 +
 
 +
Bullet Speed: 11.4:
 +
Escape Angle: 0.7170121910884176
 +
Prediction: 0.8471556332457875
 +
 
 +
Bullet Speed: 11.5:
 +
Escape Angle: 0.7104995591301005
 +
Prediction: 0.8360222462765713
 +
 
 +
Bullet Speed: 11.600000000000001:
 +
Escape Angle: 0.7041071328615146
 +
Prediction: 0.8252514148545027
 +
 
 +
Bullet Speed: 11.700000000000001:
 +
Escape Angle: 0.6978314740784414
 +
Prediction: 0.8148220420131798
 +
 
 +
Bullet Speed: 11.8:
 +
Escape Angle: 0.6916692864575538
 +
Prediction: 0.8047148798932051
 +
 
 +
Bullet Speed: 11.9:
 +
Escape Angle: 0.685617407285771
 +
Prediction: 0.7949123112702848
 +
 
 +
Bullet Speed: 12.0:
 +
Escape Angle: 0.6796727998340208
 +
Prediction: 0.7853981633902923
 +
 
 +
Bullet Speed: 12.100000000000001:
 +
Escape Angle: 0.6738325463130002
 +
Prediction: 0.7761575484239104
 +
 
 +
Bullet Speed: 12.200000000000001:
 +
Escape Angle: 0.668093841355649
 +
Prediction: 0.7671767260049279
 +
 
 +
Bullet Speed: 12.3:
 +
Escape Angle: 0.6624539859772478
 +
Prediction: 0.7584429842061166
 +
 
 +
Bullet Speed: 12.4:
 +
Escape Angle: 0.6569103819694577
 +
Prediction: 0.7499445360003807
 +
 
 +
Bullet Speed: 12.5:
 +
Escape Angle: 0.6514605266893417
 +
Prediction: 0.74167042880019
 +
 
 +
Bullet Speed: 12.600000000000001:
 +
Escape Angle: 0.646102008208559
 +
Prediction: 0.7336104651002772
 +
 
 +
Bullet Speed: 12.700000000000001:
 +
Escape Angle: 0.6408325007915578
 +
Prediction: 0.7257551325932152
 +
 
 +
Bullet Speed: 12.8:
 +
Escape Angle: 0.6356497606747965
 +
Prediction: 0.7180955424043315
 +
 
 +
Bullet Speed: 12.9:
 +
Escape Angle: 0.6305516221218561
 +
Prediction: 0.7106233743162302
 +
 
 +
Bullet Speed: 13.0:
 +
Escape Angle: 0.6255359937317999
 +
Prediction: 0.7033308280352042
 +
 
 +
Bullet Speed: 13.100000000000001:
 +
Escape Angle: 0.620600854980369
 +
Prediction: 0.6962105797007199
 +
 
 +
Bullet Speed: 13.200000000000001:
 +
Escape Angle: 0.6157442529755357
 +
Prediction: 0.6892557429615973
 +
 
 +
Bullet Speed: 13.3:
 +
Escape Angle: 0.6109642994107284
 +
Prediction: 0.682459834043714
 +
 
 +
Bullet Speed: 13.4:
 +
Escape Angle: 0.6062591677005588
 +
Prediction: 0.6758167403181464
 +
 
 +
Bullet Speed: 13.5:
 +
Escape Angle: 0.601627090285309
 +
Prediction: 0.669320691948796
 +
 
 +
Bullet Speed: 13.600000000000001:
 +
Escape Angle: 0.5970663560916503
 +
Prediction: 0.6629662362573612
 +
 
 +
Bullet Speed: 13.700000000000001:
 +
Escape Angle: 0.5925753081382007
 +
Prediction: 0.6567482144929919
 +
 
 +
Bullet Speed: 13.8:
 +
Escape Angle: 0.5881523412755126
 +
Prediction: 0.6506617407357893
 +
 
 +
Bullet Speed: 13.9:
 +
Escape Angle: 0.5837959000509967
 +
Prediction: 0.6447021826987749
 +
 
 +
Bullet Speed: 14.0:
 +
Escape Angle: 0.5795044766900752
 +
Prediction: 0.638865144223163
 +
 
 +
Bullet Speed: 14.100000000000001:
 +
Escape Angle: 0.575276609185606
 +
Prediction: 0.6331464492875558
 +
 
 +
Bullet Speed: 14.200000000000001:
 +
Escape Angle: 0.5711108794882658
 +
Prediction: 0.6275421273738028
 +
 
 +
Bullet Speed: 14.3:
 +
Escape Angle: 0.5670059117911797
 +
Prediction: 0.6220484000512764
 +
 
 +
Bullet Speed: 14.4:
 +
Escape Angle: 0.562960370902617
 +
Prediction: 0.6166616686577209
 +
 
 +
Bullet Speed: 14.5:
 +
Escape Angle: 0.5589729607010712
 +
Prediction: 0.6113785029690175
 +
 
 +
Bullet Speed: 14.600000000000001:
 +
Escape Angle: 0.5550424226674765
 +
Prediction: 0.6061956307625184
 +
 
 +
Bullet Speed: 14.700000000000001:
 +
Escape Angle: 0.5511675344897213
 +
Prediction: 0.6011099281893126
 +
 
 +
Bullet Speed: 14.8:
 +
Escape Angle: 0.5473471087349788
 +
Prediction: 0.5961184108801252
 +
 
 +
Bullet Speed: 14.9:
 +
Escape Angle: 0.5435799915857266
 +
Prediction: 0.5912182257177159
 +
 
 +
Bullet Speed: 15.0:
 +
Escape Angle: 0.5398650616356022
 +
Prediction: 0.5864066432158043
 +
 
 +
Bullet Speed: 15.100000000000001:
 +
Escape Angle: 0.5362012287415584
 +
Prediction: 0.5816810504508354
 +
 
 +
Bullet Speed: 15.200000000000001:
 +
Escape Angle: 0.532587432929
 +
Prediction: 0.5770389444984385
 +
 
 +
Bullet Speed: 15.3:
 +
Escape Angle: 0.5290226433468467
 +
Prediction: 0.5724779263313178
 +
 
 +
Bullet Speed: 15.4:
 +
Escape Angle: 0.5255058572696637
 +
Prediction: 0.5679956951396367
 +
 
 +
Bullet Speed: 15.5:
 +
Escape Angle: 0.5220360991442051
 +
Prediction: 0.5635900430387886
 +
 
 +
Bullet Speed: 15.600000000000001:
 +
Escape Angle: 0.5186124196778965
 +
Prediction: 0.559258850132841
 +
 
 +
Bullet Speed: 15.700000000000001:
 +
Escape Angle: 0.5152338949669462
 +
Prediction: 0.555000079904977
 +
 
 +
Bullet Speed: 15.8:
 +
Escape Angle: 0.511899625661932
 +
Prediction: 0.5508117749089398
 +
 
 +
Bullet Speed: 15.9:
 +
Escape Angle: 0.5086087361688503
 +
Prediction: 0.5466920527379062
 +
 
 +
Bullet Speed: 16.0:
 +
Escape Angle: 0.5053603738837394
 +
Prediction: 0.5426391022493595
 +
 
 +
Bullet Speed: 16.1:
 +
Escape Angle: 0.5021537084591243
 +
Prediction: 0.5386511800264655
 +
 
 +
Bullet Speed: 16.2:
 +
Escape Angle: 0.4989879311006239
 +
Prediction: 0.5347266070581833
 +
 
 +
Bullet Speed: 16.3:
 +
Escape Angle: 0.4958622538921788
 +
Prediction: 0.5308637656219011
 +
 
 +
Bullet Speed: 16.400000000000002:
 +
Escape Angle: 0.49277590914844127
 +
Prediction: 0.5270610963537865
 +
 
 +
Bullet Speed: 16.5:
 +
Escape Angle: 0.48972814879298004
 +
Prediction: 0.5233170954933015
 +
 
 +
Bullet Speed: 16.6:
 +
Escape Angle: 0.4867182437609991
 +
Prediction: 0.519630312289474
 +
 
 +
Bullet Speed: 16.7:
 +
Escape Angle: 0.48374548342538626
 +
Prediction: 0.5159993465575505
 +
 
 +
Bullet Speed: 16.8:
 +
Escape Angle: 0.48080917504494824
 +
Prediction: 0.5124228463755808
 +
 
 +
Bullet Speed: 16.900000000000002:
 +
Escape Angle: 0.477908643233771
 +
Prediction: 0.5088995059113369
 +
 
 +
Bullet Speed: 17.0:
 +
Escape Angle: 0.4750432294507034
 +
Prediction: 0.5054280633707354
 +
 
 +
Bullet Speed: 17.1:
 +
Escape Angle: 0.47221229150801264
 +
Prediction: 0.5020072990596257
 +
 
 +
Bullet Speed: 17.2:
 +
Escape Angle: 0.46941520309832563
 +
Prediction: 0.49863603355144803
 +
 
 +
Bullet Speed: 17.3:
 +
Escape Angle: 0.466651353339011
 +
Prediction: 0.4953131259538367
 +
 
 +
Bullet Speed: 17.400000000000002:
 +
Escape Angle: 0.4639201463332056
 +
Prediction: 0.49203747226777644
 +
 
 +
Bullet Speed: 17.5:
 +
Escape Angle: 0.46122100074673794
 +
Prediction: 0.48880800383339884
 +
 
 +
Bullet Speed: 17.6:
 +
Escape Angle: 0.4585533494002351
 +
Prediction: 0.4856236858569444
 +
 
 +
Bullet Speed: 17.7:
 +
Escape Angle: 0.4559166388757421
 +
Prediction: 0.48248351601382566
 +
 
 +
Bullet Speed: 17.8:
 +
Escape Angle: 0.4533103291372156
 +
Prediction: 0.479386523123083
 +
 
 +
Bullet Speed: 17.900000000000002:
 +
Escape Angle: 0.45073389316429485
 +
Prediction: 0.47633176588887804
 +
 
 +
Bullet Speed: 18.0:
 +
Escape Angle: 0.4481868165987693
 +
Prediction: 0.4733183317049672
 +
 
 +
Bullet Speed: 18.1:
 +
Escape Angle: 0.44566859740320997
 +
Prediction: 0.4703453355183887
 +
 
 +
Bullet Speed: 18.2:
 +
Escape Angle: 0.4431787455312451
 +
Prediction: 0.4674119187488613
 +
 
 +
Bullet Speed: 18.3:
 +
Escape Angle: 0.44071678260898817
 +
Prediction: 0.4645172482606248
 +
 
 +
Bullet Speed: 18.400000000000002:
 +
Escape Angle: 0.43828224162716545
 +
Prediction: 0.46166051538368624
 +
 
 +
Bullet Speed: 18.5:
 +
Escape Angle: 0.4358746666434845
 +
Prediction: 0.4588409349816298
 +
 
 +
Bullet Speed: 18.6:
 +
Escape Angle: 0.4334936124948371
 +
Prediction: 0.45605774456334336
 +
 
 +
Bullet Speed: 18.7:
 +
Escape Angle: 0.43113864451892525
 +
Prediction: 0.45331020343618766
 +
 
 +
Bullet Speed: 18.8:
 +
Escape Angle: 0.4288093382849335
 +
Prediction: 0.4505975918982937
 +
 
 +
Bullet Speed: 18.900000000000002:
 +
Escape Angle: 0.42650527933288
 +
Prediction: 0.4479192104678227
 +
 
 +
Bullet Speed: 19.0:
 +
Escape Angle: 0.4242260629212929
 +
Prediction: 0.44527437914716245
 +
 
 +
Bullet Speed: 19.1:
 +
Escape Angle: 0.42197129378288556
 +
Prediction: 0.44266243672015787
 +
 
 +
Bullet Speed: 19.200000000000003:
 +
Escape Angle: 0.4197405858879035
 +
Prediction: 0.44008274008059534
 +
 
 +
Bullet Speed: 19.3:
 +
Escape Angle: 0.4175335622148354
 +
Prediction: 0.4375346635902649
 +
 
 +
Bullet Speed: 19.400000000000002:
 +
Escape Angle: 0.4153498545281982
 +
Prediction: 0.43501759846502797
 +
 
 +
Bullet Speed: 19.5:
 +
Escape Angle: 0.4131891031631054
 +
Prediction: 0.43253095218741416
 +
 
 +
Bullet Speed: 19.6:
 +
Escape Angle: 0.41105095681634946
 +
Prediction: 0.4300741479443506
 +
 
 +
Bullet Speed: 19.700000000000003:
 +
Escape Angle: 0.40893507234372906
 +
Prediction: 0.4276466240887158
 +
 
 +
Average MEA:0.5434857572979093
 
</pre>
 
</pre>
:This function is slow because of many iterations.
+
 
;Fast [[MEA]]
+
:It is clear that the [[MEA]] prediction overshoots the real EA. Additionally, it's average Escape Angle is 0.5434857572979093 while Traditional [[MEA]] gets an average of 0.5700086432884667.
:By using WolframAlpha and Polynomial Regression, I found a function which gives very close results to the ''Brute Force MEA''.
+
:I have also calculated what would happen if I changed the retreat angle a little bit.  
 
<pre>
 
<pre>
        double x = bulletSpeed;
+
RetreatAngle = pi / 4
        double a = -3.508129323E-5;
+
Escape Angle = 0.3899271370580362
        double b = 2.460363294E-3;
+
 
        double c = -6.666318894E-2;
+
RetreatAngle = 0.1
        double d = 8.545020365E-1;
+
Escape Angle = 0.5667488043961456
        double e = -3.337830707;
 
        double angle = a * Math.pow(x, 4) + b * Math.pow(x, 3) + c * Math.pow(x, 2) + d * x + e;
 
        return Math.sin(angle) / (bulletSpeed / 8 - Math.cos(angle));
 
</pre>
 
:Here are some results.
 
{| class="wikitable"
 
! style="font-weight: bold;" | Bullet Velocity/Type
 
! style="font-weight: bold;" | Traditional MEA
 
! style="font-weight: bold;" | Perfect Orbit MEA
 
! style="font-weight: bold;" | Brute Force MEA
 
! style="font-weight: bold;" | Fast Accurate MEA
 
|-
 
| style="font-weight: bold;" | 11.0
 
| 0.8143399421265254
 
| 0.7272727272727273
 
| 1.0596258856320087
 
| 1.0596258725889567
 
|-
 
| style="font-weight: bold;" | 11.5
 
| 0.7693273435231462
 
| 0.6956521739130435
 
| 0.9683640522574986
 
| 0.968363900596335
 
|-
 
| style="font-weight: bold;" | 12.0
 
| 0.7297276562269663
 
| 0.6666666666666666
 
| 0.894427190975601
 
| 0.8944271125817973
 
|-
 
| style="font-weight: bold;" | 12.5
 
| 0.694498265626556
 
| 0.64
 
| 0.8329267300655651
 
| 0.8329267278277855
 
|-
 
| style="font-weight: bold;" | 13.0
 
| 0.6628738236501358
 
| 0.6153846153846154
 
| 0.7807200583557125
 
| 0.780720043134266
 
|-
 
| style="font-weight: bold;" | 13.5
 
| 0.634273648122496
 
| 0.5925925925925926
 
| 0.7356807837876015
 
| 0.7356807492372547
 
|-
 
| style="font-weight: bold;" | 14.0
 
| 0.6082455789102096
 
| 0.5714285714285714
 
| 0.6963106238213576
 
| 0.6963105997202048
 
|-
 
| style="font-weight: bold;" | 14.5
 
| 0.5844300733415584
 
| 0.5517241379310345
 
| 0.6615185844552328
 
| 0.6615185795887975
 
|-
 
| style="font-weight: bold;" | 15.0
 
| 0.5625362445438555
 
| 0.5333333333333333
 
| 0.6304883249909795
 
| 0.6304883242101953
 
|-
 
| style="font-weight: bold;" | 15.5
 
| 0.5423253027748484
 
| 0.5161290322580645
 
| 0.6025948617234669
 
| 0.6025948511581146
 
|-
 
| style="font-weight: bold;" | 16.0
 
| 0.5235987755982989
 
| 0.5
 
| 0.5773502691896257
 
| 0.5773502519499172
 
|-
 
| style="font-weight: bold;" | 16.5
 
| 0.5061899196266034
 
| 0.48484848484848486
 
| 0.5543671429174404
 
| 0.554367131856091
 
|-
 
| style="font-weight: bold;" | 17.0
 
| 0.4899573262537283
 
| 0.47058823529411764
 
| 0.5333333333085944
 
| 0.5333333322391546
 
|-
 
| style="font-weight: bold;" | 17.5
 
| 0.47478007356550933
 
| 0.45714285714285713
 
| 0.513994052961485
 
| 0.5139940493814433
 
|-
 
| style="font-weight: bold;" | 18.0
 
| 0.4605539916813224
 
| 0.4444444444444444
 
| 0.49613893835306566
 
| 0.4961389212446966
 
|-
 
| style="font-weight: bold;" | 18.5
 
| 0.44718874522671376
 
| 0.43243243243243246
 
| 0.47959251946407533
 
| 0.47959250502886874
 
|-
 
| style="font-weight: bold;" | 19.0
 
| 0.43460552560736715
 
| 0.42105263157894735
 
| 0.4642070825481933
 
| 0.46420708019143475
 
|-
 
| style="font-weight: bold;" | 19.5
 
| 0.42273520519034663
 
| 0.41025641025641024
 
| 0.44985724569216
 
| 0.4498570266324053
 
|}
 
  
:As you can see it gives higher results than ''Perfect orbit'' and very accurate according to the results.
+
RetreatAngle = 0.001
 +
Escape Angle = 0.5700083166139558
 +
 
 +
RetreatAngle = -0.001
 +
Escape Angle = 0.5700083166139558
 +
 
 +
RetreatAngle = -0.1
 +
Escape Angle = 0.5667488043961456
 +
 
 +
RetreatAngle = -pi / 4
 +
Escape Angle = 0.3899271370580362
 +
</pre>
  
;Pros
+
:As you can see even a little change in retreat angle can lower MEA. Additionally, since the results are symmetrically separated by PI / 2 which means that PI / 2 is the optimal value for '''linear movement'''.
*It is fast.
+
:So I tried a new Retreat Angle formula which increased its retreat angle a bit every tick. Even when I brute-forced to find the best solution Traditional MEA was better so for now, Traditional MEA seems correct except the fact that it doesn't take bot width and bullet start position's into account.
*It is accurate.
 
*You can also get the best lateral/advancing velocity because it calculates the retreat angle first.
 
  
;Cons
+
==Notes==
*Robot velocity is fixed to 8.
+
I am happy that traditional [[MEA]] is very likely to be correct since [[WhiteFang]] used my incorrect one.
*Hard to interpret or improve.
 

Latest revision as of 20:40, 12 July 2018

After doing some tests with the code below I have found out that every MEA theory I have written was wrong.

Code

package dsekercioglu.mega.mea;

import java.awt.geom.Point2D;
import java.util.ArrayList;

public class Test {

    static MEAFormula[] formulas = new MEAFormula[4];
    static final double SIM_SENSITIVITY = 50000;
    static final double DISTANCE = 500;
    static final boolean LINEAR_MOVE = false;

    public static void main(String[] args) {
        formulas[0] = new TraditionalMEA();
        formulas[1] = new TraditionalMEAPlusSomeNumber(0);
        formulas[2] = new DsekerciogluOldMEA();
        formulas[3] = new DsekerciogluTestMEA(0.01);
        for (int f = 0; f < formulas.length; f++) {
            System.out.println("=================================" + formulas[f].getName() + "=================================");
            int counter = 0;
            double averageMEA = 0;
            for (int i = 110; i <= 197; i++) {
                double bulletSpeed = i * 0.1;
                Bot b = new Bot(formulas[f].getRetreatAngle(bulletSpeed), formulas[f].getTurnPerTick(DISTANCE));
                Wave w = new Wave(bulletSpeed);
                Point2D.Double intersection;
                if (!LINEAR_MOVE) {
                    while (w.source.distance(b.location) > w.distanceTraveled) {
                        w.update();
                        b.update();
                    }
                    intersection = b.location;
                } else {
                    intersection = b.interceptWave(w);
                }
                averageMEA += (absoluteBearing(w.source, intersection) - averageMEA) / (++counter);
                System.out.println("Bullet Speed: " + bulletSpeed + ":");
                System.out.println("Escape Angle: " + absoluteBearing(w.source, intersection));
                System.out.println("Prediction: " + formulas[f].getMEA(bulletSpeed));
                System.out.println("");
            }
            System.out.println("Average MEA:" + averageMEA);
        }
    }

    public static class Wave {

        Point2D.Double source = new Point2D.Double(0, 0);//starting from the origin
        final double VELOCITY;
        double distanceTraveled;

        public Wave(double velocity) {
            this.VELOCITY = velocity;//We don't set distanceTraveled to velocity since the MEA calculations doesn't take that into account.
        }

        public void update() {
            distanceTraveled += VELOCITY / SIM_SENSITIVITY;
        }
    }

    public static class Bot {

        Point2D.Double location = new Point2D.Double(0, DISTANCE);
        final double VELOCITY = 8;
        final double TURN;
        double angle;

        public Bot(double retreatAngle, double turnPerTick) {
            angle = retreatAngle;
            TURN = turnPerTick;

        }

        public void update() {
            location = project(location, angle, VELOCITY / SIM_SENSITIVITY);
            angle += TURN / SIM_SENSITIVITY;
        }

        public Point2D.Double interceptWave(Wave w) {
            return intercept(w.source, w.VELOCITY, location, angle, VELOCITY);
        }
    }

    //CREDIT: Chase-san
    public static Point2D.Double intercept(Point2D pos, double vel, Point2D tPos, double tHeading, double tVel) {
        double tVelX = Math.sin(tHeading) * tVel;
        double tVelY = Math.cos(tHeading) * tVel;
        double relX = tPos.getX() - pos.getX();
        double relY = tPos.getY() - pos.getY();
        double b = relX * tVelX + relY * tVelY;
        double a = vel * vel - tVel * tVel;
        b = (b + Math.sqrt(b * b + a * (relX * relX + relY * relY))) / a;
        return new Point2D.Double(tVelX * b + tPos.getX(), tVelY * b + tPos.getY());
    }

    public static abstract class MEAFormula {

        public abstract double getMEA(double bulletSpeed);

        public abstract double getRetreatAngle(double bulletSpeed);

        public abstract double getTurnPerTick(double distance);

        public abstract String getName();

    }

    public static class DsekerciogluOldMEA extends MEAFormula {

        @Override
        public double getMEA(double bulletSpeed) {
            double x = bulletSpeed;
            double xx = x * x;
            double xxx = xx * x;
            double a = 4.626248824E-7;
            double b = -4.203721619E-5;
            double c = 1.571662957E-3;
            double d = -3.085855208E-2;
            double e = 3.337262571E-1;
            double f = -2.893934846E-1;
            double angle = a * xxx * xx + b * xx * xx + c * xxx + d * xx + e * x + f;
            return Math.asin(Math.sin(angle) / (bulletSpeed / 8 - Math.cos(angle) / 2));
        }

        @Override
        public double getRetreatAngle(double bulletSpeed) {
            double x = bulletSpeed;
            double xx = x * x;
            double xxx = xx * x;
            double a = 4.626248824E-7;
            double b = -4.203721619E-5;
            double c = 1.571662957E-3;
            double d = -3.085855208E-2;
            double e = 3.337262571E-1;
            double f = -2.893934846E-1;
            return a * xxx * xx + b * xx * xx + c * xxx + d * xx + e * x + f;
        }

        @Override
        public double getTurnPerTick(double distance) {
            return 0;
        }

        @Override
        public String getName() {
            return "Dsekercioglu's Old MEA";
        }

    }

    public static class TraditionalMEA extends MEAFormula {

        @Override
        public double getMEA(double bulletSpeed) {
            return Math.asin(8 / bulletSpeed);
        }

        @Override
        public double getRetreatAngle(double bulletSpeed) {
            return Math.PI / 2;
        }

        @Override
        public double getTurnPerTick(double distance) {
            return 0;
        }

        @Override
        public String getName() {
            return "Traditional MEA";
        }

    }

    public static class TraditionalMEAPlusSomeNumber extends MEAFormula {

        private final double EXTRA;

        public TraditionalMEAPlusSomeNumber(double extra) {
            EXTRA = extra;
        }

        @Override
        public double getMEA(double bulletSpeed) {
            return Math.asin(8 / bulletSpeed);
        }

        @Override
        public double getRetreatAngle(double bulletSpeed) {
            return Math.PI / 2 + EXTRA;
        }

        @Override
        public double getTurnPerTick(double distance) {
            return 0;
        }

        @Override
        public String getName() {
            return "Traditional MEA Plus " + EXTRA;
        }

    }

    public static class DsekerciogluTestMEA extends MEAFormula {
        
        private final double RETREAT_FACTOR;
        
        public DsekerciogluTestMEA(double retreatFactor) {
            RETREAT_FACTOR = retreatFactor;
        }

        @Override
        public double getMEA(double bulletSpeed) {
            return 0;
        }

        @Override
        public double getRetreatAngle(double bulletSpeed) {
            return Math.PI / 2;
        }

        @Override
        public double getTurnPerTick(double distance) {
            return RETREAT_FACTOR / distance;
        }

        @Override
        public String getName() {
            return "Dsekercioglu Test MEA";
        }

    }

    public static Point2D.Double project(Point2D.Double source, double angle, double distance) {
        return new Point2D.Double(source.x + Math.sin(angle) * distance, source.y + Math.cos(angle) * distance);
    }

    public static double absoluteBearing(Point2D.Double p1, Point2D.Double p2) {
        return Math.atan2(p2.x - p1.x, p2.y - p1.y);
    }
}


Test Results

My Old MEA
Bullet Speed: 11.0:
Escape Angle: 0.7443390319356681
Prediction: 0.8958173020565081

Bullet Speed: 11.100000000000001:
Escape Angle: 0.7373080257129179
Prediction: 0.8829756036277365

Bullet Speed: 11.200000000000001:
Escape Angle: 0.7304125890046199
Prediction: 0.8706053037227797

Bullet Speed: 11.3:
Escape Angle: 0.7236486178072312
Prediction: 0.8586747798058824

Bullet Speed: 11.4:
Escape Angle: 0.7170121910884176
Prediction: 0.8471556332457875

Bullet Speed: 11.5:
Escape Angle: 0.7104995591301005
Prediction: 0.8360222462765713

Bullet Speed: 11.600000000000001:
Escape Angle: 0.7041071328615146
Prediction: 0.8252514148545027

Bullet Speed: 11.700000000000001:
Escape Angle: 0.6978314740784414
Prediction: 0.8148220420131798

Bullet Speed: 11.8:
Escape Angle: 0.6916692864575538
Prediction: 0.8047148798932051

Bullet Speed: 11.9:
Escape Angle: 0.685617407285771
Prediction: 0.7949123112702848

Bullet Speed: 12.0:
Escape Angle: 0.6796727998340208
Prediction: 0.7853981633902923

Bullet Speed: 12.100000000000001:
Escape Angle: 0.6738325463130002
Prediction: 0.7761575484239104

Bullet Speed: 12.200000000000001:
Escape Angle: 0.668093841355649
Prediction: 0.7671767260049279

Bullet Speed: 12.3:
Escape Angle: 0.6624539859772478
Prediction: 0.7584429842061166

Bullet Speed: 12.4:
Escape Angle: 0.6569103819694577
Prediction: 0.7499445360003807

Bullet Speed: 12.5:
Escape Angle: 0.6514605266893417
Prediction: 0.74167042880019

Bullet Speed: 12.600000000000001:
Escape Angle: 0.646102008208559
Prediction: 0.7336104651002772

Bullet Speed: 12.700000000000001:
Escape Angle: 0.6408325007915578
Prediction: 0.7257551325932152

Bullet Speed: 12.8:
Escape Angle: 0.6356497606747965
Prediction: 0.7180955424043315

Bullet Speed: 12.9:
Escape Angle: 0.6305516221218561
Prediction: 0.7106233743162302

Bullet Speed: 13.0:
Escape Angle: 0.6255359937317999
Prediction: 0.7033308280352042

Bullet Speed: 13.100000000000001:
Escape Angle: 0.620600854980369
Prediction: 0.6962105797007199

Bullet Speed: 13.200000000000001:
Escape Angle: 0.6157442529755357
Prediction: 0.6892557429615973

Bullet Speed: 13.3:
Escape Angle: 0.6109642994107284
Prediction: 0.682459834043714

Bullet Speed: 13.4:
Escape Angle: 0.6062591677005588
Prediction: 0.6758167403181464

Bullet Speed: 13.5:
Escape Angle: 0.601627090285309
Prediction: 0.669320691948796

Bullet Speed: 13.600000000000001:
Escape Angle: 0.5970663560916503
Prediction: 0.6629662362573612

Bullet Speed: 13.700000000000001:
Escape Angle: 0.5925753081382007
Prediction: 0.6567482144929919

Bullet Speed: 13.8:
Escape Angle: 0.5881523412755126
Prediction: 0.6506617407357893

Bullet Speed: 13.9:
Escape Angle: 0.5837959000509967
Prediction: 0.6447021826987749

Bullet Speed: 14.0:
Escape Angle: 0.5795044766900752
Prediction: 0.638865144223163

Bullet Speed: 14.100000000000001:
Escape Angle: 0.575276609185606
Prediction: 0.6331464492875558

Bullet Speed: 14.200000000000001:
Escape Angle: 0.5711108794882658
Prediction: 0.6275421273738028

Bullet Speed: 14.3:
Escape Angle: 0.5670059117911797
Prediction: 0.6220484000512764

Bullet Speed: 14.4:
Escape Angle: 0.562960370902617
Prediction: 0.6166616686577209

Bullet Speed: 14.5:
Escape Angle: 0.5589729607010712
Prediction: 0.6113785029690175

Bullet Speed: 14.600000000000001:
Escape Angle: 0.5550424226674765
Prediction: 0.6061956307625184

Bullet Speed: 14.700000000000001:
Escape Angle: 0.5511675344897213
Prediction: 0.6011099281893126

Bullet Speed: 14.8:
Escape Angle: 0.5473471087349788
Prediction: 0.5961184108801252

Bullet Speed: 14.9:
Escape Angle: 0.5435799915857266
Prediction: 0.5912182257177159

Bullet Speed: 15.0:
Escape Angle: 0.5398650616356022
Prediction: 0.5864066432158043

Bullet Speed: 15.100000000000001:
Escape Angle: 0.5362012287415584
Prediction: 0.5816810504508354

Bullet Speed: 15.200000000000001:
Escape Angle: 0.532587432929
Prediction: 0.5770389444984385

Bullet Speed: 15.3:
Escape Angle: 0.5290226433468467
Prediction: 0.5724779263313178

Bullet Speed: 15.4:
Escape Angle: 0.5255058572696637
Prediction: 0.5679956951396367

Bullet Speed: 15.5:
Escape Angle: 0.5220360991442051
Prediction: 0.5635900430387886

Bullet Speed: 15.600000000000001:
Escape Angle: 0.5186124196778965
Prediction: 0.559258850132841

Bullet Speed: 15.700000000000001:
Escape Angle: 0.5152338949669462
Prediction: 0.555000079904977

Bullet Speed: 15.8:
Escape Angle: 0.511899625661932
Prediction: 0.5508117749089398

Bullet Speed: 15.9:
Escape Angle: 0.5086087361688503
Prediction: 0.5466920527379062

Bullet Speed: 16.0:
Escape Angle: 0.5053603738837394
Prediction: 0.5426391022493595

Bullet Speed: 16.1:
Escape Angle: 0.5021537084591243
Prediction: 0.5386511800264655

Bullet Speed: 16.2:
Escape Angle: 0.4989879311006239
Prediction: 0.5347266070581833

Bullet Speed: 16.3:
Escape Angle: 0.4958622538921788
Prediction: 0.5308637656219011

Bullet Speed: 16.400000000000002:
Escape Angle: 0.49277590914844127
Prediction: 0.5270610963537865

Bullet Speed: 16.5:
Escape Angle: 0.48972814879298004
Prediction: 0.5233170954933015

Bullet Speed: 16.6:
Escape Angle: 0.4867182437609991
Prediction: 0.519630312289474

Bullet Speed: 16.7:
Escape Angle: 0.48374548342538626
Prediction: 0.5159993465575505

Bullet Speed: 16.8:
Escape Angle: 0.48080917504494824
Prediction: 0.5124228463755808

Bullet Speed: 16.900000000000002:
Escape Angle: 0.477908643233771
Prediction: 0.5088995059113369

Bullet Speed: 17.0:
Escape Angle: 0.4750432294507034
Prediction: 0.5054280633707354

Bullet Speed: 17.1:
Escape Angle: 0.47221229150801264
Prediction: 0.5020072990596257

Bullet Speed: 17.2:
Escape Angle: 0.46941520309832563
Prediction: 0.49863603355144803

Bullet Speed: 17.3:
Escape Angle: 0.466651353339011
Prediction: 0.4953131259538367

Bullet Speed: 17.400000000000002:
Escape Angle: 0.4639201463332056
Prediction: 0.49203747226777644

Bullet Speed: 17.5:
Escape Angle: 0.46122100074673794
Prediction: 0.48880800383339884

Bullet Speed: 17.6:
Escape Angle: 0.4585533494002351
Prediction: 0.4856236858569444

Bullet Speed: 17.7:
Escape Angle: 0.4559166388757421
Prediction: 0.48248351601382566

Bullet Speed: 17.8:
Escape Angle: 0.4533103291372156
Prediction: 0.479386523123083

Bullet Speed: 17.900000000000002:
Escape Angle: 0.45073389316429485
Prediction: 0.47633176588887804

Bullet Speed: 18.0:
Escape Angle: 0.4481868165987693
Prediction: 0.4733183317049672

Bullet Speed: 18.1:
Escape Angle: 0.44566859740320997
Prediction: 0.4703453355183887

Bullet Speed: 18.2:
Escape Angle: 0.4431787455312451
Prediction: 0.4674119187488613

Bullet Speed: 18.3:
Escape Angle: 0.44071678260898817
Prediction: 0.4645172482606248

Bullet Speed: 18.400000000000002:
Escape Angle: 0.43828224162716545
Prediction: 0.46166051538368624

Bullet Speed: 18.5:
Escape Angle: 0.4358746666434845
Prediction: 0.4588409349816298

Bullet Speed: 18.6:
Escape Angle: 0.4334936124948371
Prediction: 0.45605774456334336

Bullet Speed: 18.7:
Escape Angle: 0.43113864451892525
Prediction: 0.45331020343618766

Bullet Speed: 18.8:
Escape Angle: 0.4288093382849335
Prediction: 0.4505975918982937

Bullet Speed: 18.900000000000002:
Escape Angle: 0.42650527933288
Prediction: 0.4479192104678227

Bullet Speed: 19.0:
Escape Angle: 0.4242260629212929
Prediction: 0.44527437914716245

Bullet Speed: 19.1:
Escape Angle: 0.42197129378288556
Prediction: 0.44266243672015787

Bullet Speed: 19.200000000000003:
Escape Angle: 0.4197405858879035
Prediction: 0.44008274008059534

Bullet Speed: 19.3:
Escape Angle: 0.4175335622148354
Prediction: 0.4375346635902649

Bullet Speed: 19.400000000000002:
Escape Angle: 0.4153498545281982
Prediction: 0.43501759846502797

Bullet Speed: 19.5:
Escape Angle: 0.4131891031631054
Prediction: 0.43253095218741416

Bullet Speed: 19.6:
Escape Angle: 0.41105095681634946
Prediction: 0.4300741479443506

Bullet Speed: 19.700000000000003:
Escape Angle: 0.40893507234372906
Prediction: 0.4276466240887158

Average MEA:0.5434857572979093
It is clear that the MEA prediction overshoots the real EA. Additionally, it's average Escape Angle is 0.5434857572979093 while Traditional MEA gets an average of 0.5700086432884667.
I have also calculated what would happen if I changed the retreat angle a little bit.
RetreatAngle = pi / 4
Escape Angle = 0.3899271370580362

RetreatAngle = 0.1
Escape Angle = 0.5667488043961456

RetreatAngle = 0.001
Escape Angle = 0.5700083166139558

RetreatAngle = -0.001
Escape Angle = 0.5700083166139558

RetreatAngle = -0.1
Escape Angle = 0.5667488043961456

RetreatAngle = -pi / 4
Escape Angle = 0.3899271370580362
As you can see even a little change in retreat angle can lower MEA. Additionally, since the results are symmetrically separated by PI / 2 which means that PI / 2 is the optimal value for linear movement.
So I tried a new Retreat Angle formula which increased its retreat angle a bit every tick. Even when I brute-forced to find the best solution Traditional MEA was better so for now, Traditional MEA seems correct except the fact that it doesn't take bot width and bullet start position's into account.

Notes

I am happy that traditional MEA is very likely to be correct since WhiteFang used my incorrect one.