private static Vector2[] GenerateStarSystemsPositions(Int32 count, Single multiplier)
        {
            Assert.IsTrue(count > 4);

            var positions = new Vector2[count];

            Int32 horizontalCount = (Int32)Mathf.Sqrt(count);

            for (Int32 i = 0; i < count; i++)
            {
                // ReSharper disable once PossibleLossOfFraction
                positions[i] = new Vector2(i % horizontalCount, i / horizontalCount);

                for (Int32 rndOffsetCount = 2; rndOffsetCount <= 6; rndOffsetCount++)
                {
                    positions[i] += new Vector2(Random.Range(-1f, 1f), Random.Range(-0.6f, 0.6f)) / rndOffsetCount;
                }
            }

            Single minX = positions.Select(p => p.x).Min();
            Single minY = positions.Select(p => p.y).Min();

            Single deltaX = minX < 0 ? -minX : 0;
            Single deltaY = minY < 0 ? -minY : 0;

            for (Int32 i = 0; i < positions.Length; i++)
            {
                positions[i] += new Vector2(deltaX, deltaY);
                positions[i] *= multiplier;
            }

            return(positions);
        }
Exemple #2
0
        public static void CalculateGaussian(float dx, float dy, float force, out float[] weightsParameter, out Vector4[] offsetsParameter) {
            // Look up how many samples our gaussian blur effect supports.
            const int sampleCount = EffectPpBlur.SampleCount;

            // Create temporary arrays for computing our filter settings.
            var sampleWeights = new float[sampleCount];
            var sampleOffsets = new Vector2[sampleCount];

            // The first sample always has a zero offset.
            sampleWeights[0] = ComputeGaussian(0, force);
            sampleOffsets[0] = new Vector2(0);

            // Maintain a sum of all the weighting values.
            var totalWeights = sampleWeights[0];

            // Add pairs of additional sample taps, positioned
            // along a line in both directions from the center.
            for (var i = 0; i < sampleCount / 2; i++) {
                // Store weights for the positive and negative taps.
                var weight = ComputeGaussian(i + 1, force);

                sampleWeights[i * 2 + 1] = weight;
                sampleWeights[i * 2 + 2] = weight;

                totalWeights += weight * 2;

                // To get the maximum amount of blurring from a limited number of
                // pixel shader samples, we take advantage of the bilinear filtering
                // hardware inside the texture fetch unit. If we position our texture
                // coordinates exactly halfway between two texels, the filtering unit
                // will average them for us, giving two samples for the price of one.
                // This allows us to step in units of two texels per sample, rather
                // than just one at a time. The 1.5 offset kicks things off by
                // positioning us nicely in between two texels.
                var sampleOffset = i * 2 + 1.5f;

                var delta = new Vector2(dx, dy) * sampleOffset;

                // Store texture coordinate offsets for the positive and negative taps.
                sampleOffsets[i * 2 + 1] = delta;
                sampleOffsets[i * 2 + 2] = -delta;
            }

            // Normalize the list of sample weightings, so they will always sum to one.
            for (var i = 0; i < sampleWeights.Length; i++) {
                sampleWeights[i] /= totalWeights;
            }

            // Tell the effect about our new filter settings.
            weightsParameter = sampleWeights;
            offsetsParameter = sampleOffsets.Select(x => new Vector4(x, 0, 0)).ToArray();
        }
    private void ModifyRectangleGrid(VertexHelper vh, UIVertex[] rectangleVertices, GradationMaterial.Grid grid, int x, int y, Vector2[] rectangleNormalizePositions)
    {
        var gridPositions = new Vector2[System.Enum.GetValues(typeof(RectangleIndex)).Length];
        var gridColors    = new Color[System.Enum.GetValues(typeof(RectangleIndex)).Length];

        for (int i = 0, iMax = System.Enum.GetValues(typeof(RectangleIndex)).Length; i < iMax; ++i)
        {
            var xOffset = (i ^ (i >> 1)) & 0x01;
            var yOffest = i >> 1;
            var xIndex  = x + xOffset;
            var yIndex  = y + yOffest;
            gridPositions[i] = new Vector2(grid.xThresholds[xIndex], grid.yThresholds[yIndex]);
            gridColors[i]    = grid.GetColor(xIndex, yIndex);
        }

        System.Func <Vector2, UIVertex> PickupUIVertex = (position) => {
            var v = position;
            for (int i = 0, iMax = 2; i < iMax; ++i)
            {
                v[i] = Mathf.InverseLerp(rectangleNormalizePositions[(int)RectangleIndex.UpperLeft][i], rectangleNormalizePositions[(int)RectangleIndex.LowerRight][i], v[i]);
            }
            var result = Lerp2D <UIVertex>(rectangleVertices, v, LerpUIVertex);

            var c = position;
            for (int i = 0, iMax = 2; i < iMax; ++i)
            {
                c[i] = Mathf.InverseLerp(gridPositions[(int)RectangleIndex.UpperLeft][i], gridPositions[(int)RectangleIndex.LowerRight][i], c[i]);
            }
            var gridColor = Lerp2D <Color>(gridColors, c, Color.Lerp);
            result.color = BlendColor(result.color, gridColor);

            return(result);
        };

        var maskedPositions = new Vector2[System.Enum.GetValues(typeof(RectangleIndex)).Length];

        for (int i = 0, iMax = maskedPositions.Length; i < iMax; ++i)
        {
            for (int k = 0, kMax = 2; k < kMax; ++k)
            {
                maskedPositions[i][k] = Mathf.Clamp(rectangleNormalizePositions[i][k], gridPositions[(int)RectangleIndex.UpperLeft][k], gridPositions[(int)RectangleIndex.LowerRight][k]);
            }
        }
        maskedPositions = maskedPositions.Distinct(new Vector2Approximately()).ToArray();

        if (maskedPositions.Length == 4)
        {
            var maskedVertices = maskedPositions.Select(z => PickupUIVertex(z)).ToArray();
            vh.AddUIVertexQuad(maskedVertices);
        }
    }
        public static IEnumerable <Vector2> GetSurroundingTiles(Vector2 tileLocation)
        {
            Vector2[] offsets = new Vector2[] {
                new Vector2(0, 1),
                new Vector2(0, -1),
                new Vector2(1, 0),
                new Vector2(-1, 0),
                new Vector2(1, 1),
                new Vector2(1, -1),
                new Vector2(-1, 1),
                new Vector2(-1, -1)
            };

            return(offsets.Select(offset => tileLocation + offset).
                   Where(v => v.X >= 0 && v.Y >= 0));
        }
Exemple #5
0
    protected virtual void Update()
    {
        if (BeginTarget == null || EndTarget == null)
        {
            return;
        }

        Vector2[] positions = new Vector2[]
        {
            PositionAlongLine(BeginDistance),
            PositionAlongLine(CurrentDistance - EndDistance)
        };

        mLineRenderer.SetPositions(positions.Select(Helper.CanvasToWorldSpace).ToArray());
        mLineRenderer.enabled = CurrentDistance >= MinRenderDistance;
    }
        private static void DrawBox(BoxCollider2D box, ST2USettings settings)
        {
            CheckHelpers();
            Vector3 offset = box.offset;

            var corners = new Vector2[]
            {
                new Vector2(box.offset.x - box.size.x * 0.5f, box.offset.y + box.size.y * 0.5f),
                new Vector2(box.offset.x + box.size.x * 0.5f, box.offset.y + box.size.y * 0.5f),
                new Vector2(box.offset.x + box.size.x * 0.5f, box.offset.y - box.size.y * 0.5f),
                new Vector2(box.offset.x - box.size.x * 0.5f, box.offset.y - box.size.y * 0.5f),
            };

            var points = corners.Select(pt => box.transform.TransformPoint(pt)).ToArray();

            DrawAsConvexPolygon(box.gameObject, points, settings);
        }
        public void SetDetailLevels(float[] fovs)
        {
            FOVs          = new int[fovs.Length];
            fovTestAngles = new Vector2[fovs.Length][];
            var requiredAngles = new Vector2[fovs.Length][];

            for (int f = 0; f < fovs.Length; ++f)
            {
                FOVs[f]           = (int)fovs[f];
                fovTestAngles[f]  = MakeTestAngles(fovs[f], true);
                requiredAngles[f] = MakeTestAngles(fovs[f], false);
            }

            lodLevelRequirements = requiredAngles
                                   .Select(a => a.Length)
                                   .ToArray();
        }
        public override Collider2D MakeBox(GameObject go, float width, float height)
        {
            // In isometric space, a box is skewed and therefore represented by a polygon
            var points = new Vector2[4]
            {
                new Vector2(0, 0),
                new Vector2(width, 0),
                new Vector2(width, height),
                new Vector2(0, height),
            };

            // Points are transformed to isometric space and then into Unity coordinates
            var transformed = points.Select(p => ImportContext.MakePoint(TransformPoint(p))).ToArray();

            var collider = go.AddComponent <PolygonCollider2D>();

            collider.SetPath(0, transformed);

            return(collider);
        }
Exemple #9
0
        internal static IEnumerable<Polygon> CreatePolygons(float height, Vector2[] points, Func<Vector3, Vector3, Vertex> vertexFactory, bool guaranteeNormals = true)
        {
            vertexFactory = vertexFactory ?? ((p, n) => new Vertex(p, n));

            //top circle
            var top = new Polygon(points.Select(a => new Vector3(a.X, height / 2, a.Y)).Select(a => vertexFactory(a, Vector3.Zero)));

            float dot = Vector3.Dot(Vector3.Up, top.Plane.Normal);
            if (dot < 0 && guaranteeNormals)
            {
                foreach (var item in CreatePolygons(height, points.Reverse().ToArray(), vertexFactory, false))
                    yield return item;
                yield break;
            }

            yield return top;

            //bottom circle
            var bottom = new Polygon(points.Reverse().Select(a => new Vector3(a.X, -height / 2, a.Y)).Select(a => vertexFactory(a, Vector3.Zero)));
            yield return bottom;

            //sides
            for (int i = 0; i < points.Length; i++)
            {
                Vector2 pos1 = points[(i + 1) % points.Length];
                Vector2 pos2 = points[i];

                var poly = new Polygon(new Vertex[] {                                  
                    vertexFactory(new Vector3(pos2.X, height / 2, pos2.Y), Vector3.Zero),
                    vertexFactory(new Vector3(pos2.X, -height / 2, pos2.Y), Vector3.Zero),
                    vertexFactory(new Vector3(pos1.X, -height / 2, pos1.Y), Vector3.Zero),
                    vertexFactory(new Vector3(pos1.X, height / 2, pos1.Y), Vector3.Zero),
                });

                yield return poly;
            }
        }
Exemple #10
0
        public static BufferData4Textured UnitCircle(Color4 col, int vertices, float radius)
        {
            var UnitCircleVertices =
                new Vector2[] {
                new Vector2(0, 0)
            }
            .Concat(
                Enumerable.Range(1, vertices)
                .Select(vertex => 2 * Math.PI * vertex / vertices)
                .Select(angleRadians => new Vector2(
                            (float)(radius * Math.Cos(angleRadians)),
                            (float)(radius * Math.Sin(angleRadians))
                            )
                        )
                )
            .ToArray();

            return(new BufferData4Textured {
                Vertices = UnitCircleVertices.Select(
                    v => new Vertex4Textured {
                    Position = new Vector4(v.X, v.Y, 0.0f, 1.0f),
                    TexCoord = new Vector2(v.X / 2 + 0.5f, v.Y / 2 + 0.5f)
                }
                    )
                           .ToArray(),
                Indices = Enumerable.Range(0, vertices)
                          .SelectMany(x => new uint[]
                {
                    0,
                    (uint)((x + 1) <= vertices ? (x + 1) : ((x + 1) - vertices)),
                    (uint)((x + 2) <= vertices ? (x + 2) : ((x + 2) - vertices))
                }
                                      )
                          .ToArray()
            });
        }
        /// <summary>
        /// you whims. fine, this functions sets and positions the vertices for you. no need to worry about centering vertices about the orgin or anything. (this also sets the position of the object as the center of the vertices)
        /// </summary>
        /// <param name="verts"></param>
        public void ConstructFromVertices(Vector2[] verts)
        {
            if (verts.Length < 3) new Exception("verts must be >= 3.");

            var cent = verts.Aggregate((a, b) => a + b) / verts.Length;
            this.RawVertices = verts.Select(v => v - cent).ToArray();
            this.SetMasterPosition(cent);
        }
Exemple #12
0
        public static Matrix4x4 TSMTransform(Camera camera, Matrix4x4 lightViewProjection,
                                             ShadowSettings shadowSettings)
        {
            var frustumVerts = ShadowUtils
                               .GetCameraFrustumVerticies(camera, camera.nearClipPlane, shadowSettings.maxShadowDistance)
                               .Select(p => ToPostPerspective(p, lightViewProjection));
            var convex     = GetConvexHull(frustumVerts.Select(p => p.ToVector2()).ToArray());
            var nearCenter =
                ToPostPerspective(camera.transform.position + camera.transform.forward * camera.nearClipPlane,
                                  lightViewProjection).ToVector2();
            var farCenter =
                ToPostPerspective(
                    camera.transform.position + camera.transform.forward * shadowSettings.maxShadowDistance,
                    lightViewProjection).ToVector2();
            var focusPoint =
                ToPostPerspective(camera.transform.position + camera.transform.forward * shadowSettings.focusDistance,
                                  lightViewProjection).ToVector2();
            var centralLine       = farCenter - nearCenter;
            var centralLineVector = centralLine.normalized;
            var topPoint          = nearCenter +
                                    centralLineVector * convex.Min(p => Vector2.Dot(p - nearCenter, centralLineVector));
            var bottomVert  = convex.MaxOf(p => Vector2.Dot(p - nearCenter, centralLineVector), p => p);
            var bottomPoint = topPoint + centralLineVector * Vector2.Dot(bottomVert - topPoint, centralLineVector);
            var tangent     = (bottomVert - bottomPoint).normalized *
                              Mathf.Sign(MathUtility.Cross2(bottomVert - topPoint, centralLineVector));
            var height   = (bottomPoint - topPoint).magnitude;
            var focusLen = Vector2.Dot(focusPoint - topPoint, centralLineVector);

            var λ = height;
            var ξ = -0.6f;
            var δ = focusLen;
            var η = (λ * δ + λ * δ * ξ) / (λ - 2 * δ - λ * ξ);

            var origin          = -η * centralLineVector + topPoint;
            var cosMaxHalfAngle = convex.Min(p => Vector2.Dot((p - origin).normalized, centralLineVector));
            var tan             = Mathf.Sqrt(1 - cosMaxHalfAngle * cosMaxHalfAngle) / cosMaxHalfAngle;
            var minSinHalfAngle = convex.Min(p => MathUtility.Cross2((p - origin).normalized, centralLineVector));
            var maxSinHalfAngle = convex.Max(p => MathUtility.Cross2((p - origin).normalized, centralLineVector));
            var minTan          = minSinHalfAngle / Mathf.Sqrt(1 - minSinHalfAngle * minSinHalfAngle);
            var maxTan          = maxSinHalfAngle / Mathf.Sqrt(1 - maxSinHalfAngle * maxSinHalfAngle);

            var t0 = bottomPoint + (bottomPoint - origin).magnitude * minTan * tangent;
            var t1 = bottomPoint + (bottomPoint - origin).magnitude * maxTan * tangent;
            var t2 = topPoint + (topPoint - origin).magnitude * minTan * tangent;
            var t3 = topPoint + (topPoint - origin).magnitude * maxTan * tangent;

            // Transform trapezoid into unit cube
            // Following https://www.comp.nus.edu.sg/~tants/tsm/TSM_recipe.html
            var transform = Matrix4x4.identity;

            // #1
            Vector4 u = (t2 + t3) / 2;

            transform = Matrix4x4.Translate(-u) * transform;

            // #2
            u         = (t2 - t3) / (t2 - t3).magnitude;
            transform = new Matrix4x4(
                new Vector4(u.x, u.y, 0, 0),
                new Vector4(u.y, -u.x, 0, 0),
                new Vector4(0, 0, 1, 0),
                new Vector4(0, 0, 0, 1)
                ) * transform;

            // #3
            u         = transform * origin.ToVector4(0, 1);
            transform = Matrix4x4.Translate(-u) * transform;

            // #4
            u         = (transform.MultiplyPoint((t2 + t3) / 2));
            transform = new Matrix4x4(
                new Vector4(1, -u.x / u.y, 0, 0),
                new Vector4(0, 1, 0, 0),
                new Vector4(0, 0, 1, 0),
                new Vector4(0, 0, 0, 1)
                ).transpose *transform;

            // #5
            u         = transform.MultiplyPoint(t2);
            transform = Matrix4x4.Scale(new Vector3(1 / u.x, 1 / u.y, 1)) * transform;

            // #6
            transform = new Matrix4x4(
                new Vector4(1, 0, 0, 0),
                new Vector4(0, 1, 0, 1),
                new Vector4(0, 0, 1, 0),
                new Vector4(0, 1, 0, 0)
                ) * transform;

            // #7
            u = transform * t0.ToVector4(0, 1);
            var v = transform * t2.ToVector4(0, 1);

            transform = Matrix4x4.Translate(new Vector3(0, -(u.y / u.w + v.y / v.w) / 2, 0)) * transform;

            // #8
            u         = transform * t0.ToVector4(0, 1);
            transform = Matrix4x4.Scale(new Vector3(1, -u.w / u.y, 1)) * transform;


            var trapezoidal = new Vector2[] { t0, t1, t3, t2 };
            var t           = trapezoidal.Select(p => transform.MultiplyPoint(p).ToVector2()).ToArray();

            //DrawPolygonOnLightPlane(t, lightViewProjection, Color.blue);
            if (shadowSettings.debug)
            {
                ShadowUtils.DrawPolygonOnLightPlane(trapezoidal, lightViewProjection, Color.blue);
                ShadowUtils.DrawPolygonOnLightPlane(new Vector2[] { nearCenter, farCenter }, lightViewProjection, Color.red);
                ShadowUtils.DrawPolygonOnLightPlane(convex, lightViewProjection, Color.red);
            }

            return(transform);
        }
    private static Mesh CreateMesh(Sprite sprite, Vector2[] polygon)
    {
        if (sprite != null && polygon != null) {
            Rect bounds = GetBounds(polygon);

            DTSweepContext ctx = new DTSweepContext();
            Polygon poly = new Polygon(polygon.Select(p => new PolygonPoint(p.x, p.y)));

            ctx.PrepareTriangulation(poly);
            DTSweep.Triangulate(ctx);

            List<Vector2> verts = new List<Vector2>();
            List<int> tris = new List<int>();

            foreach (DelaunayTriangle tri in poly.Triangles) {
                verts.AddRange(tri.Points.Reverse().Select(p => new Vector2(p.Xf, p.Yf)));
                for (int i = 0; i < 3; i++) {
                    tris.Add(tris.Count);
                }
            }

            Mesh mesh = new Mesh();
            mesh.vertices = verts.Select(x => (Vector3)x).ToArray();
            mesh.triangles = tris.ToArray();

            List<Vector2> uv = new List<Vector2>();

            Vector3 lower = new Vector3(bounds.x, bounds.y);
            Vector3 size = new Vector3(bounds.xMax, bounds.yMax) - lower;

            Rect uvBounds = new Rect(sprite.rect.x / sprite.texture.width, sprite.rect.y / sprite.texture.height,
                sprite.rect.width / sprite.texture.width, sprite.rect.height / sprite.texture.height);

            float scalex = sprite.bounds.size.x / bounds.width;
            float scaley = sprite.bounds.size.y / bounds.height;

            Vector3[] scaled = mesh.vertices;

            for (int i = 0; i < mesh.vertices.Length; i++) {
                Vector3 v = scaled[i];
                Vector3 rel = v - lower;
                uv.Add(new Vector2(rel.x / size.x * uvBounds.width, rel.y / size.y * uvBounds.height) +
                       new Vector2(uvBounds.x, uvBounds.y));

                scaled[i] = new Vector3(v.x * scalex, v.y * scaley, v.z) - ((Vector3)bounds.center * scalex) +
                            sprite.bounds.center;
            }

            mesh.vertices = scaled;
            mesh.uv = uv.ToArray();
            mesh.RecalculateNormals();
            mesh.RecalculateBounds();
            mesh.Optimize();

            return mesh;
        }

        return null;
    }
Exemple #14
0
 /// <summary>
 ///     Draws a set of lines joining the array of points given.
 /// </summary>
 /// <param name="points">The points to draw lines between.</param>
 public void DrawLines(Vector2[] points)
 {
     _graphics.DrawLines(LinePen, points.Select(GDIExtensions.ToPointF).ToArray());
 }
    /// <summary>
    /// 多角形をRectの中に収まるようにリサイズする。
    /// </summary>
    /// <returns>
    /// リサイズされたポリゴン。
    /// </returns>
    /// <param name='inPolygon'>
    /// もとのポリゴン。
    /// </param>
    /// <param name='inRect'>
    /// 収めたい四角形
    /// </param>
    static Vector2[] StretchPolygonToRect(Vector2[] inPolygon, Rect inRect)
    {
        float xMin = inPolygon.Select (vec => vec.x).Min ();
        float yMin = inPolygon.Select (vec => vec.y).Min ();
        float xMax = inPolygon.Select (vec => vec.x).Max ();
        float yMax = inPolygon.Select (vec => vec.y).Max ();
        Vector2 scaler = new Vector2 (inRect.width / (xMax - xMin), inRect.height / (yMax - yMin));
        Vector2 origin = new Vector2 (inRect.x, inRect.y);

        return inPolygon.Select(vec => origin + new Vector2((vec.x - xMin) * scaler.x, (vec.y - yMin) * scaler.y)).ToArray();
    }
Exemple #16
0
        //Project a bounding box into the sprite sheet
        //Takes parameters in VERTEX space (range -0.5 to +0.5 on each axis, and Y increases upwards)
        //Returns vertices in vertex space, with texture coordinates in texture space (range 0 to 0.1 within this box, and Y increases downwards)
        //The texture coordinates can be transformed by an input matrix.
        //We invert that matrix to be more intuitive.  Example: Scale 2 would double the coords of the bounding box, shrinking the contents.  Inversion makes that the other way around, scale 2 doubles the size of the contents
        private List<VertexPositionNormalTexture> GetBoxVertices(int row, int frame, Vector2 center, float width, float height, Matrix transform)
        {
            //in VERTEX space, Y increases upwards
            //6 vertices, middle two repeated: NW SW NE NE SW SE
            var vertices = new Vector2[] {
                new Vector2(center.X - width / 2, center.Y + height / 2),
                new Vector2(center.X - width / 2, center.Y - height / 2),
                new Vector2(center.X + width / 2, center.Y + height / 2),
                new Vector2(center.X + width / 2, center.Y + height / 2),
                new Vector2(center.X - width / 2, center.Y - height / 2),
                new Vector2(center.X + width / 2, center.Y - height / 2),
            };

            var sheetOffset = new Vector2(frame * 0.1F, row / 6F);
            var centerInTextureSpace = new Vector3(0.5F + center.X, 1 - (0.5F + center.Y), 0);
            var scaleVector = new Vector2(0.1F, 1 / 6F);

            //Create VertexPositionNormalTexture by projecting those vertices into texture space (Y increases downwards)
            var result = vertices.Select(v =>
                new VertexPositionNormalTexture(
                    new Vector3(v, 0),
                    Vector3.UnitZ,
                    Vector2.Transform(
                        new Vector2(0.5F + v.X, 1 - (0.5F + v.Y)),          //Project to texture space
                        Matrix.CreateTranslation(-centerInTextureSpace)
                        * Matrix.Invert(transform)                          //Transform by inverted matrix
                        * Matrix.CreateTranslation(centerInTextureSpace)
                        )
                        * scaleVector                                       //Scale into box on sprite sheet
                        + sheetOffset                                       //Locate correct box on sprite sheet
                    ));

            return result.ToList();
        }
Exemple #17
0
 private void PunchWalls(Vector2[] relativeSliceSides)
 {
     var punchPoses = relativeSliceSides.Select(side => Pos + (_range * side).Rotate(Rotation));
     var punchedPoses = punchPoses.Where(pos => Arena.MakeHole(pos, _wallPunchRadius) > 0).ToList();
     foreach (var pos in punchedPoses) GobHelper.CreateGobs(_wallPunchEffects, Arena, pos);
     if (Game.NetworkMode == Core.NetworkMode.Server)
     {
         _wallPunchPosesForClient.AddRange(punchedPoses);
         ForcedNetworkUpdate = punchedPoses.Any();
     }
     PlayWallHitSound(punchedPoses);
 }
        private void CreateGeometry()
        {
            //Outline of the left hemisphere of the apple
            var ApplePath = new Vector2[] {
                new Vector2(-0.020000F, 0.700000F),     //top of stem
                new Vector2(-0.010000F, 0.440213F),
                new Vector2(-0.058064F, 0.458075F),
                new Vector2(-0.089738F, 0.47272F),
                new Vector2(-0.124715F, 0.485741F),
                new Vector2(-0.158809F, 0.494292F),
                new Vector2(-0.190711F, 0.498586F),
                new Vector2(-0.22123F, 0.5F),
                new Vector2(-0.247882F, 0.5F),
                new Vector2(-0.277519F, 0.497122F),
                new Vector2(-0.310265F, 0.490708F),
                new Vector2(-0.344814F, 0.481744F),
                new Vector2(-0.376999F, 0.469076F),
                new Vector2(-0.407488F, 0.45381F),
                new Vector2(-0.434271F, 0.437314F),
                new Vector2(-0.459377F, 0.417243F),
                new Vector2(-0.484007F, 0.395206F),
                new Vector2(-0.507048F, 0.369914F),
                new Vector2(-0.526035F, 0.344555F),
                new Vector2(-0.54089F, 0.319227F),
                new Vector2(-0.555707F, 0.290045F),
                new Vector2(-0.569115F, 0.254852F),
                new Vector2(-0.577314F, 0.228198F),
                new Vector2(-0.584468F, 0.19906F),
                new Vector2(-0.588578F, 0.16896F),
                new Vector2(-0.591284F, 0.133185F),
                new Vector2(-0.591284F, 0.098829F),
                new Vector2(-0.589493F, 0.061006F),
                new Vector2(-0.586381F, 0.024448F),
                new Vector2(-0.579149F, -0.016041F),
                new Vector2(-0.568172F, -0.056079F),
                new Vector2(-0.555456F, -0.094218F),
                new Vector2(-0.540547F, -0.132857F),
                new Vector2(-0.521512F, -0.176759F),
                new Vector2(-0.500255F, -0.217859F),
                new Vector2(-0.478427F, -0.254953F),
                new Vector2(-0.45186F, -0.293177F),
                new Vector2(-0.428561F, -0.322585F),
                new Vector2(-0.402263F, -0.353761F),
                new Vector2(-0.373769F, -0.383047F),
                new Vector2(-0.348312F, -0.406423F),
                new Vector2(-0.323264F, -0.42672F),
                new Vector2(-0.285627F, -0.453059F),
                new Vector2(-0.254352F, -0.471896F),
                new Vector2(-0.225644F, -0.486786F),
                new Vector2(-0.193114F, -0.496683F),
                new Vector2(-0.15846F, -0.5F),
                new Vector2(-0.123685F, -0.5F),
                new Vector2(-0.091406F, -0.495908F),
                new Vector2(-0.059537F, -0.486206F),
                new Vector2(-0.029113F, -0.471417F),
                new Vector2(0F, -0.45465F),
            };
            const int LONGITUDES = 41;

            //Take N copies of that to rotate around for the entire half-apple
            VertexPositions = (from i in Enumerable.Range(0, LONGITUDES)
                               from v in ApplePath.Select(v => new Vector3(v, 0))
                               select GetLongitudeTransform(v, i / (float)(LONGITUDES - 1))
                              ).ToArray();

            //For each vertex except the last, create the two triangles between it and the next vertex and this pair of vertices on the next longitude
            var n = ApplePath.Length;
            int[][] TriangleIndices = Enumerable.Range(0, n - 1)
                .SelectMany(i => new int[][] {
                    new int[] { i, i + 1, i + n },
                    new int[] { i + 1, i + n + 1, i + n }
                }).ToArray();

            //Explode that to the number of strips (longitudes - 1)
            TriangleIndices = (from l in Enumerable.Range(0, LONGITUDES - 1)
                               from indices in TriangleIndices
                               select indices.Select(i => i + n * l).ToArray())
                              .ToArray();

            //Make a flat list of triangle indices from our jagged array
            AppleVertexIndices = TriangleIndices.SelectMany(i => i).ToArray();

            //Project vertex positions to include texture coordinates
            AppleVertices = CalculateVertexPositionTextures(VertexPositions, TriangleIndices);

            //Set up vertices for the second pass - redraw the polyhedron with VertexPositionColors to produce blue glass
            ColorVertices = AppleVertices.Select(vpt =>
                new VertexPositionColor(
                    vpt.Position,
                    Color.Blue
                    )).ToArray();
        }
        internal void drawAllLines()
        {
            TransportLine[] tls       = Singleton <TransportManager> .instance.m_lines.m_buffer;
            var             segments  = segmentManager.getSegments();
            string          mainStyle = "<polyline points=\"{0}\" class=\"path{4}\" style='stroke:rgb({1},{2},{3});' stroke-linejoin=\"round\" stroke-linecap=\"round\" marker-mid=\"url(#5)\"/> ";

            foreach (var segment in segments)
            {
                List <Vector2> basePoints = segment.path;
                for (int i = 0; i < basePoints.Count; i++)
                {
                    basePoints[i] = (basePoints[i] - offset) * multiplier;
                }
                float         offsetNeg = 0;
                float         offsetPos = 0;
                CardinalPoint dir       = CardinalPoint.getCardinal2D(segment.s1.centralPos, segment.s2.centralPos);
                dir++;
                dir++;
                Vector2 offsetDir = dir.getCardinalOffset2D();
                foreach (var line in segment.lines)
                {
                    float width = 0;
                    TransportInfo.TransportType tt = tls[line.Key.lineId].Info.m_transportType;
                    switch (tt)
                    {
                    case TransportInfo.TransportType.Tram:
                    case TransportInfo.TransportType.Bus:
                        width = 1;
                        break;

                    case TransportInfo.TransportType.Train:
                        width = 5;
                        break;

                    case TransportInfo.TransportType.Metro:
                        width = 2.5f;
                        break;

                    case TransportInfo.TransportType.Ship:
                        width = 8;
                        break;
                    }
                    float coordMultiplier = 0;
                    if (offsetNeg > offsetPos)
                    {
                        coordMultiplier = (offsetPos + width / 2);
                        offsetPos      += width;
                    }
                    else if (offsetNeg < offsetPos)
                    {
                        coordMultiplier = -(offsetNeg + width / 2);
                        offsetNeg      += width;
                    }
                    else
                    {
                        offsetPos = width / 2;
                        offsetNeg = width / 2;
                    }

                    var       lineTotalOffset = offsetDir * coordMultiplier * 2;
                    Vector2[] points          = new Vector2[basePoints.Count];
                    for (int i = 0; i < basePoints.Count; i++)
                    {
                        if (i == 0)
                        {
                            var cp = segment.s1.getDirectionForStation(segment.s2);
                            cp++;
                            cp++;
                            points[i] = basePoints[i] + cp.getCardinalOffset2D() * coordMultiplier * 2;
                        }
                        else if (i == basePoints.Count - 1)
                        {
                            var cp = segment.s2.getDirectionForStation(segment.s1);
                            cp++;
                            cp++;
                            points[i] = basePoints[i] + cp.getCardinalOffset2D() * coordMultiplier * 2;
                        }
                        else
                        {
                            points[i] = basePoints[i] + lineTotalOffset;
                        }
                    }
                    svgPart.AppendFormat(mainStyle, string.Join(" ", points.Select(x => "" + x.x + "," + x.y).ToArray()), line.Key.lineColor.r, line.Key.lineColor.g, line.Key.lineColor.b, tt.ToString(), line.Value);
                }
            }
        }
Exemple #20
0
    public static void FillPolygon(this Texture2D texture, Vector2[] points, Color color)
    {
        // http://alienryderflex.com/polygon_fill/

        var IMAGE_BOT = (int)points.Max(p => p.y);
        var IMAGE_TOP = (int)points.Min(p => p.y);
        var IMAGE_LEFT = (int)points.Min(p => p.x);
        var IMAGE_RIGHT = (int)points.Max(p => p.x);
        var MAX_POLY_CORNERS = points.Count();
        var polyCorners = MAX_POLY_CORNERS;
        var polyY = points.Select(p => p.y).ToArray();
        var polyX = points.Select(p => p.x).ToArray();
        int[] nodeX = new int[MAX_POLY_CORNERS];
        int nodes, pixelX, i, j, swap;

        //  Loop through the rows of the image.
        for (int pixelY = IMAGE_TOP; pixelY <= IMAGE_BOT; pixelY++)
        {

            //  Build a list of nodes.
            nodes = 0;
            j = polyCorners - 1;
            for (i = 0; i < polyCorners; i++)
            {
                if (polyY[i] < (float)pixelY && polyY[j] >= (float)pixelY || polyY[j] < (float)pixelY && polyY[i] >= (float)pixelY)
                {
                    nodeX[nodes++] = (int)(polyX[i] + (pixelY - polyY[i]) / (polyY[j] - polyY[i]) * (polyX[j] - polyX[i]));
                }
                j = i;
            }

            //  Sort the nodes, via a simple “Bubble” sort.
            i = 0;
            while (i < nodes - 1)
            {
                if (nodeX[i] > nodeX[i + 1])
                {
                    swap = nodeX[i]; nodeX[i] = nodeX[i + 1]; nodeX[i + 1] = swap; if (i != 0) i--;
                }
                else
                {
                    i++;
                }
            }

            //  Fill the pixels between node pairs.
            for (i = 0; i < nodes; i += 2)
            {
                if (nodeX[i] >= IMAGE_RIGHT) 
                    break;
                if (nodeX[i + 1] > IMAGE_LEFT)
                {
                    if (nodeX[i] < IMAGE_LEFT) 
                        nodeX[i] = IMAGE_LEFT;
                    if (nodeX[i + 1] > IMAGE_RIGHT) 
                        nodeX[i + 1] = IMAGE_RIGHT;
                    for (j = nodeX[i]; j < nodeX[i + 1]; j++)
                        texture.SetPixel(j, pixelY, color);
                }
            }
        }
    }
 // TODO DRAWER Eliminate Vector3 convertion
 public void DrawPolyLine(Vector2[] lines, Color color)
 {
     Handles.color = color;
     Handles.DrawPolyLine(lines.Select(x => new Vector3(x.x, x.y, 0)).ToArray());
 }
Exemple #22
0
        bool levelDown()
        {
            bool removed = false;
            //extract feature points from candidate
            List <int> candidate = makeCandidate();

            if (candidate.Count == 0)
            {
                return(false);
            }

            //calculate the priorities of candidate.
            Dictionary <int, float>            priorities = new Dictionary <int, float>();
            Dictionary <int, List <Triangle> > stars      = new Dictionary <int, List <Triangle> >();

            Utility.calcPrioritiesAndStars(mmesh, candidate, out stars, out priorities);

            //by the priorities, select the independent set
            List <int> remove_indices = Utility.makeRemovedIndices(priorities, stars);

            //flatten and retriangulation
            for (int i = 0; i < remove_indices.Count(); i++)
            {
                var star = stars[remove_indices[i]];

                bool on_boundary = false;
                bool invalid     = false;

                if (star.Count < 3 || star.Count > 12)
                {
                    unremoval_indices.Add(remove_indices[i]);
                    continue;
                }
                List <int> ring = Utility.FindRingFromStar(star, ref on_boundary, ref invalid);
                if (invalid)
                {
                    unremoval_indices.Add(remove_indices[i]);
                    continue;
                }
                //Add new triangles
                //Fistly, using conformal map z^a, 1 ring will be flattened
                Vector3                   pi          = mmesh.P[remove_indices[i]];
                List <Vector3>            ring_vs     = new List <Vector3>();
                List <float>              thetas      = new List <float>();
                List <float>              temp_thetas = new List <float>();
                Dictionary <int, Vector2> mapped_ring = new Dictionary <int, Vector2>();

                float a = Utility.calcMappedRing(mmesh, pi, ring, on_boundary, ref thetas, ref temp_thetas, ref mapped_ring);

                //Secondly, retriangulation by a constrained Delauney triangulation
                //In Test, implementation is easy one.
                if (ring.Count < 3 || ring.Count >= 12)
                {
                    unremoval_indices.Add(remove_indices[i]);
                    continue;
                }

                List <Triangle> added_triangles = null;
                bool            found_triangles = TrianglationNet.triangulateFromRing(ring, mapped_ring, out added_triangles);
                if (!found_triangles)
                {
                    unremoval_indices.Add(remove_indices[i]);
                    continue;
                }
                mmesh.K.triangles.AddRange(added_triangles);

                //Finally, remove triangle and remove vertex from mmesh
                all_removed_indices.Add(remove_indices[i]);
                mmesh.removeStars(star);
                mmesh.removeVertex(remove_indices[i]);

                bool found = false;
                //About Bijection
                //When the previous bijection of removed vertex is identity,
                //Updated bijection of it will be constructed by triangles whrere it on in conformed mapped star.
                //Detection by cross
                //KeyValuePair<vertexIndex, bijection<>> initialy bijection[vertexIndex]={vertexIndex:1.0}

                foreach (Dictionary <int, float> kv in mmesh.bijection)
                {
                    //if removed vertex is used for some construction, recalc the construction
                    //https://www.chart.co.jp/subject/sugaku/suken_tsushin/74/74-1.pdf
                    if (!kv.ContainsKey(remove_indices[i]))
                    {
                        continue;
                    }
                    //------------------------------------------------------------------------------
                    //Find update bijection index;
                    //------------------------------------------------------------------------------
                    Vector2 myu_pi = Vector2.one * 1000.0f;
                    float   al = 0, bet = 0;
                    if (kv.Count == 1)
                    {
                        //Initialy bijection[vertexIndex]={vertexIndex:1.0}
                        myu_pi = Vector2.zero;
                    }
                    else if (kv.Count == 2)
                    {
                        foreach (KeyValuePair <int, float> bb in kv)
                        {
                            if (bb.Key == remove_indices[i])
                            {
                                continue;
                            }
                            myu_pi = mapped_ring[bb.Key] * bb.Value;
                        }
                    }
                    else if (kv.Count == 3)
                    {
                        //3つから構成されている場合
                        for (int l = 0; l < ring.Count(); l++)
                        {
                            if (kv.ContainsKey(ring[l]) && kv.ContainsKey(ring[l + 1 != ring.Count ? l + 1 : 0]))
                            {
                                int ind_min = ring[l];
                                int ind_max = ring[l + 1 != ring.Count ? l + 1 : 0];
                                al     = kv[ind_min];
                                bet    = kv[ind_max];
                                myu_pi = mapped_ring[ind_min] * kv[ind_min] + mapped_ring[ind_max] * kv[ind_max];
                                break;
                            }
                        }
                    }

                    //find triangle which contain myu_pi
                    //For example case 1,
                    //myu_pi = (0,0) and find added triangle contain (0,0)
                    //------------------------------------------------------------------------------
                    //Find update bijection index;
                    //------------------------------------------------------------------------------
                    //Calc center of mapped ring to refine myu_pi.
                    Vector2 center = new Vector2(0, 0);
                    foreach (KeyValuePair <int, Vector2> mp in mapped_ring)
                    {
                        center += mp.Value / (float)(mapped_ring.Count);
                    }

                    found = false;
                    int nloop = 0;
                    while (!found && nloop < 10)
                    {
                        foreach (Triangle T in added_triangles)
                        {
                            Vector2[] points = new Vector2[3] {
                                mapped_ring[T.ind1], mapped_ring[T.ind2], mapped_ring[T.ind3]
                            };
                            if (!MathUtility.checkContain(points, myu_pi))
                            {
                                continue;
                            }
                            points = points.Select(p => p - myu_pi).ToArray();
                            float[] param = new float[3] {
                                MathUtility.calcArea(points[1], points[2]), MathUtility.calcArea(points[2], points[0]), MathUtility.calcArea(points[0], points[1])
                            };
                            for (int x = 0; x < 3; x++)
                            {
                                param[x] = double.IsNaN(param[x]) ? 0 : param[x];
                            }
                            float params_sum = param.Sum();
                            if (params_sum == 0)
                            {
                                continue;
                            }
                            param = param.Select(p => p / params_sum).ToArray();
                            kv.Clear();
                            if (param[0] != 0)
                            {
                                kv.Add(T.ind1, param[0]);
                            }
                            if (param[1] != 0)
                            {
                                kv.Add(T.ind2, param[1]);
                            }
                            if (param[2] != 0)
                            {
                                kv.Add(T.ind3, param[2]);
                            }
                            found = true;
                            break;
                        }
                        myu_pi += 0.1f * (center - myu_pi);
                        nloop++;
                    }
                }
                removed = true;
            }
            return(removed);
        }