예제 #1
0
        /// <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);
        }
예제 #2
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));
        }
예제 #3
0
        /// <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();
        }
예제 #4
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);

            if (aEnd.Y < bEnd.Y)
            {
                return(-1);
            }
            else if (aEnd.Y > bEnd.Y)
            {
                return(1);
            }
            return(0);
        }
예제 #5
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);
            }
        }
예제 #6
0
        /// <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);
        }
예제 #7
0
        /// <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);
        }