Exemplo n.º 1
0
        // move to social comparison state if can and should. Return true if can and should and move, else return false
        public bool moveToSocialComparisonStateInStructureIfShould(clsGroundAtom refGroundAtom)
        {
            double socialComparisonProbability = Util.random.NextDouble();

            // draw probabilistically whether to compare or not
            if (socialComparisonProbability <= refGroundAtom.getSocialComparisonProbability())
            {
                // do social comparison
                clsGroundAtom mostSimilar = SocialComparison.findMostSimilarInStructure(refGroundAtom, Structure);

                // check if there is someone similar to me
                if (mostSimilar != null)
                {
                    refGroundAtom.ChangeState(new SOCIAL_COMPARISON_IN_STRUCTURE_STATE(Structure, mostSimilar));
                    return(true);
                }

                // if couldn't find someone similar in vicinity do not compare
            }

            return(false);
        }
Exemplo n.º 2
0
        private void MoveInStructure(clsGroundAtom refGroundAtom, int DeltaTime)
        {
            double DeltaTimeSec = DeltaTime * 0.001;
            double dist         = refGroundAtom.currentSpeed * DeltaTimeSec / 3600;

            double oldX = refGroundAtom.curr_X;
            double oldY = refGroundAtom.curr_Y;

            // YD - fixed bug where atoms in building travel way to fast than they should be.
            // Details: In the third line below addition of distance in meters to position in coordinates!
            //TerrainService.Vector vt = targetPosition - refGroundAtom.currPosition;
            //vt.normalize();
            //TerrainService.Vector NewPosition = refGroundAtom.currPosition + (vt * dist);
            ////.........

            TerrainService.Vector vt = targetPosition - refGroundAtom.currPosition;
            double targetDist        = TerrainService.MathEngine.CalcDistance(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, targetPosition.x, targetPosition.y);
            double targetAzimuth     = Util.Azimuth2Points(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, targetPosition.x, targetPosition.y);

            TerrainService.Vector NewPosition = new TerrainService.Vector();
            TerrainService.MathEngine.CalcProjectedLocationNew(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, targetAzimuth, 1000 * dist, out NewPosition.x, out NewPosition.y);
            // ----------------------------------------------------------------------------------------

            // check if in collision
            clsGroundAtom collidingAtom = null;

            manageCollisions(refGroundAtom, NewPosition, out collidingAtom);

            TerrainService.GeometryHelper.Edge CrossedEdge = new TerrainService.GeometryHelper.Edge();
            TerrainService.shPoint[]           Pnts        = Structure.Points.ToArray();
            // step aside in case of collision
            if (!refGroundAtom.isCollision)
            {
                // draw avoidance side randomly to when collision will occur
                int random = Util.random.Next(2) * 2 - 1;
                refGroundAtom.Offset_Azimuth = 90 * random;
            }
            if (refGroundAtom.isCollision)
            {
                // choose side to step to according to social comparison theory
                clsGroundAtom mostSimilar = SocialComparison.findMostSimilarInStructure(refGroundAtom, Structure);

                if (mostSimilar != null)
                {
                    TerrainService.Vector headingVector = new TerrainService.Vector();
                    headingVector.x = targetPosition.x - refGroundAtom.curr_X;
                    headingVector.y = targetPosition.y - refGroundAtom.curr_Y;
                    TerrainService.Vector vectorToMostSimilar = new TerrainService.Vector();
                    vectorToMostSimilar.x = mostSimilar.curr_X - refGroundAtom.curr_X;
                    vectorToMostSimilar.y = mostSimilar.curr_Y - refGroundAtom.curr_Y;
                    bool mostSimilarIsToTheLeft = (headingVector ^ vectorToMostSimilar).norm() > 0;
                    if (mostSimilarIsToTheLeft)
                    {
                        refGroundAtom.Offset_Azimuth = 90;
                    }
                    else
                    {
                        refGroundAtom.Offset_Azimuth = -90;
                    }
                }

                List <CollisionTime> collisions = refGroundAtom.Collisions;
                double azimuthToCollidingAtom   = Util.Azimuth2Points(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, collidingAtom.currPosition.x, collidingAtom.currPosition.y);
                TerrainService.MathEngine.CalcProjectedLocationNew(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, azimuthToCollidingAtom + refGroundAtom.Offset_Azimuth, 1000 * dist, out NewPosition.x, out NewPosition.y);
            }

            bool isCross = TerrainService.GeometryHelper.GeometryMath.isPolygonBorderCross(refGroundAtom.curr_X, refGroundAtom.curr_Y, NewPosition.x, NewPosition.y, ref Pnts, ref CrossedEdge);

            if (isCross)
            {
                CrossedEdge.rot90();
                TerrainService.Vector orig = new TerrainService.Vector(CrossedEdge.org.x, CrossedEdge.org.y, 0);
                TerrainService.Vector dest = new TerrainService.Vector(CrossedEdge.dest.x, CrossedEdge.dest.y, 0);
                TerrainService.Vector n    = dest - orig;

                n.normalize();



                TerrainService.Vector NewD = vt - 2 * (vt * n) * n;
                NewD.normalize();

                TerrainService.Vector NewDirect = NewD * 5000;


                // YD: calculate new target position according to next waypoint and not randomly
                //targetPosition = NewDirect;
                targetPosition = CalculateNextWaypointPosition(refGroundAtom);
                // ---

                // YD: Bug fix for moving too fast in buildings
                //vt = targetPosition - refGroundAtom.currPosition;
                //vt.normalize();
                //NewPosition = refGroundAtom.currPosition + (vt * dist);

                vt            = targetPosition - refGroundAtom.currPosition;
                targetDist    = TerrainService.MathEngine.CalcDistance(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, targetPosition.x, targetPosition.y) / 1000;
                targetAzimuth = Util.Azimuth2Points(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, targetPosition.x, targetPosition.y);
                TerrainService.MathEngine.CalcProjectedLocationNew(refGroundAtom.currPosition.x, refGroundAtom.currPosition.y, targetAzimuth, 1000 * dist, out NewPosition.x, out NewPosition.y);
                // ---------------------------------------------------------------------------------

                //refGroundAtom.currPosition = NewPosition;
                //refGroundAtom.curr_X = refGroundAtom.currPosition.x;
                //refGroundAtom.curr_Y = refGroundAtom.currPosition.y;

                // return;
            }


            refGroundAtom.currPosition = NewPosition;
            // YD: get current azimuth
            refGroundAtom.currentAzimuth = Util.Azimuth2Points(refGroundAtom.curr_X, refGroundAtom.curr_Y, NewPosition.x, NewPosition.y);
            refGroundAtom.curr_X         = refGroundAtom.currPosition.x;
            refGroundAtom.curr_Y         = refGroundAtom.currPosition.y;



            bool isIn = TerrainService.GeometryHelper.GeometryMath.isPointInPolygon(refGroundAtom.curr_X, refGroundAtom.curr_Y, ref Pnts);

            if (isIn == false)
            {
                System.Random Rnd = new Random();
                while (true)
                {
                    double vRnd  = Rnd.NextDouble();
                    double randX = Structure.minX + (Structure.maxX - Structure.minX) * vRnd;
                    vRnd = Rnd.NextDouble();
                    double randY     = Structure.minY + (Structure.maxY - Structure.minY) * vRnd;
                    bool   inPolygon = TerrainService.GeometryHelper.GeometryMath.isPointInPolygon(randX, randY, ref Pnts);
                    if (inPolygon == true)
                    {
                        refGroundAtom.curr_X       = randX;
                        refGroundAtom.curr_Y       = randY;
                        refGroundAtom.currPosition = new TerrainService.Vector(randX, randY, 0);
                        // YD: calculate new target position according to next waypoint and not randomly
                        //targetPosition = CalculateNextRandomPosition(5000, refGroundAtom.curr_X, refGroundAtom.curr_Y);
                        targetPosition = CalculateNextWaypointPosition(refGroundAtom);
                        // ---
                        break;
                    }
                }
            }

            // YD: since there are more than once structure, update possition according to the right structure's quadtree
            refGroundAtom.m_GameObject.getQuadTreeByStructure(Structure).PositionUpdate(refGroundAtom);
        }