/// <summary> /// Compares two endpoints on the basis of the Y value /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> public int EndpointSort(Sketch.EndPoint a, Sketch.EndPoint b) { // Get the y-coordinate the first endpoint would have if this component was // rotated about the origin until it was perfectly horizontal, // pointing left to right. double aY = a.Y * Math.Cos(Shape.Orientation) + a.X * Math.Sin(Shape.Orientation); // Get the y-coordinate of the second endpoint if it underwent // the same transformation. double bY = b.Y * Math.Cos(Shape.Orientation) + b.X * Math.Sin(Shape.Orientation); if (aY < bY) { return(-1); } else if (aY > bY) { return(1); } return(0); }
/// <summary> /// Compares two wires on the basis of the Y value of the endpoint that connects to this gate /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> public int WireSort(WireMesh a, WireMesh b) { Sketch.EndPoint aEnd = Shape.ClosestEndpointFrom(a.Shape); Sketch.EndPoint bEnd = Shape.ClosestEndpointFrom(b.Shape); return(EndpointSort(aEnd, bEnd)); }
/// <summary> /// Figures out everything a given logic gate should be /// connected to, and connects them appropriately. /// /// Assumption: Every wire-mesh has a unique name. /// /// Note: this currently only deals with connections to wires. /// Hence, it does not make any connections for notbubbles yet. /// </summary> /// <param name="gate">The gate to connect</param> private void connectWiresTo(LogicGate gate) { // We keep track of what wire-meshes are inputs and outputs // so we can do sanity checks before actually connecting // them to the logic gate. List <string> inputWires = new List <string>(); List <string> outputWires = new List <string>(); int maxOutputs = LogicDomain.MaxOutputs(gate.Type); // Cycle through everything connected to the gate's associated // shape and categorize their connection type accordingly foreach (Sketch.Shape connectedShape in gate.Shape.ConnectedShapes) { if (!Domain.LogicDomain.IsWire(connectedShape.Type)) { throw new Exception("Gate " + gate + " was connected to non-wire shape " + connectedShape); } Sketch.EndPoint connectingEndpoint = gate.Shape.ClosestEndpointFrom(connectedShape); if (gate.ShouldBeInput(connectingEndpoint)) { inputWires.Add(connectedShape.Name); } else { outputWires.Add(connectedShape.Name); } } // If it looks like we mixed up the output and input wires, // swap them so they're more correct (this can happen if the // gate's orientation was recognized in the wrong direction) if ((outputWires.Count > maxOutputs) && (inputWires.Count <= maxOutputs)) { swap(ref outputWires, ref inputWires); } // Make the connections. foreach (string wireName in inputWires) { WireMesh inputWire = _wireMeshes[wireName]; gate.ConnectInput(inputWire); } foreach (string wireName in outputWires) { WireMesh outputWire = _wireMeshes[wireName]; gate.ConnectOutput(outputWire); } gate.ConnectAllInputs(); gate.ConnectAllOutputs(); }
/// <summary> /// Compares two wires on the basis of the Y value of the endpoint that connects to this gate /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> public int WireSort(WireMesh a, WireMesh b) { Sketch.EndPoint aEnd = Shape.ClosestEndpointFrom(a.Shape); Sketch.EndPoint bEnd = Shape.ClosestEndpointFrom(b.Shape); if (aEnd.Y < bEnd.Y) { return(-1); } else if (aEnd.Y > bEnd.Y) { return(1); } return(0); }
private void loadEndpoints() { // Here we make a bunch of assertions about what must be true. // It is the responsibility of CircuitDomain to set these. // For every connected shape, there is an endpoint connected to it. foreach (Sketch.Shape shape in _associatedShape.ConnectedShapes) { bool found = false; Sketch.EndPoint theEndpoint = null; foreach (Sketch.EndPoint endpoint in _associatedShape.Endpoints) { if (endpoint.ConnectedShape == shape) { found = true; theEndpoint = endpoint; break; } } myAssert(found); } // For every endpoint, if it is connected to a shape, that shape is in the list of connected shapes foreach (Sketch.EndPoint endpoint in _associatedShape.Endpoints) { if (endpoint.ConnectedShape != null) { myAssert(_associatedShape.ConnectedShapes.Contains(endpoint.ConnectedShape)); } } // Any connected wires should have been merged by now foreach (Sketch.Shape shape in _associatedShape.ConnectedShapes) { if (shape != _associatedShape) { myAssert(shape.Type != Domain.LogicDomain.WIRE); } } // Every endpoint should be in _endPoints _endPoints = new HashSet <Sketch.EndPoint>(); foreach (Sketch.EndPoint endpoint in _associatedShape.Endpoints) { _endPoints.Add(endpoint); } }
/// <summary> /// Determines whether a given endpoint of a wire would connect /// to the invoking logic gate as an input or output. /// /// Precondition: the underlying shape has a valid Orientation /// </summary> /// <param name="wireEnd">The wire endpoint to analyze</param> /// <returns>True if the endpoint would be an input, /// false if it would be an output</returns> public bool ShouldBeInput(Sketch.EndPoint wireEnd) { // Get the x-coordinate the logic gate would have if it were // rotated about the origin until it was perfectly horizontal, // pointing left to right. double adjGateCenterX = Shape.Centroid.X * Math.Cos(Shape.Orientation) + Shape.Centroid.Y * Math.Sin(Shape.Orientation); // Get the x-coordinate of the wire endpoint if it underwent // the same transformation. double adjWireEndX = wireEnd.X * Math.Cos(Shape.Orientation) + wireEnd.Y * Math.Sin(Shape.Orientation); // Determine whether the wire endpoint is to the left or right // of the gate's center, which likewise corresponds to whether // it's an input or output. return(adjGateCenterX > adjWireEndX); }
/// <summary> /// Constructor /// </summary> /// <param name="sketch">SketchPanel to add a label to</param> /// <param name="inkStrokes">InkOverlay strokes</param> /// <param name="inkStrokes">A StrokeCollection strokes</param> /// <param name="label">Label to apply</param> /// <param name="domainInfo">DomainInfo for our Labeler</param> public EndPointMoveCmd(InkToSketchWPF.InkCanvasSketch inkSketch, Sketch.EndPoint oldLoc, Point newLoc, Stroke attachedStroke, Sketch.Shape shapeAtNewLoc) { isUndoable = true; this.inkSketch = inkSketch; oldLocation = oldLoc; newLocation = newLoc; this.attachedStroke = attachedStroke; this.shapeAtNewLoc = shapeAtNewLoc; this.changedShape = inkSketch.GetSketchSubstrokeByInk(attachedStroke).ParentShape; oldInternalConnection = changedShape.ConnectedShapes.Contains(changedShape); newIsWire = Domain.LogicDomain.IsWire(shapeAtNewLoc.Type); substrokesInNewShape = shapeAtNewLoc.SubstrokesL; // Make a new stroke comprising 100 points along the straight line between oldLocation and newLocation System.Windows.Input.StylusPointCollection line = new System.Windows.Input.StylusPointCollection(); for (double m = 0; m <= 1; m += 0.01) { double midX = oldLocation.X + m * (newLocation.X - oldLocation.X); double midY = oldLocation.Y + m * (newLocation.Y - oldLocation.Y); line.Add(new System.Windows.Input.StylusPoint(midX, midY)); } this.newStroke = new Stroke(line); }