/// <summary> /// Connector constructor /// </summary> /// <param name="name">Name of the connector.</param> /// <param name="positions">List of positions of the connector, can be empty.</param> /// <param name="glue">Glue of the connector.</param> /// <param name="angle">Angle of the connector.</param> /// <param name="resistance">Resistance of the connector.</param> /// <exception cref="ArgumentException"> /// If name is null or empty string or if list of positions is null or if Glue is null. /// </exception> public Connector(string name, IList <Point3D> positions, Glue glue, Angle angle, double resistance = 0) : base(name) { if (positions == null) { throw new ArgumentException($"Positions of the connector {name} can't be null."); } if (glue == null) { throw new ArgumentException($"Glue of the connector {name} can't be null."); } Glue = glue; Angle = angle; Resistance = resistance; switch (positions.Count) { case 0: throw new ArgumentException($"Position of the connector {name} is undefined."); case 1: Positions = new ReadOnlyCollection <Point3D>(positions); break; case 2: Positions = new Segment3D(positions[0], positions[1], name); // Checks the distance of endpoints break; default: throw new ArgumentException($"Connector {name} can't have more than two vertices."); } }
/// <summary> /// Returns a pair of facet connectors at distinct positions on "tile" which match "glue1" and "glue2" in GlueRelation. /// If no such pair exist, then both returned connectors are null. /// TODO: check whether connectors are on opposite ends of the tile /// </summary> public Tuple <ConnectorOnTile, ConnectorOnTile> MatchingConectors(Tile tile, Glue glue1, Glue glue2) { ConnectorOnTile conn2 = null; var facetConnectors = tile.Connectors.Where(conn => conn.Positions.All(point => tile.Vertices.ContainsPoint(point))); var conn1 = facetConnectors.FirstOrDefault( connector1 => GlueRelation.MatchAsymmetric(glue1, connector1.Glue) && (conn2 = facetConnectors.FirstOrDefault( connector2 => !Geometry.Overlap(connector1.Positions, connector2.Positions) && GlueRelation.MatchAsymmetric(glue2, connector2.Glue))) != null); return(Tuple.Create(conn1, conn2)); }
/// <summary> /// Tile constructor. TODO low priority: separate constructor for vertices 1D, vertices 2D /// </summary> /// <param name="name">Name of the tile.</param> /// <param name="vertices">Vertices of the tile.</param> /// <param name="connectors">Connectors of the tile.</param> /// <param name="surfaceGlue">Surface glue of the tile.</param> /// <param name="proteins">Proteins of the tile.</param> /// <param name="color">Color of the tile (named if possible).</param> /// <param name="alpha">Alpha attribute of the color</param> /// <param name="alphaRatio">Tile resistor ratio, for cTAM tilings</param> public Tile(string name, IList <Point3D> vertices, IEnumerable <Connector> connectors, Glue surfaceGlue, IList <ProteinOnTile> proteins, Color color, int alpha = 255, double alphaRatio = 1) : base(name) { Vertices = CreateVertices(vertices, name); SurfaceGlue = surfaceGlue ?? new Glue("EmptyGlue"); Color = color; Alpha = alpha; AlphaRatio = alphaRatio; Proteins = new ReadOnlyCollection <ProteinOnTile>(proteins ?? new List <ProteinOnTile>()); foreach (var protein in Proteins) { if (!Vertices.ContainsPoint(protein.Position)) { throw new InvalidOperationException($"{protein} must be on the object {name}."); } } Connectors = new ReadOnlyCollection <ConnectorOnTile>(connectors?.Select(conn => new ConnectorOnTile(this, conn)).ToList() ?? new List <ConnectorOnTile>()); }
/// <summary> /// Checks whether a tile can be eventually inserted between two connectors with glue1 and glue2. /// </summary> /// <param name="tile"></param> /// <param name="glue1"></param> /// <param name="glue2"></param> private bool IsInsertable(Tile tile, Glue glue1, Glue glue2) { return(MatchingConectors(tile, glue1, glue2).Item2 != null); }
/// <summary> /// Initializes the key glue1 in the dictionary. /// Then adds the element keyed glue1, glue2 to the dictionary. /// </summary> private static void AddRulesToDictionary <T>(IDictionary <Glue, Dictionary <Glue, T> > dict, Glue glue1, Glue glue2, T element) { if (!dict.ContainsKey(glue1)) { dict[glue1] = new Dictionary <Glue, T>(); } dict[glue1][glue2] = element; }