public IEnumerable<Constraint> GetConstraints(Dictionary<string, Part> parts, IEnumerable<Bitmap> positives, IEnumerable<Bitmap> negatives) { List<Constraint> constraints = new List<Constraint>(); Constraint topSymmetricToBottom = new Constraint(SameEdgeDepth, parts["top"], parts["bottom"]); constraints.Add(topSymmetricToBottom); Constraint leftSymmetricToRight = new Constraint(SameEdgeDepth, parts["left"], parts["right"]); constraints.Add(leftSymmetricToRight); Constraint topLeftAdjacentToTopRegion = new Constraint(RegionStartEqualsWidth, parts["topleft"], parts["top"]); constraints.Add(topLeftAdjacentToTopRegion); Constraint topRightAdjacentToTopRegion = new Constraint(RegionEndEqualsWidth, parts["top"], parts["topright"]); constraints.Add(topRightAdjacentToTopRegion); Constraint bottomLeftAdjacentToBottomRegion = new Constraint(RegionStartEqualsWidth, parts["bottom"], parts["bottomleft"]); constraints.Add(bottomLeftAdjacentToBottomRegion); Constraint bottomRightAdjacentToBottomRegion = new Constraint(RegionEndEqualsWidth, parts["bottomright"], parts["bottom"]); constraints.Add(bottomRightAdjacentToBottomRegion); Constraint topLeftAdjacentToLeftRegion = new Constraint(RegionStartEqualsHeight, parts["left"], parts["bottomleft"]); constraints.Add(topLeftAdjacentToLeftRegion); Constraint bottomLeftAdjacentToLeftRegion = new Constraint(RegionEndEqualsHeight, parts["bottomleft"], parts["left"]); constraints.Add(bottomLeftAdjacentToLeftRegion); Constraint topRightAdjacentToRightRegion = new Constraint(RegionStartEqualsHeight, parts["topright"], parts["right"]); constraints.Add(topRightAdjacentToRightRegion); Constraint bottomRightAdjacentToRightRegion = new Constraint(RegionEndEqualsHeight, parts["right"], parts["bottomright"]); constraints.Add(bottomRightAdjacentToRightRegion); Constraint topLeftIsSquare = new Constraint(FeatureIsSquare, parts["topleft"], parts["topleft"]); constraints.Add(topLeftIsSquare); Constraint topRightIsSquare = new Constraint(FeatureIsSquare, parts["topright"], parts["topright"]); constraints.Add(topRightIsSquare); Constraint bottomRightIsSquare = new Constraint(FeatureIsSquare, parts["bottomright"], parts["bottomright"]); constraints.Add(bottomRightIsSquare); Constraint bottomLeftIsSquare = new Constraint(FeatureIsSquare, parts["bottomleft"], parts["bottomleft"]); constraints.Add(bottomLeftIsSquare); Constraint topLeftTopRightSameSize = new Constraint(PartsAreSameSizeOrZero, parts["topleft"], parts["topright"]); constraints.Add(topLeftTopRightSameSize); Constraint topRightBottomRightSameSize = new Constraint(PartsAreSameSizeOrZero, parts["topright"], parts["bottomright"]); constraints.Add(topRightBottomRightSameSize); Constraint bottomRightBottomLeftSameSize = new Constraint(PartsAreSameSizeOrZero, parts["bottomright"], parts["bottomleft"]); constraints.Add(bottomRightBottomLeftSameSize); Constraint bottomLeftTopLeftSameSize = new Constraint(PartsAreSameSizeOrZero, parts["bottomleft"], parts["topleft"]); constraints.Add(bottomLeftTopLeftSameSize); Constraint topIsLessThanOrEqualToHeight = new Constraint(DepthIsSmallHeight, parts["topleft"], parts["top"]); constraints.Add(topIsLessThanOrEqualToHeight); Constraint bottomIsLessThanOrEqualToHeight = new Constraint(DepthIsSmallHeight, parts["bottomleft"], parts["bottom"]); constraints.Add(bottomIsLessThanOrEqualToHeight); Constraint leftIsLessThanOrEqualToWidth = new Constraint(DepthIsSmallWidth, parts["left"], parts["topleft"]); constraints.Add(leftIsLessThanOrEqualToWidth); Constraint rightIsLessThanOrEqualToWidth = new Constraint(DepthIsSmallWidth, parts["right"], parts["topright"]); constraints.Add(rightIsLessThanOrEqualToWidth); Constraint topStartEqualsEnd = new Constraint(RegionStartEqualsEnd, parts["top"], parts["top"]); constraints.Add(topStartEqualsEnd); Constraint bottomStartEqualsEnd = new Constraint(RegionStartEqualsEnd, parts["bottom"], parts["bottom"]); constraints.Add(bottomStartEqualsEnd); Constraint leftStartEqualsEnd = new Constraint(RegionStartEqualsEnd, parts["left"], parts["left"]); constraints.Add(leftStartEqualsEnd); Constraint rightStartEqualsEnd = new Constraint(RegionStartEqualsEnd, parts["right"], parts["right"]); constraints.Add(rightStartEqualsEnd); return constraints; }
/// <summary> /// Given a constraint, it removes the values from any variables /// that do not satisify the constraint. /// </summary> /// <param name="constraint">The constraint to apply</param> /// <returns>True if any values were removed</returns> private bool RemoveInconsistentValues(Constraint constraint, bool useCurrentValidValues) { bool removed = false; ArrayList toRemove = new ArrayList(); ArrayList constraintValues = constraint.Part1.CurrentValidValues; ArrayList correspondingValues = constraint.Part2.CurrentValidValues; if (!useCurrentValidValues) { constraintValues = constraint.Part1.AllValues; correspondingValues = constraint.Part2.AllValues; } foreach (object value in constraintValues) { if (NoValueSatisfies(constraint, value, correspondingValues)) { toRemove.Add(value); removed = true; } } foreach (object rm in toRemove) constraintValues.Remove(rm); return removed; }
/// <summary> /// Returns true if there is no such value v2 in the /// given consraint that allow the constraint {v1,v2} to be true. /// </summary> /// <param name="constraint">Constraint to check</param> /// <param name="v1">Value to satisfy</param> /// <returns>True if nothing satisfies v1</returns> private bool NoValueSatisfies(Constraint constraint, object v1, IEnumerable values) { foreach (object v2 in values) { if (constraint.Satisfied(v1, v2)) { return false; } } return true; }
/// <summary> /// Returns a list of constraints with the given variable. /// </summary> /// <param name="var">Variable to check for in each constraint</param> /// <param name="excludeThisConstraint">A constraint to ignore</param> /// <param name="constraints">List of constraints to check</param> /// <returns>The constraints that have var as a variable, excluding excludeThisConstraint</returns> private IEnumerable<Constraint> ConstraintsWith(Part part, Constraint excludeThisConstraint, IEnumerable<Constraint> constraints) { List<Constraint> toReturn = new List<Constraint>(); foreach (Constraint c in constraints) { if ((c.Part1 == part || c.Part2 == part) && c != excludeThisConstraint) { toReturn.Add(c); } //else if (c.Part2 == part && c != excludeThisConstraint) //{ // toReturn.Add(c); // //Constraint reverse = Reverse(constraints, c); // //if(reverse != excludeThisConstraint) // // toReturn.Add(reverse); //} } return toReturn; }