Ejemplo n.º 1
0
        public virtual CircleCastHit CircleCastHandle(CircleCast cast)
        {
            // Already collided at origin position
            if (pos.distTo(cast.origin) < cast.r)
            {
                return(new CircleCastHit
                       (
                           isHit: true, isOriginHit: true,
                           originCirclePos: cast.origin, hitCirclePos: cast.origin, contactPos: pos
                       ));
            }
            // Detect
            var castLine = cast.GetLineBase();

            if (castLine.FootOnThis(pos))
            {
                var dist = castLine.DistToPoint(pos);
                if (dist <= cast.r)
                {
                    var distContactFoot   = Math.Sqrt(cast.r * cast.r - dist * dist);
                    var foot1             = castLine.FootPoint(pos);
                    var distOriginFoot    = (foot1 - cast.origin) * cast.dir;
                    var distOriginContact = distOriginFoot - distContactFoot;
                    var hit = cast.origin + cast.dir * distOriginContact;
                    return(new CircleCastHit
                           (
                               isHit: true, isOriginHit: false, originCirclePos: cast.origin,
                               hitCirclePos: hit, contactPos: pos
                           ));
                }
            }

            // No Collision
            return(CircleCastHit.NotHit(cast.origin));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Scan one wall.
        /// </summary>
        private ScanResult _ScanWall(Wall wall, double[] rads)
        {
            ScanResult res    = ScanResult.init(rads, range + 1);
            var        egopos = ego.pos;

            var castTry = new CircleCast(egopos, 0, margin);
            var hitTry  = castTry.CastTo(wall);

            // currently in collision
            if (hitTry.isOriginHit)
            {
                res.isCollision = true;

                var dist2wall   = wall.DistToPoint_TruncatedByEnds(egopos);
                var colSeverity = Max(0, margin + wall.margin - dist2wall) / margin;

                for (int i = 0; i < rads.Length; ++i)
                {
                    var rad          = rads[i];
                    var repulsionDir = wall.RepulsionDirToPoint(egopos);

                    if (useSafety)
                    {
                        res.safety[i] = Cos(AbsRad(rads[i] - repulsionDir.rad)) * (1 + colSeverity);
                    }
                    else
                    {
                        var dist = Max(0.1, Vector.fromRadMag(rad, 1) * repulsionDir * 100);
                        res.dists[i] = dist;
                    }
                }
            }
            // not in collision
            else
            {
                for (int i = 0; i < rads.Length; ++i)
                {
                    var rad  = rads[i];
                    var cast = new CircleCast(egopos, rad, margin);
                    var hit  = cast.CastTo(wall);

                    // No hit
                    if (!hit.isHit)
                    {
                        continue;
                    }

                    // Hit
                    var dist = hit.dist;
                    if (dist < res.dists[i])
                    {
                        res.dists[i] = dist;
                    }
                }
            }

            return(res);
        }
Ejemplo n.º 3
0
        public virtual CircleCastHit CircleCastHandle(CircleCast cast)
        {
            var hit_between = CircleCastHandle_ExceptEnds(cast);

            if (hit_between.isHit)
            {
                return(hit_between);
            }

            var hit_ends = CircleCastHandle_Ends(cast);

            return(hit_ends);
        }
Ejemplo n.º 4
0
        protected CircleCastHit CircleCastHandle_Ends(CircleCast cast)
        {
            Point p1   = new Point(point1);
            Point p2   = new Point(point2);
            var   hit1 = p1.CircleCastHandle(cast);
            var   hit2 = p2.CircleCastHandle(cast);

            if (hit1.EarlierThan(hit2))
            {
                return(hit1);
            }
            return(hit2);
        }
Ejemplo n.º 5
0
        // public Wall(double a, double b, double c, double margin=0) : base(a, b, c){
        //     this.margin = margin;
        // }

        public override CircleCastHit CircleCastHandle(CircleCast cast)
        {
            CircleCast surrCast = new CircleCast(cast.origin, cast.rad, cast.r + margin);

            var hit = base.CircleCastHandle(surrCast);

            if (!hit.isHit)
            {
                return(hit);
            }

            var contactVec = hit.contactPos - hit.hitCirclePos;
            var contact    = (contactVec.mag - margin) * contactVec.unit + hit.hitCirclePos;

            return(new CircleCastHit(
                       isHit: true, isOriginHit: hit.isOriginHit,
                       originCirclePos: cast.origin,
                       hitCirclePos: hit.hitCirclePos,
                       contactPos: contact
                       ));
        }
Ejemplo n.º 6
0
        protected CircleCastHit CircleCastHandle_ExceptEnds(CircleCast cast)
        {
            if (this.DistToPoint(cast.origin) < cast.r)
            {
                // Already collided at origin position
                if (this.FootOnThis(cast.origin))
                {
                    return(new CircleCastHit
                           (
                               isHit: true, isOriginHit: true, originCirclePos: cast.origin,
                               hitCirclePos: cast.origin, contactPos: FootPoint(cast.origin)
                           ));
                }
                // Except Collide Inside out
                else
                {
                    return(CircleCastHit.NotHit(cast.origin));
                }
            }

            // Detect collision between ends
            var marginLine = this.MovedAlongNormToPointSide(cast.origin, cast.r);
            var castLine   = cast.GetLineBase();
            var sec        = castLine.Intersect(marginLine);

            if (!sec.isNull)
            {
                return(new CircleCastHit
                       (
                           isHit: true, isOriginHit: false, originCirclePos: cast.origin,
                           hitCirclePos: sec, contactPos: FootPoint(sec)
                       ));
            }
            // No Collision
            return(CircleCastHit.NotHit(cast.origin));
        }