/// <summary>
        /// Creates a single EndPointPainter.
        ///
        /// Helper function.
        /// </summary>
        /// <param name="w">The endpoint to paint</param>
        /// <returns>A new EndPointPainter</returns>
        private EndPointPainter createEndpointPainter(Sketch.EndPoint endpoint)
        {
            // Create painter
            EndPointPainter epp = new EndPointPainter(endpoint, sketchPanel.InkCanvas);

            // Set painter type
            if (!endpoint.IsConnected)
            {
                epp.Type = EndPointPainter.EndPointType.Unconnected;
            }
            else if (Domain.LogicDomain.IsGate(endpoint.ConnectedShape.Type))
            {
                epp.Type = EndPointPainter.EndPointType.ConnectedToSymbol;
            }
            else if (Domain.LogicDomain.IsText(endpoint.ConnectedShape.Type))
            {
                epp.Type = EndPointPainter.EndPointType.ConnectedToLabel;
            }
            else if (Domain.LogicDomain.IsWire(endpoint.ConnectedShape.Type))
            {
                epp.Type = EndPointPainter.EndPointType.ConnectedToWire;
            }
            else
            {
                epp.Type = EndPointPainter.EndPointType.UnknownConnection;
            }

            return(epp);
        }
Exemple #2
0
 /// <summary>
 /// Constructor
 /// </summary>
 public EndPoint(Sketch.EndPoint endpoint, bool isEnd)
 {
     m_Stroke            = endpoint.ParentSub;
     m_End               = isEnd;
     m_Pt                = endpoint;
     m_AttachedEndpoints = new List <EndPoint>();
 }
        /// <summary>
        /// Look at a particular shape's orientation angle (relative to horizontal)
        /// and correct it if necessary.
        ///
        /// Note: Although the image recognizer gives an orientation angle,
        /// we are not using it. Originally, we did use it, then calculated a new
        /// orientation angle using wire slopes. The new orientation angle replaced
        /// the original angle unless they were close to each other. However,
        /// now we've commented that out and are using only the wire slopes.
        ///
        /// Actually, we do use image recognizer orientation angle, but only
        /// for NOT gates, since both sides of NOT gates have one wire.
        /// </summary>
        /// <param name="shape1">The shape to check.</param>
        /// <param name="sketch">The sketch containing the shape.</param>
        public override void OrientShape(Sketch.Shape shape, Sketch.Sketch sketch)
        {
            if (shape.Classification == LogicDomain.GATE_CLASS && shape.Type != LogicDomain.NOT)
            {
                // The gate's angle based on it's connected wires.
                double connectionsAngle  = 0;
                double numConnectedWires = 0;

                // Check the slope orientation of adjacent wires
                foreach (Sketch.Shape connectedShape in shape.ConnectedShapes)
                {
                    if (connectedShape.Type.Classification == LogicDomain.WIRE_CLASS)
                    {
                        Sketch.EndPoint endpoint = shape.ClosestEndpointFrom(connectedShape);
                        double          slope    = endpoint.Slope;
                        // negated since our y-axis is inverted.
                        connectionsAngle -= Math.Atan(Math.Abs(slope));
                        numConnectedWires++;
                    }
                }

                // Get the average angle
                connectionsAngle = connectionsAngle / numConnectedWires;

                //// Check if the two angles are close enough
                //if (Math.Abs(orientationAngle - connectionsAngle) % Math.PI < CLOSE_ENOUGH ||
                //    Math.PI % Math.Abs(orientationAngle - connectionsAngle) < CLOSE_ENOUGH)
                //    shape.Orient = shape.Orient; // Don't change anything.
                //else
                //    // Use the connections rather than the template rotation angle
                //    shape.Orient = connectionsAngle;

                shape.Orientation = connectionsAngle;
            }
        }
Exemple #4
0
        /// <summary>
        /// Determine a shape's orientation based on the angles of incoming and outgoing
        /// wires. This method is highly reliable (numerous user studies have shown that
        /// users don't draw wires coming into a gate at meaningless orientations), but
        /// it is sometimes off by 180 degrees (by which I mean Pi, since we are working
        /// in radians).
        ///
        /// NOTE: Currently, this code is not used. HOWEVER, it is extremely reliable. Often
        /// moreso than the orientation obtained from the image recognizer. The refiner should
        /// be able to use this information.
        /// </summary>
        /// <param name="shape1">The shape to check.</param>
        /// <param name="sketch">The sketch containing the shape.</param>
        public override double OrientShape(Sketch.Shape shape, Sketch.Sketch sketch)
        {
            if (shape.Classification == LogicDomain.GATE_CLASS)
            {
                // The gate's angle based on its connected wires.
                double connectionsAngle  = 0;
                double numConnectedWires = 0;

                // Check the slope orientation of adjacent wires
                foreach (Sketch.Shape connectedShape in shape.ConnectedShapes)
                {
                    if (connectedShape.Type.Classification == LogicDomain.WIRE_CLASS)
                    {
                        Sketch.EndPoint endpoint = shape.ClosestEndpointFrom(connectedShape);
                        double          slope    = endpoint.Slope;
                        // negated since our y-axis is inverted (positive-y is down)
                        connectionsAngle -= Math.Atan(Math.Abs(slope));
                        numConnectedWires++;
                    }
                }

                // Get the average angle
                connectionsAngle = connectionsAngle / numConnectedWires;

                // Connections angle is currently in the range [-Pi, Pi], so add Pi
                return(connectionsAngle + Math.PI);
            }
            return(0);
        }
Exemple #5
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 <Shape> inputWires  = new List <Shape>();
            List <Shape> outputWires = new List <Shape>();

            int maxOutputs = _domain.NumberOutputs(gate.Type).Max;

            // Cycle through everything connected to the gate's associated
            // shape and categorize their connection type accordingly
            foreach (Sketch.Shape connectedShape in gate.Shape.ConnectedShapes)
            {
                // We'll take care of the not bubbles when they come up seprately
                if (connectedShape.Type == LogicDomain.NOTBUBBLE)
                {
                    continue;
                }
                // If it's not a wire or a not bubble, something is wrong
                else if (!Domain.LogicDomain.IsWire(connectedShape.Type))
                {
                    throw new Exception("Gate " + gate + " was connected to non-wire, non-notbubble shape " + connectedShape);
                }

                Sketch.EndPoint connectingEndpoint =
                    gate.Shape.ClosestEndpointFrom(connectedShape);

                if (gate.ShouldBeInput(connectingEndpoint))
                {
                    inputWires.Add(connectedShape);
                }
                else
                {
                    outputWires.Add(connectedShape);
                }
            }

            // Make the connections.
            foreach (Shape wire in inputWires)
            {
                WireMesh inputWire = _wireMeshes[wire];
                gate.ConnectInput(inputWire);
            }
            foreach (Shape wire in outputWires)
            {
                WireMesh outputWire = _wireMeshes[wire];
                gate.ConnectOutput(outputWire);
            }
            gate.ConnectAllInputs();
            gate.ConnectAllOutputs();
        }
        /// <summary>
        /// Allows the user to connect shapes by dragging a connection
        /// Stylus up connects the wire to the nearest target
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void InkCanvas_StylusUp(object sender, StylusEventArgs e)
        {
            if (debug)
            {
                Console.WriteLine("Endpoint stylus up recieved.");
            }

            // If no point has been clicked, return
            if (clickedIndex == null)
            {
                return;
            }

            EndPointPainter clickedPoint;

            endPointPainterMap.TryGetValue((int)clickedIndex, out clickedPoint);

            // Check if there are strokes close-by
            Sketch.EndPoint           oldLocation      = clickedPoint.EPoint;
            System.Windows.Point      oldLocationPoint = new System.Windows.Point(oldLocation.X, oldLocation.Y);
            System.Windows.Point      newLocation      = e.GetPosition(sketchPanel.InkCanvas);
            System.Windows.Ink.Stroke attachedStroke   = sketchPanel.InkSketch.GetInkStrokeBySubstroke(clickedPoint.EPoint.ParentSub);

            // Find the shape that the endpoint was dragged to
            // You can't connect a wire to itself!
            Shape closest = sketchPanel.Sketch.shapeAtPoint(newLocation.X, newLocation.Y, 10, clickedPoint.EPoint.ParentShape);

            if (closest != null && attachedStroke != null) //&& !clickedPoint.EPoint.IsConnected)
            {
                clickedPoint.Clear();
                clickedPoint.PointShape = null;
                endPointPainterMap.Remove((int)clickedIndex);

                // pass the endpoint moved event to the display manager
                endPointMoved(oldLocation, newLocation, attachedStroke, closest);
            }
            else
            {
                clickedPoint.ResetMove();
            }
            clickedPoint.PaintMe();

            // Reset the clickedIndex and the editing mode
            sketchPanel.EnableDrawing();
            clickedIndex = null;
        }
Exemple #7
0
        /// <summary>
        /// Connects not bubbles to gates and wires
        /// </summary>
        /// <param name="gate"></param>
        private void connectNotBubble(LogicGate bubble)
        {
            LogicGate parentGate = null;
            WireMesh  wire       = null;

            // Get the components this not bubble is connected to
            foreach (Shape connected in bubble.Shape.ConnectedShapes)
            {
                if (LogicDomain.IsGate(connected.Type) && parentGate == null)
                {
                    parentGate = _logicGates[connected];
                }
                else if (LogicDomain.IsWire(connected.Type))
                {
                    wire = _wireMeshes[connected];
                }
            }

            // If this is not connected to a gate, connect it like a normal logic gate
            if (parentGate == null)
            {
                connectWiresTo(bubble);
                return;
            }

            // Is this bubble on the output or the input?
            Sketch.EndPoint connectingEndpoint =
                parentGate.Shape.ClosestEndpointFrom(bubble.Shape);
            bool isInput = parentGate.ShouldBeInput(connectingEndpoint);

            if (isInput)
            {
                wire.ConnectDependent(bubble);
                parentGate.ConnectInput(bubble, 0);
            }
            else
            {
                wire.ConnectSource(bubble, 0);
                parentGate.ConnectOutput(bubble, 0);
            }
        }