Ejemplo n.º 1
0
        public void PointOfAngleTest()
        {
            var zero = new Position(0, 0, null, null);
            var p = zero.PointOfAngle(Molecule.TETRAHEDRON_SITE, Math.PI * 5 / 6);
            Assert.Less(p.X, zero.X);

            Assert.AreEqual(2, p.TetrahedronPart(zero));
        }
Ejemplo n.º 2
0
        public void BoundPositionTest(Molecule molecule, int boundNr, double xExp, double yExp)
        {
            var poz = molecule.BoundPosition(boundNr);

            var poz_expected = new Position(xExp, yExp);

            AssertExtensions.AreAlmostEqual(poz_expected, poz);
        }
Ejemplo n.º 3
0
 /// <summary>
 ///    Circle equation: 
 ///    x = s.X + r*cos(t)
 ///    y = s.Y + r*sin(t)
 ///    Segment equation:
 ///    x = p1.X + k*(p2.X-p1.X) 
 ///    y = p1.Y + k*(p2.Y-p1.Y)
 ///    where k in [0, 1], t in [0, 360)
 ///    =>
 ///    t = acos((x - s.X)/r OR t = asin((y - s.Y)/r
 ///    k = (x - p1.X)/(p2.X-p1.X) OR k = (y - p1.Y)/(p2.Y-p1.Y) 
 /// </summary>
 public static List<Position> CircleAndSegmentIntersections(Position p1, Position p2, double r, Position s, bool includeEnds)
 {
     List<Position> ret = new List<Position>();
     if (p1.X != p2.X)
     {
         /*
          y = ax + b
         (s.x - x)^2 + (s.y - y)^2 = r^2
         =>
         (s.x-x)^2 + (s.y - b - ax) ^2 = r^2
         =>
         (1 + a^2)x^2- 2[(s.y-b)a + s.x] x + s.x^2 + (s.y-b)^2 - r^2   = 0
         */
         double a = (p2.Y - p1.Y) / (p2.X - p1.X);
         double b = p1.Y - a * p1.X;
         double[] xs = SolveQuadraticalEquation(
             1 + a * a,
             -2 * ((s.Y - b) * a + s.X),
             s.X * s.X + (s.Y - b) * (s.Y - b) - r * r
         );
         foreach (double x in xs)
         {
             double k = (x - p1.X) / (p2.X - p1.X);
             if (includeEnds && 0 <= k && k <= 1 || !includeEnds && 0 < k && k < 1)
             {
                 ret.Add(new Position(x, a * x + b));
             }
         }
     }
     else
     {
         /*
         x = a
         (s.x - x)^2 + (s.y - y)^2 = r^2
         =>
         (s.X - a)^2 + (s.Y - y)^2 = r^2
         =>
         y^2 + -2*s.Y*y + s.Y^2 + (s.X - a)^2 - r^2 = 0
          */
         double a = p1.X;
         double[] ys = SolveQuadraticalEquation(
             1,
             -2 * s.Y,
             s.Y * s.Y + (s.X - a) * (s.X - a) - r * r
         );
         foreach (double y in ys)
         {
             double k = (y - p1.Y) / (p2.Y - p1.Y);
             if (includeEnds && 0 <= k && k <= 1 || !includeEnds && 0 < k && k < 1)
             {
                 ret.Add(new Position(a, y));
             }
         }
     }
     return ret;
 }
Ejemplo n.º 4
0
        public void TetrahedronPartTest()
        {
            Position zero = new Position(3.45, 7.93, null, null);
            Position p = new Position(3.45, 10, null, null);

            Assert.AreEqual(1, p.TetrahedronPart(zero));

            p.X = -100;
            p.Y = 8;

            Assert.AreEqual(2, p.TetrahedronPart(zero));

            p.X = 100;
            p.Y = 1;

            Assert.AreEqual(5, p.TetrahedronPart(zero));
        }
Ejemplo n.º 5
0
        public void PointOnBorderOfTetrahedronPartTest()
        {
            Position zero = new Position(3.45, 7.93, null, null);

            Double r = 10;

            var p = zero.PointOnBorderOfTetrahedronPart(r, 3);

            var p_expected = new Position(zero.X - r, zero.Y, null, null);

            AssertExtensions.AreAlmostEqual(p_expected, p);

            p = zero.PointOnBorderOfTetrahedronPart(r, 5);

            p_expected = new Position(zero.X + r / 2, zero.Y - r * Math.Sqrt(3) / 2, null, null);

            AssertExtensions.AreAlmostEqual(p_expected, p);
        }
Ejemplo n.º 6
0
        public void CircleAndSegmentIntersectionsTest()
        {
            var positions = Intersections.CircleAndSegmentIntersections(new Position(6, 6), new Position(6, 20), 10, new Position(0, 0), false);

            var pExp = new Position(6, 8);

            AssertExtensions.AreAlmostEqual(pExp, positions[0]);

            positions = Intersections.CircleAndSegmentIntersections(new Position(0, -8), new Position(12, -8), 10, new Position(0, 0), false);

            pExp = new Position(6, -8);

            AssertExtensions.AreAlmostEqual(pExp, positions[0]);

            positions = Intersections.CircleAndSegmentIntersections(new Position(0, -7.8), new Position(12, -8.2), 10, new Position(0, 0), false);

            pExp = new Position(6, -8);

            AssertExtensions.AreAlmostEqual(pExp, positions[0]);
        }
Ejemplo n.º 7
0
        public static void DoElasticCollisionOfTwoBalls(double mass1, Position b1, double mass2, Position b2)
        {
            // Avoid division by zero below in computing new normal velocities
            // Doing a collision where both balls have no mass makes no sense anyway
            if (mass1 <= 0.0 || mass2 <= 0.0) return;

            // Compute unit normal and unit tangent vectors
            V v_n = b2 - b1; // v_n = normal vec. - a vector normal to the collision surface
            V v_un = v_n.UnitVector(); // unit normal vector
            V v_ut = new V(-v_un.Y, v_un.X); // unit tangent vector

            // Compute scalar projections of velocities onto v_un and v_ut
            double v1n = v_un * b1.Direction; // Dot product
            double v1t = v_ut * b1.Direction;
            double v2n = v_un * b2.Direction;
            double v2t = v_ut * b2.Direction;

            // Compute new tangential velocities
            double v1tPrime = v1t; // Note: in reality, the tangential velocities do not change after the collision
            double v2tPrime = v2t;

            // Compute new normal velocities using one-dimensional elastic collision equations in the normal direction
            // Division by zero avoided. See early return above.
            double v1nPrime = (v1n * (mass1 - mass2) + 2.0 * mass2 * v2n) / (mass1 + mass2);
            double v2nPrime = (v2n * (mass2 - mass1) + 2.0 * mass1 * v1n) / (mass1 + mass2);

            // Compute new normal and tangential velocity vectors
            V v_v1nPrime = v1nPrime * v_un; // Multiplication by a scalar
            V v_v1tPrime = v1tPrime * v_ut;
            V v_v2nPrime = v2nPrime * v_un;
            V v_v2tPrime = v2tPrime * v_ut;

            // Set new velocities in x and y coordinates
            b1.Direction.X = v_v1nPrime.X + v_v1tPrime.X;
            b1.Direction.Y = v_v1nPrime.Y + v_v1tPrime.Y;
            b2.Direction.X = v_v2nPrime.X + v_v2tPrime.X;
            b2.Direction.Y = v_v2nPrime.Y + v_v2tPrime.Y;
        }
Ejemplo n.º 8
0
 public void Init(Habitat habitat, InitMoleculeType type)
 {
     this.habitat = habitat;
     if (type == InitMoleculeType.Center)
     {
         Position = new Position(0, 0, new V(0, 0), this);
         AttachedIteration = 0;
     }
     else
     {
         Position = Position.NextRandomPosition(
             habitat.CondensationCenter.Position.X,
             habitat.CondensationCenter.Position.Y,
             habitat.Radius,
             this.DefaultSpeed,
             this,
             type == InitMoleculeType.Additional);
     }
 }
Ejemplo n.º 9
0
 public static void AreAlmostEqual(Position expected, Position actual)
 {
     AssertExtensions.AreAlmostEqual(expected.X, actual.X, "X");
     AssertExtensions.AreAlmostEqual(expected.Y, actual.Y, "Y");
 }
Ejemplo n.º 10
0
 /// <summary>
 /// Pod  jakim jest kątem do dodaniej osi OX
 /// </summary>
 /// <param name="zero">Początek układu współrzędnych</param>
 /// <returns></returns>
 public double Angle(Position zero)
 {
     double angle;
     double x_rel = X - zero.X;
     double y_rel = Y - zero.Y;
     if (x_rel == 0)
         angle = y_rel > 0 ? Math.PI / 2 : 3 * Math.PI / 2;
     else
     {
         switch (Quadrant(zero))
         {
             case 1: angle = Math.Atan(y_rel / x_rel);
                 break;
             case 4: angle = Math.Atan(y_rel / x_rel) + 2 * Math.PI;
                 break;
             default: angle = Math.Atan(y_rel / x_rel) + Math.PI;
                 break;
         }
     }
     angle = (angle + 2 * Math.PI) % (Math.PI * 2);
     return angle;
 }
Ejemplo n.º 11
0
 /// <summary>
 /// Do której szóstki układu współrzędych należy punkt numerowane 0 - 5
 /// </summary>
 /// <param name="zero">Początek układu współrzędnych</param>
 /// <returns></returns>
 public int TetrahedronPart(Position zero)
 {
     double angle = Angle(zero);
     return (int)(angle / (Math.PI / 3));
 }
Ejemplo n.º 12
0
 /// <summary>
 /// Do której ćwiartki układu współrzędych należy punkt numerowane 1 - 4
 /// </summary>
 /// <param name="zero">Początek układu współrzędnych</param>
 /// <returns></returns>
 public int Quadrant(Position zero)
 {
     if (X - zero.X >= 0)
         if (Y - zero.Y >= 0)
             return 1;
         else
             return 4;
     else
         if (Y - zero.Y >= 0)
             return 2;
         else
             return 3;
 }
Ejemplo n.º 13
0
 public void BumpWalls()
 {
     V d = new V(Direction.X, Direction.Y);
     Position expectedPosition = new Position(this.X + Direction.X, this.Y + Direction.Y);
     while (d.Speed > 0)
     {
         List<Position> crossing = Intersections.CircleAndSegmentIntersections(this, expectedPosition, HabitatRadius, HabitatCondensationCenter.Position, false);
         if (crossing.Count == 0)
             break;
         Position crossPosition = crossing.First<Position>();
         double alpha = (4 * Math.PI / 9) * random.NextDouble() - (2 * Math.PI / 9);
         double angle = HabitatCondensationCenter.Position.Angle(crossPosition);
         double dMoved = (crossPosition - this).Speed;
         expectedPosition = crossPosition.PointOfAngle(dMoved, angle + alpha);
         this.X = crossPosition.X;
         this.Y = crossPosition.Y;
         double oldSpeed = Direction.Speed;
         Direction = expectedPosition - crossPosition;
         Direction.Speed = oldSpeed;
         d.Speed -= dMoved;
     }
     Direction.Speed = EvaluateSpeed();
     this.X = expectedPosition.X;
     this.Y = expectedPosition.Y;
 }