コード例 #1
0
        /// <summary>
        ///     Gets the matrix that transforms the part at this position to another position.
        /// </summary>
        /// <param name="other">The other.</param>
        /// <returns></returns>
        /// <exception cref="System.InvalidOperationException">
        ///     The method has been called on a default instance of the <see cref="EdgePartPosition" /> struct.
        /// </exception>
        /// <exception cref="System.ArgumentException">The other edge part has not been set.</exception>
        public Matrix3x2 GetTransformTo(EdgePartPosition other)
        {
            if (Part == null)
            {
                throw new InvalidOperationException("Edge part not set.");
            }
            if (other.Part == null)
            {
                throw new ArgumentException("Other edge part not set.", nameof(other));
            }

            bool isClockwise      = Part.IsClockwise;
            bool otherIsClockwise = other.Part.IsClockwise;

            Vector2 fromStart = isClockwise ? Start : End;
            Vector2 fromEnd   = isClockwise ? End : Start;
            Vector2 toStart   = otherIsClockwise ? other.Start : other.End;
            Vector2 toEnd     = otherIsClockwise ? other.End : other.Start;

            Matrix3x2 transform = Matrix.GetTransform(fromStart, fromEnd, toStart, toEnd);

            if (isClockwise == otherIsClockwise)
            {
                transform *= Matrix.CreateReflection(toStart, toEnd);
            }

            return(transform);
        }
コード例 #2
0
 public EdgePartPosition GetEdgePartPosition([NotNull] EdgePart edgePart)
 => EdgePartPosition.Create(edgePart, Shape, Transform);
コード例 #3
0
        public Tiling CreateTiling(
            [NotNull] TilingDefinition tilingDefinition,
            [NotNull] ShapeSet shapes,
            [NotNull] StyleManager styleManager)
        {
            if (tilingDefinition == null)
            {
                throw new ArgumentNullException(nameof(tilingDefinition));
            }
            if (shapes == null)
            {
                throw new ArgumentNullException(nameof(shapes));
            }
            if (styleManager == null)
            {
                throw new ArgumentNullException(nameof(styleManager));
            }
            if (!Tilings.Values.Contains(tilingDefinition))
            {
                throw new ArgumentException(
                          Strings.Template_CreateTiling_UnknownTilingDefinition,
                          nameof(tilingDefinition));
            }

            HashSet <ShapeTemplate> templates = new HashSet <ShapeTemplate>(shapes.Select(s => s.Template));

            if (!templates.SetEquals(ShapeTemplates.Values))
            {
                throw new ArgumentException(Strings.Template_CreateTiling_WrongShapes, nameof(shapes));
            }

            Dictionary <int, ShapeLines> shapeLines = new Dictionary <int, ShapeLines>();

            List <Tile> tiles = new List <Tile>(shapes.Count);

            // TODO Order shapes so that the nth shape is adjacent to at least one of the previous shapes
            foreach (Shape shape in shapes)
            {
                Debug.Assert(shape != null, "shape != null");

                string    label     = null;
                Matrix3x2 transform = default(Matrix3x2);

                if (tiles.Count < 1)
                {
                    label = tilingDefinition.AdjacentParts
                            .Where(l => l.Value.ShapeTemplate == shape.Template)
                            .OrderBy(l => l.Label, StringComparer.InvariantCulture)
                            .First().Label;
                    transform = Matrix3x2.Identity;
                }
                else
                {
                    foreach (Tile t in tiles)
                    {
                        foreach (EdgePartShape partShape in t.PartShapes)
                        {
                            Debug.Assert(partShape != null, "partShape != null");

                            Labeled <EdgePart> adjacent;
                            if (!tilingDefinition.AdjacentParts.TryGetAdjacent(
                                    partShape.Part.WithLabel(t.Label),
                                    out adjacent))
                            {
                                continue;
                            }

                            Debug.Assert(adjacent.Value != null, "adjacent.Value != null");
                            if (adjacent.Value.ShapeTemplate != shape.Template)
                            {
                                continue;
                            }

                            label     = adjacent.Label;
                            transform = EdgePartPosition.Create(adjacent.Value, shape)
                                        .GetTransformTo(t.GetEdgePartPosition(partShape.Part));
                        }

                        if (label != null)
                        {
                            break;
                        }
                    }

                    if (label == null)
                    {
                        throw new InvalidDataException();
                    }
                }

                EdgePartShape[] partShapes = shape.Template.EdgeParts[tilingDefinition]
                                             .Select(
                    ep => new EdgePartShape(
                        ep,
                        shapes.GetEdge(ep.EdgePattern.EdgeName),
                        shapeLines.GetOrAdd(ep.PartShapeID, _ => ShapeLines.CreateDefault())))
                                             .ToArray();

                Tile tile = new Tile(label, shape, transform, partShapes);
                tile.Style = styleManager.GetStyle(tile);
                tiles.Add(tile);
            }

            return(new Tiling(this, tilingDefinition, tiles, styleManager));
        }
コード例 #4
0
        /// <summary>
        ///     Gets the matrix that transforms the part at this position to another position.
        /// </summary>
        /// <param name="other">The other.</param>
        /// <returns></returns>
        /// <exception cref="System.InvalidOperationException">
        ///     The method has been called on a default instance of the <see cref="EdgePartPosition" /> struct.
        /// </exception>
        /// <exception cref="System.ArgumentException">The other edge part has not been set.</exception>
        public Matrix3x2 GetTransformTo(EdgePartPosition other)
        {
            if (Part == null) throw new InvalidOperationException("Edge part not set.");
            if (other.Part == null) throw new ArgumentException("Other edge part not set.", nameof(other));

            bool isClockwise = Part.IsClockwise;
            bool otherIsClockwise = other.Part.IsClockwise;

            Vector2 fromStart = isClockwise ? Start : End;
            Vector2 fromEnd = isClockwise ? End : Start;
            Vector2 toStart = otherIsClockwise ? other.Start : other.End;
            Vector2 toEnd = otherIsClockwise ? other.End : other.Start;

            Matrix3x2 transform = Matrix.GetTransform(fromStart, fromEnd, toStart, toEnd);

            if (isClockwise == otherIsClockwise)
                transform *= Matrix.CreateReflection(toStart, toEnd);

            return transform;
        }