/// <summary>
        /// 凸多角形の再分割処理
        /// </summary>
        public static ConvexPolygon Execute(ConvexPolygon polygon, float angleThreshold, float t = 0.5f)
        {
            //入力がnullならnullを返す
            if (polygon == null)
            {
                return(null);
            }

            //諸々のデータ構造
            List <Vector2> results  = new List <Vector2>();             //計算結果
            List <Vector2> temp     = new List <Vector2>();             //一時データ
            List <Vector2> vertices = polygon.GetVerticesCopy();

            //はじめに2点追加
            temp.Add(vertices[0]);
            temp.Add(vertices[1]);

            //巡回
            int size = vertices.Count;

            for (int i = 2; i <= size; ++i)
            {
                //順次処理
                temp.Add(vertices[i % size]);
                Process(temp, results, angleThreshold, t);                      //処理
            }
            //0番目の処理
            temp.Add(results[0]);
            Process(temp, results, angleThreshold, t);                  //処理

            return(new ConvexPolygon(results));
        }
예제 #2
0
        private static LineSegment2D?ClosestTo(Point pt, ConvexPolygon poly)
        {
            FixedPoint?   closest = null;
            LineSegment2D edge    = default;

            for (var i = 0; i < poly.NumLineSegments; i++)
            {
                var seg  = poly.GetLineSegment(i);
                var dist = CollisionDetector.DetermineClosestPoint(seg, pt);
                if (dist == null)
                {
                    continue;
                }

                if (closest == null || dist.Value.Distance < closest)
                {
                    closest = dist.Value.Distance;
                    edge    = seg;
                }
            }

            if (closest == null)
            {
                return(null);
            }

            return(edge);
        }
        /// <summary>
        /// 重み付きボロノイ図の生成
        /// </summary>
        public List <ConvexPolygon> Execute(ConvexPolygon area, List <WaitedVoronoiSite> sites)
        {
            List <ConvexPolygon> result = new List <ConvexPolygon>();

            foreach (var s1 in sites)
            {
                ConvexPolygon region = null;                    //途中計算結果格納用の領域
                foreach (var s2 in sites)
                {
                    if (s1 == s2)
                    {
                        continue;
                    }
                    //s1とs2の垂直線を重み付きで求める
                    Line line = Line.PerpendicularWaitLine(s1.Point, s1.Wait, s2.Point, s2.Wait);
                    //垂直二等分線による半平面のうち,s1を含む方を求める
                    ConvexPolygon halfPlane = halfPlaneGenerator.Execute(line, s1.Point);
                    if (region == null)
                    {
                        //初回計算時
                        region = IntersectionOperation.Execute(area, halfPlane);
                    }
                    else
                    {
                        //二回目以降
                        region = IntersectionOperation.Execute(region, halfPlane);
                    }
                }
                //最終的な計算結果をボロノイ領域とする
                result.Add(region);
            }
            return(result);
        }
        public void Update(double elapsedTime)
        {
            _selectedPolygon     = _navMesh.FindNearestPolygon(_input.Mouse.Position);
            _selectedVertexIndex = FindSelectedVertex(_input.Mouse.Position, _selectedPolygon, VertexEditRadius);

            if (_draggingVertex)
            {
                if (_input.Mouse.LeftHeld && _selectedVertexIndex != -1)
                {
                    _selectedPolygon.TryToUpdateVertPosition(_selectedVertexIndex, _input.Mouse.Position);
                    return;
                }
                else
                {
                    _draggingVertex = false;
                }
            }

            if (_input.Keyboard.IsKeyPressed(System.Windows.Forms.Keys.A))
            {
                _navMesh.AddPolygon(new ConvexPolygon(_input.Mouse.Position));
            }

            if (_input.Mouse.LeftHeld && _selectedVertexIndex != -1)
            {
                _draggingVertex = true;
            }
        }
예제 #5
0
        IDrawable run(IDrawable input)
        {
            if (!(input is PointSet))
            {
                throw new Exception("PolygonTest. Input is not PolygonTest.");
            }
            var   inp = input as PointSet;
            Point c = inp[0]; Point d = inp[1]; Point e = inp[2]; Point fe = inp[3];

            ConvexPolygon f1 = new ConvexPolygon(new Point((c.X + d.X) / 2, c.Y), new Point(d.X, (c.Y + d.Y) / 3), new Point(d.X, 2 * ((d.Y + c.Y) / 3)), new Point((c.X + d.X) / 2, d.Y), new Point(c.X, 2 * ((d.Y + c.Y) / 3)), new Point(c.X, ((d.Y + c.Y) / 3)));
            ConvexPolygon f2 = new ConvexPolygon(new Point((e.X + fe.X) / 2, e.Y), new Point(fe.X, (e.Y + fe.Y) / 3), new Point(fe.X, 2 * ((fe.Y + e.Y) / 3)), new Point((e.X + fe.X) / 2, fe.Y), new Point(e.X, 2 * ((fe.Y + e.Y) / 3)), new Point(e.X, ((fe.Y + e.Y) / 3)));
            var           x  = Intersect.GetIntersection(f1, f2);

            if (x.Count > 0)
            {
                return(new DrawableSet(new List <IDrawable>()
                {
                    new PointSet(x.ToArray()), new PolygonSet(f1, f2), DrawableElement.Text(0, 0, "Vse horosho")
                }));
            }
            else
            {
                return(new DrawableSet(new List <IDrawable>()
                {
                    new PointSet(x.ToArray()), new PolygonSet(f1, f2), DrawableElement.Text(0, 0, "Vse ploho")
                }));
            }
        }
예제 #6
0
        IDrawable run(IDrawable input)
        {
            if (!(input is PointSet))
            {
                throw new Exception("PointPolygonTest. Input is not PointPolygonTest.");
            }

            var inp = input as PointSet;

            Point a = inp[0]; Point c = inp[1]; Point d = inp[2];
            var   b = new ConvexPolygon(new Point(c.X, c.Y), new Point(d.X, c.Y), new Point(d.X, d.Y), new Point(c.X, d.Y));

            var x = Intersect.IsIntersected(a, b);

            //var x = Intersect.GetIntersection(b, a);
            if (x)
            {
                return(new DrawableSet(new List <IDrawable>()
                {
                    new PointSet(), new PolygonSet(b), DrawableElement.Text(0, 0, "Vse horosho")
                }));
            }
            else
            {
                return(new DrawableSet(new List <IDrawable>()
                {
                    new PointSet(), new PolygonSet(b), DrawableElement.Text(0, 0, "Vse ploho")
                }));
            }
            //return new PointSet(x.ToArray());
        }
예제 #7
0
    private void Update()
    {
        ConvexPolygon p1 = polygon1.Polygon;
        ConvexPolygon p2 = polygon2.Polygon;

        if (p1 == null || p2 == null)
        {
            return;
        }
        ConvexPolygon polygon = IntersectionOperation.Execute(p1, p2, lineFactory);

        //DrawLine
        if (polygon == null)
        {
            return;
        }
        List <Vector3> vertices = polygon.GetVertices3Copy();

        vertices.Add(vertices[0]);                      //末尾に先頭を追加
        if (line != null)
        {
            lineFactory.DeleteLine(line);
        }
        //line = lineFactory.CreateLine(vertices, Color.green);

        //DrawEdgeLine
        //DrawEdgeLine(p1, leftEdge);
    }
예제 #8
0
        // =====
        #region Constructors

        // Default constructor
        public RigidBody(Scene scene, ConvexPolygon shape, String material, float mass)
        {
            // Get ID
            this.id = nextID++;

            // Entry logging
      #if IS_LOGGING_METHODS
            Log.Write(String.Format("Entering method for {0}", this.Name));
      #endif

            this.scene           = scene;
            this.geometry        = shape;
            this.material        = material;
            this.mass            = mass;
            this.velocity        = Vector2.Zero;
            this.angularVelocity = 0;
            this.rotationalAxis  = this.Geometry.Centroid;
            this.momentOfInertia = this.Geometry.GetMomentAbout(this.RotationalAxis, this.Mass);
            this.contacts        = new List <Contact>();
            this.appliedImpulses = new List <Impulse>();
            this.sweep           = new Sweep(this);
            this.rank            = -1;
            this.isSleeping      = false;
            this.isTranslatable  = true;
            this.isRotatable     = true;

            // Exit logging
      #if IS_LOGGING_METHODS
            Log.Write(String.Format("Exiting method for {0}", this.Name));
      #endif
        }
예제 #9
0
        /// <summary>
        /// ボロノイ図の生成
        /// </summary>
        public List <ConvexPolygon> Execute(ConvexPolygon area, List <Vector2> sites)
        {
            List <ConvexPolygon> result = new List <ConvexPolygon>();

            foreach (Vector2 s1 in sites)
            {
                ConvexPolygon region = null;                    //途中計算結果格納用の領域
                foreach (Vector2 s2 in sites)
                {
                    if (s1 == s2)
                    {
                        continue;
                    }
                    //s1とs2の垂直二等分線を求める
                    Line line = Line.PerpendicularBisector(s1, s2);
                    //垂直二等分線による半平面のうち,s1を含む方を求める
                    ConvexPolygon halfPlane = halfPlaneGenerator.Execute(line, s1);
                    if (region == null)
                    {
                        //初回計算時
                        region = IntersectionOperation.Execute(area, halfPlane);
                    }
                    else
                    {
                        //二回目以降
                        region = IntersectionOperation.Execute(region, halfPlane);
                    }
                }
                //最終的な計算結果をボロノイ領域とする
                result.Add(region);
            }
            return(result);
        }
예제 #10
0
    /// <summary>
    /// 図の更新
    /// </summary>
    private void UpdateDiagram(List <Vector2> sites)
    {
        //ボロノイ図の作成
        areaPolygon      = ConvexPolygon.SquarePolygon(10f);
        voronoiGenerator = new VoronoiDiagramGenerator();
        regions          = voronoiGenerator.Execute(areaPolygon, sites);

        //線の削除
        for (int i = 0; i < lines.Count; ++i)
        {
            lineFactory.DeleteLine(lines[i]);
        }
        lines.Clear();

        for (int i = 0; i < regions.Count; ++i)
        {
            ConvexPolygon region = regions[i];

            //線の描画
            if (drawRegionLine)
            {
                List <Vector3> vertices = region.GetVertices3Copy();
                vertices.Add(vertices[0]);
                lines.Add(lineFactory.CreateLine(vertices));
            }

            //メッシュ
            meshes[i] = region.Scale(sites[i], 0.5f).ToMesh();            //AngleSubdivisionOperation.Execute(region, 170f).Scale(sites[i], 1f).ToMesh();

            //あたり判定の設定
            colliders[i].sharedMesh = meshes[i];
        }
    }
예제 #11
0
        /// <summary>
        /// Searches the given poly for it's vertex that is closest to the given point.
        /// </summary>
        private static Point ClosestVertexTo(Point pt, ConvexPolygon poly)
        {
            FixedPoint?minDist = null;
            Point      ret     = default;

            for (var i = 0; i < poly.NumVertices; i++)
            {
                var v    = poly.GetVertex(i);
                var diff = new Vector(v.X - pt.X, v.Y - pt.Y);
                if (diff.DeltaX * diff.DeltaX + diff.DeltaY * diff.DeltaY < 0)
                {
                    continue;
                }

                if (!diff.TryMagnitude(out var dist))
                {
                    continue;
                }

                if (minDist == null || dist < minDist)
                {
                    minDist = dist;
                    ret     = v;
                }
            }

            return(ret);
        }
예제 #12
0
    /// <summary>
    /// ボロノイ図生成コルーチン
    /// </summary>
    private IEnumerator Voronoi()
    {
        PseudoHalfPlaneGenerator halfPlaneGenerator = new PseudoHalfPlaneGenerator(100f);

        while (true)
        {
            List <Vector2>       sites   = new List <Vector2>(siteTranses.Select(elem => (Vector2)elem.position));
            List <ConvexPolygon> results = new List <ConvexPolygon>();
            List <ChainLine>     lines   = new List <ChainLine>();

            for (int i = 0; i < sites.Count; ++i)
            {
                Vector3       s1     = sites[i];
                ConvexPolygon region = null;                    //途中計算結果格納用の領域
                for (int j = 0; j < sites.Count; ++j)
                {
                    Vector3 s2 = sites[j];
                    if (i == j)
                    {
                        continue;
                    }

                    //s1とs2の垂直二等分線を求める
                    Line line = Line.PerpendicularBisector(s1, s2);
                    //垂直二等分線による半平面のうち,s1を含む方を求める
                    ConvexPolygon halfPlane = halfPlaneGenerator.Execute(line, s1);

                    if (region == null)
                    {
                        //初回計算時
                        region = IntersectionOperation.Execute(areaPolygon, halfPlane);
                    }
                    else
                    {
                        //二回目以降
                        region = IntersectionOperation.Execute(region, halfPlane);
                    }
                    Debug.Log(region + " : " + halfPlane);

                    //halfPlaneを可視化
                    List <Vector3> vertices = halfPlane.GetVertices3Copy();
                    vertices.Add(vertices[0]);                          //末尾を追加
                    ChainLine subl = lineFactory.CreateLine(vertices, subColor);

                    //regionを可視化
                    vertices = region.GetVertices3Copy();
                    vertices.Add(vertices[0]);                          //末尾を追加
                    ChainLine l = lineFactory.CreateLine(vertices, lineColor.Evaluate((float)j / sites.Count));
                    yield return(StartCoroutine(Wait()));

                    lineFactory.DeleteLine(subl);
                    lineFactory.DeleteLine(l);
                }
            }
            Debug.Log("Complete");

            yield return(StartCoroutine(Wait()));
        }
    }
예제 #13
0
        private static bool DoTheyCollide(ConvexPolygon shapeA, ConvexPolygon shapeB, Body bodyA,
                                          Body bodyB, out Vector2 impactNormal, out float penetration)
        {
            Vector2[] pointsA = shapeA.GetAdjustedPointPositions(bodyA.Position, bodyA.Rotation);
            Vector2[] pointsB = shapeB.GetAdjustedPointPositions(bodyB.Position, bodyB.Rotation);

            return(DoTheyCollide(pointsA, pointsA, out impactNormal, out penetration));
        }
예제 #14
0
 public Cell(int _i, int _j, CellGrid _grid)
 {
     i               = _i;
     j               = _j;
     grid            = _grid;
     value           = 0;
     rectangleBuffer = ConvexPolygon.Square(_grid.CellSize).GetFillBuffer();//new ColoredRectangleBuffer(X, Y, _grid.CellSize, _grid.CellSize, -1.5f);
 }
 public void SetUp()
 {
     SetPoints();
     vertices = new List <Point> {
         topLeft, bottomRight, bottomLeft, topRight
     };
     poly = new ConvexPolygon(vertices);
 }
예제 #16
0
 /// <summary>
 ///
 /// Создаёт юнит по по области его расположения
 /// </summary>
 /// <param name="polygon"></param>
 public Unit(ConvexPolygon polygon)
 {
     figures = new List <Figure> {
         polygon
     };
     Polygon       = polygon;
     unitCommander = new AutomaticCommander("");
 }
예제 #17
0
        public void Activated()
        {
            // Put the character in the center of a random polygon.
            ConvexPolygon randomPoly = _scene.NavMesh.PolygonList[_random.Next(_scene.NavMesh.PolygonList.Count)];

            _playerCharacter.SetPosition(randomPoly.CalculateCentroid());
            _playerCharacter.FaceDown();
        }
예제 #18
0
파일: Teleport.cs 프로젝트: Umqra/GameTask
 public Teleport(Point center)
     : base(Physics.Material.Adamantium, new Point(0, 0), false, null)
 {
     teleported = null;
     Activated  = false;
     Enabled    = true;
     Shape      = ConvexPolygon.Rectangle(center, Width, Height);
 }
예제 #19
0
    /// <summary>
    /// ボロノイ図生成コルーチン
    /// </summary>
    private IEnumerator Voronoi()
    {
        while (true)
        {
            List <Vector2>       sites   = new List <Vector2>(siteTranses.Select(elem => (Vector2)elem.position));
            List <ConvexPolygon> results = new List <ConvexPolygon>();
            List <ChainLine>     lines   = new List <ChainLine>();

            foreach (Vector2 s1 in sites)
            {
                ConvexPolygon region = null;                    //途中計算結果格納用の領域
                foreach (Vector2 s2 in sites)
                {
                    if (s1 == s2)
                    {
                        continue;
                    }
                    //ウェイト
                    yield return(StartCoroutine(WaitClick()));

                    //s1とs2の垂直二等分線を求める
                    Line line = Line.PerpendicularBisector(s1, s2);
                    //垂直二等分線による半平面のうち,s1を含む方を求める
                    ConvexPolygon halfPlane = halfPlaneGenerator.Execute(line, s1);

                    //線を描画
                    lines.Add(lineFactory.CreateLine(halfPlane.GetVertices3Copy()));

                    if (region == null)
                    {
                        //初回計算時
                        region = IntersectionOperation.Execute(areaPolygon, halfPlane);
                    }
                    else
                    {
                        //二回目以降
                        region = IntersectionOperation.Execute(region, halfPlane);
                    }
                }
                results.Add(region);
            }

            for (int i = 0; i < results.Count; ++i)
            {
                lines.Add(lineFactory.CreateLine(results[i].GetVertices3Copy(), Color.red));
            }
            Debug.Log("Complete");

            yield return(StartCoroutine(WaitClick()));

            for (int i = 0; i < lines.Count; ++i)
            {
                lineFactory.DeleteLine(lines[i]);
            }
            lines.Clear();
        }
    }
예제 #20
0
 /// <summary>
 /// создаёт юнит с заданными областью расположения, свойствами и указанным боевым командиром
 /// </summary>
 /// <param name="polygon">Область расположения</param>
 /// <param name="features">Свойства</param>
 /// <param name="commander">Боевой командир</param>
 public Unit(ConvexPolygon polygon, UnitFeatures features, AutomaticCommander commander)
 {
     figures = new List <Figure> {
         polygon
     };
     Polygon       = polygon;
     props         = features;
     unitCommander = commander;
 }
예제 #21
0
        /// <summary>
        /// 凸多角形の交差領域の抽出
        /// </summary>
        public static ConvexPolygon Execute(ConvexPolygon polygon1, ConvexPolygon polygon2)
        {
            //どちらかがnullならnullを返す
            if (polygon1 == null || polygon2 == null)
            {
                return(null);
            }

            //ステータスなど下準備
            Status      status    = new Status();
            List <Edge> leftEdge  = new List <Edge>();              //左側の計算結果
            List <Edge> rightEdge = new List <Edge>();              //右側の計算結果

            //一回目のイベントを処理
            StepResult result = FirstPass(polygon1, polygon2, status,
                                          leftEdge, rightEdge);

            //二回目以降のイベントを処理
            while (result.mustContinue)
            {
                //二番目以降のイベントを処
                result = SecondPass(status, leftEdge, rightEdge);
            }

            //左側と右側の計算結果を統合するリスト
            List <Edge> totalEdge = new List <Edge>();

            totalEdge.AddRange(leftEdge);
            rightEdge.Reverse();                                //反転して連結
            totalEdge.AddRange(rightEdge);

            //交差凸多角形の交点リスト
            List <Vector2> resultPoints = new List <Vector2>();
            Vector2        lastPoint    = Vector2.one * float.NaN;
            int            totalSize    = totalEdge.Count;

            for (int i = 0; i < totalSize; ++i)
            {
                Edge    e1 = totalEdge[i];
                Edge    e2 = totalEdge[(i + 1) % totalSize];
                Vector2 p  = Vector2.zero;
                if (e1.GetIntersectionPoint(e2, ref p))
                {
                    resultPoints.Add(p);
                }
            }

            //頂点が3つ以上なら凸多角形を作成
            if (resultPoints.Count >= 3)
            {
                return(new ConvexPolygon(resultPoints));
            }
            else
            {
                return(null);
            }
        }
예제 #22
0
 /// <summary>
 /// Создаёт юнит по области его расположения и заданным особенностям
 /// </summary>
 /// <param name="polygon">Область расположения</param>
 /// <param name="features">Свойства юнита</param>
 public Unit(ConvexPolygon polygon, UnitFeatures features)
 {
     figures = new List <Figure> {
         polygon
     };
     Polygon       = polygon;
     props         = features;
     unitCommander = new AutomaticCommander("", CommanderType.Common, this);
 }
예제 #23
0
    private void Update()
    {
        List <Vector2>       sites   = new List <Vector2>(siteTranses.Select(elem => (Vector2)elem.position));
        List <ConvexPolygon> results = new List <ConvexPolygon>();

        //線の削除
        if (lines.Count > 0)
        {
            for (int i = 0; i < lines.Count; ++i)
            {
                lineFactory.DeleteLine(lines[i]);
            }
            lines.Clear();
        }

        foreach (Vector2 s1 in sites)
        {
            ConvexPolygon region = null;                //途中計算結果格納用の領域
            foreach (Vector2 s2 in sites)
            {
                if (s1 == s2)
                {
                    continue;
                }
                //s1とs2の垂直二等分線を求める
                Line line = Line.PerpendicularBisector(s1, s2);
                //垂直二等分線による半平面のうち,s1を含む方を求める
                ConvexPolygon halfPlane = halfPlaneGenerator.Execute(line, s1);
                if (region == null)
                {
                    //初回計算時
                    region = IntersectionOperation.Execute(areaPolygon, halfPlane);
                }
                else
                {
                    //二回目以降
                    region = IntersectionOperation.Execute(region, halfPlane);
                }
            }
            if (region != null)
            {
                results.Add(region);
            }
            else
            {
                Debug.Log("Region is null");
            }
        }

        for (int i = 0; i < results.Count; ++i)
        {
            results[i].Scale(sites[i], 0.9f);
            List <Vector3> vertices = results[i].GetVertices3Copy();
            vertices.Add(vertices[0]);
            lines.Add(lineFactory.CreateLine(vertices, Color.green));
        }
    }
예제 #24
0
        public Area(List <object> fig)
        {
            var figs = fig.ConvertAll(x => (Figure)x);

            figures = figs;
            var points = new List <Point>();

            foreach (var figure in figs)
            {
                if (figure is Point)
                {
                    points.Add((Point)figure);
                }
                else if (figure is ConvexPolygon)
                {
                    points.AddRange(((ConvexPolygon)figure).Points);
                }
                else if (figure is Circle)
                {
                    points.Add(new Point(((Circle)figure).Center.X + ((Circle)figure).Radius, ((Circle)figure).Center.Y));
                    points.Add(new Point(((Circle)figure).Center.X, ((Circle)figure).Center.Y + ((Circle)figure).Radius));
                    points.Add(new Point(((Circle)figure).Center.X - ((Circle)figure).Radius, ((Circle)figure).Center.Y));
                    points.Add(new Point(((Circle)figure).Center.X, ((Circle)figure).Center.Y - ((Circle)figure).Radius));
                }
            }
            double minX = points[0].X, maxX = points[0].X, minY = points[0].Y, maxY = points[0].Y;

            foreach (var point in points)
            {
                if (point.X < minX)
                {
                    minX = point.X;
                }
                if (point.X > maxX)
                {
                    maxX = point.X;
                }
                if (point.Y < minY)
                {
                    minY = point.Y;
                }
                if (point.Y > maxY)
                {
                    maxY = point.Y;
                }
            }
            var listpo = new List <Point>()
            {
                new Point(minX, maxY),
                new Point(minX, minY),
                new Point(maxX, minY),
                new Point(maxX, maxY)
            };

            poly = new ConvexPolygon(listpo);
        }
예제 #25
0
 public Swarmer(float _x, float _y, Color4 _color) : base(ConvexPolygon.Regular(3, 10, (float) - Math.PI / 2), _x, _y)
 {
     instinct    = new SwarmInstinct(this);
     SpeedMax    = 60;
     Speed       = 60;
     Angle       = (float)Basics.Utils.RandomAngleRad();
     angleNext   = (float)Basics.Utils.RandomAngleRad();
     color       = _color;
     BoundingBox = new BoundingBox(20, 20);
 }
예제 #26
0
    /// <summary>
    /// スケールや再分割度の設定
    /// </summary>
    private void Evaluate(float par)
    {
        float         scale    = scaleCurve.Evaluate(par);
        int           division = (int)divisionCurve.Evaluate(par);
        float         t        = tCurve.Evaluate(par);
        ConvexPolygon p        = polygonObject.Origin.Scaled(transform.position, scale);

        //polygonObject.UpdatePolygon(AngleSubdivisionOperation.Execute(p, division));
        polygonObject.UpdatePolygon(LerpSubdivisionOperation.Execute(p, division, t));
    }
예제 #27
0
    public ConvexPolygon GetEnemyBounds()
    {
        List <Vector3> enemyLocations = new List <Vector3>();

        enemyLocations.AddRange(hiddenEnemies.Select(enemy => enemy.GetEnemyMarker().GetLocation()));
        enemyLocations.AddRange(viewableEnemies.Keys.Select(enemy => enemy.InfoGetCenterBottom()));
        List <Vector2> enemyLocations2D = enemyLocations.Select(location => new Vector2(location.x, location.z)).ToList();
        ConvexPolygon  enemyBounds      = new ConvexPolygon(enemyLocations2D);

        return(enemyBounds);
    }
예제 #28
0
 public void Update(double elapsedTime)
 {
     _selectedPolygon = _navMesh.FindNearestPolygon(_input.Mouse.Position);
     if (_input.Mouse.LeftPressed)
     {
         if (_selectedPolygon != null)
         {
             _selectedPolygon.TryToAddVertex(_input.Mouse.Position);
         }
     }
 }
예제 #29
0
        /// <summary>
        /// 凸多角形の「左側」または「右側」の上から下に向かう連結辺を作成する
        /// </summary>
        public static Edge CreateEdgeChain(ConvexPolygon polygon, bool left)
        {
            //凸多角形のy座標最小/最大値の頂点番号を取得
            int minYIndex = 0, maxYIndex = 0;

            polygon.GetYMinMaxindex(ref minYIndex, ref maxYIndex);

            //凸多角形の辺配列をを前進するか後退するかを決定
            bool ccw     = polygon.rotation == ConvexPolygon.Rotation.CCW;
            bool forward = (ccw && left) || (!ccw && !left);

            //要素の準備
            int  size      = polygon.GetEdgeCount();
            int  nextIndex = 0;
            Edge firstEdge = null;
            Edge lastEdge  = null;

            //最上点の位置から開始し,最下点に到達するまで続ける
            for (int i = maxYIndex; i != minYIndex; i = nextIndex)
            {
                Edge edge = new Edge();
                if (forward)
                {
                    //前進
                    nextIndex    = (i + 1) % size;
                    edge.segment = polygon.GetEdge(i);
                    edge.index   = i;
                }
                else
                {
                    //後退
                    nextIndex    = (i + size - 1) % size;
                    edge.segment = polygon.GetEdge(nextIndex);
                    edge.index   = nextIndex;
                }

                //辺の始点と終点
                edge.startPoint = polygon.GetVertex(i);
                edge.endPoint   = polygon.GetVertex(nextIndex);

                //辺の連結処理
                if (firstEdge == null)
                {
                    firstEdge = edge;
                }
                else
                {
                    lastEdge.next = edge;
                }
                lastEdge = edge;
            }

            return(firstEdge);
        }
예제 #30
0
        /// <summary>
        /// Метод серилизации для Полигона
        /// </summary>
        /// <param name="polygon">Полигон</param>
        /// <returns>Xml Element</returns>
        public static XElement Serialize(this ConvexPolygon polygon)
        {
            var el = new XElement("ConvexPolygon");

            var points  = polygon.Points.Select(x => x.X.ToString() + " " + x.Y.ToString()).ToList().Aggregate((x, y) => x + " " + y);
            var normals = polygon.Normals.Select(x => x.X.ToString() + " " + x.Y.ToString()).ToList().Aggregate((x, y) => x + " " + y);

            el.SetAttributeValue("Points", points);
            el.SetAttributeValue("Normals", normals);
            return(el);
        }
예제 #31
0
		public void AddExistingData( List<RecProductionFormStd> existingData )
		{
			if( existingData == null || existingData.Count == 0 )
			{
				return;
			}
			// We assume that we have cast ONLY on a singe bed on a certain day & shiff
			List<RecTMElement> elements = GetElements( existingData );
			if( elements != null && elements.Count > 0 )
			{
				ConvexPolygonList polygons = new ConvexPolygonList( elements );
				polygons.Sort(delegate(ConvexPolygon p1, ConvexPolygon p2) { return p1.MaxX.CompareTo(p2.MaxX); });
				LastExistingPolygon = polygons[polygons.Count - 1];
			}
		}
예제 #32
0
파일: Light.cs 프로젝트: mokujin/DN
        public void CastShadow(ConvexPolygon poly, Vector2 position, bool penumbra)
        {
            // get the line that blocks light for the blocker and light combination
            // move the light position towards blocker by its sourceradius to avoid
            // popping of penumbrae
            int[] edgeIndices = poly.GetBackfacingEdgeIndices((this.Position + Vector2.Multiply(Vector2.Normalize(position - this.Position), this.Size)) - position);

            Vector2[] shadowLine = new Vector2[edgeIndices.Length + 1];
            shadowLine[0] = position + poly[edgeIndices[0]];
            for (int i = 0; i < edgeIndices.Length; i++)
                shadowLine[i + 1] = position + poly.NextVertex(edgeIndices[i]);

            // if the light source is completely surrounded by the blocker, don't draw its shadow
            if (shadowLine.Length == poly.Count + 1)
                return;
            //
            // build penumbrae (soft shadows), cast from the edges
            //

            Penumbra rightpenumbra;
            {
                Vector2 startdir = extendDir(shadowLine[0] - (this.Position - getLightDisplacement(position, shadowLine[0])));
                rightpenumbra.sections = new List<Penumbra.Section>();
                rightpenumbra.sections.Add(new Penumbra.Section(shadowLine[0], startdir, 0));

                for (int i = 0; i < shadowLine.Length - 1; ++i)
                {
                    float wanted = Math.Abs(MathUtils.AngleBetween(startdir, getTotalShadowStartDirection(position, shadowLine[i])));
                    float available = Math.Abs(MathUtils.AngleBetween(startdir, shadowLine[i + 1] - shadowLine[i]));

                    if (wanted < available)
                    {
                        rightpenumbra.sections.Add(new Penumbra.Section(
                            shadowLine[i],
                            getTotalShadowStartDirection(position, shadowLine[i]),
                            1));
                        break;
                    }
                    else
                    {
                        rightpenumbra.sections.Add(new Penumbra.Section(
                            shadowLine[i + 1],
                            extendDir(shadowLine[i + 1] - shadowLine[i]),
                            available / wanted));
                    }
                }
            }

            Penumbra leftpenumbra;
            {
                Vector2 startdir = extendDir(shadowLine[shadowLine.Length - 1] - (this.Position - getLightDisplacement(position, shadowLine[shadowLine.Length - 1])));
                leftpenumbra.sections = new List<Penumbra.Section>();
                leftpenumbra.sections.Add(new Penumbra.Section(
                    shadowLine[shadowLine.Length - 1],
                    startdir,
                    0));
                for (int i = 0; i < shadowLine.Length - 1; ++i)
                {
                    float wanted = Math.Abs(MathUtils.AngleBetween(startdir, getTotalShadowStartDirection(position, shadowLine[shadowLine.Length - i - 1])));
                    float available = Math.Abs(MathUtils.AngleBetween(startdir, shadowLine[shadowLine.Length - i - 2] - shadowLine[shadowLine.Length - i - 1]));

                    if (wanted < available)
                    {
                        leftpenumbra.sections.Add(new Penumbra.Section(
                            shadowLine[shadowLine.Length - i - 1],
                            getTotalShadowStartDirection(position, shadowLine[shadowLine.Length - i - 1]),
                            1));
                        break;
                    }
                    else
                    {
                        leftpenumbra.sections.Add(new Penumbra.Section(
                            shadowLine[shadowLine.Length - i - 2],
                            extendDir(shadowLine[shadowLine.Length - i - 2] - shadowLine[shadowLine.Length - i - 1]),
                            available / wanted));
                    }
                }
            }

            //
            // build umbrae (hard shadows), cast between the insides of penumbrae
            //

            Umbra umbra;
            umbra.sections = new List<Umbra.Section>();

            umbra.sections.Add(new Umbra.Section(rightpenumbra.sections.Last()._base, rightpenumbra.sections.Last().direction));

            for (int i = rightpenumbra.sections.Count - 1; i < shadowLine.Length - leftpenumbra.sections.Count + 1; i++)
                umbra.sections.Add(new Umbra.Section(shadowLine[i], extendDir(Vector2.Multiply(leftpenumbra.sections.Last().direction + rightpenumbra.sections.Last().direction, 0.5f))));

            umbra.sections.Add(new Umbra.Section(leftpenumbra.sections.Last()._base, leftpenumbra.sections.Last().direction));

            //
            // draw shadows to alpha
            //
            umbra.draw();
            rightpenumbra.draw();
            leftpenumbra.draw();
        }
예제 #33
0
 public void PrepareLastElement()
 {
     if( null == this.ProductionCast || null == this.ProductionCast.Elements )
     {
         this.lastExistingPolygon = null;
         return;
     }
     this.lastExistingPolygon = this.ProductionCast.LastElement;
 }
예제 #34
0
 public void AddShadowCaster(Rectangle rect)
 {
     ConvexPolygon poly = new ConvexPolygon( new Vector2(-rect.Width/2, -rect.Height/2),
                                             new Vector2(rect.Width/2, -rect.Height/2),
                                             new Vector2(rect.Width/2, rect.Height/2),
                                             new Vector2(-rect.Width/2, rect.Height/2));
     casters.Add(new ShadowCaster() { poly = poly, position = new Vector2(rect.X + rect.Width / 2, rect.Y + rect.Height / 2) });
 }
예제 #35
0
 public void AddShadowCaster(ConvexPolygon poly, Vector2 position)
 {
     casters.Add(new ShadowCaster() { poly = poly, position = position });
 }