/// <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;
            }
        }
示例#2
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);
        }
示例#3
0
 /// <summary>
 /// Get the closest endpoint from this shape to the given shape.
 /// </summary>
 /// <param name="othershape">The shape to compare to</param>
 /// <returns>The closest endpoint in otherShape</returns>
 public EndPoint ClosestEndpointTo(Shape othershape)
 {
     return(othershape.ClosestEndpointFrom(this));
 }
        /// <summary>
        /// Connects the given shape to the other shapes in the sketch.
        ///
        /// Postcondition:
        ///     If the shape is a wire, the following things are true:
        ///       - For every substroke in the wire, both endpoints are connected to the closest shape
        ///       - The shapes the endpoints are connected to are also in the list of connected shapes
        ///       - The shapes that the wire is  connected to also know they are connected to the wire
        ///     If the shape is a NOTBUBBLE
        ///       - It is connected to the two closest shapes??
        /// </summary>
        /// <param name="shape">The shape to check.</param>
        /// <param name="sketch">The sketch containing the shape.</param>
        public override void ConnectShape(Sketch.Shape shape, Sketch.Sketch sketch)
        {
            if (!sketch.ShapesL.Contains(shape))
            {
                throw new ArgumentException("The given shape " + shape + " is not in the given sketch!");
            }

            // Connect wires to adjacent shapes
            if (shape.Type == LogicDomain.WIRE)
            {
                foreach (Sketch.Substroke substroke in shape.Substrokes)
                {
                    // Find the shape closest to the start point of the wire
                    Shape shape2 = findClosest(true, substroke, sketch);
                    if (shape2 != null)
                    {
                        EndPoint start = substroke.Endpoints[0];
                        if (!start.IsConnected)
                        {
                            sketch.connectShapes(shape, shape2);
                            start.ConnectedShape = shape2;
                        }
                    }

                    // Find the shape closest to the end point of the wire
                    Shape shape3 = findClosest(false, substroke, sketch);
                    if (shape3 != null)
                    {
                        EndPoint end = substroke.Endpoints[1];
                        if (!end.IsConnected)
                        {
                            sketch.connectShapes(shape, shape3);
                            end.ConnectedShape = shape3;
                        }
                    }
                }
            }

            // Connect NotBubbles to its two closest shapes.
            // FIXME: This could potentially cause problems. For instance,
            // on the off chance that one of the closest shapes was a wire
            // whose connections were already figured out, this could leave
            // the wire in an inconsistent state.
            else if (shape.Type == LogicDomain.NOTBUBBLE)
            {
                List <Sketch.Shape> shapes = twoClosest(shape, sketch);

                foreach (Shape closeShape in shapes)
                {
                    if (closeShape == null)
                    {
                        continue;
                    }

                    // FIXME: For now, we're only connecting this notbubble to a wire if that wire's closest endpoint is free.
                    if (closeShape.Type == LogicDomain.WIRE)
                    {
                        EndPoint endpoint = shape.ClosestEndpointFrom(closeShape);
                        if (!endpoint.IsConnected)
                        {
                            closeShape.ConnectNearestEndpointTo(shape);
                        }
                    }
                    else
                    {
                        sketch.connectShapes(closeShape, shape);
                    }
                }
            }
        }