Example #1
0
        /// <summary>
        /// Add a connection to the database.  Must not already exist in DB.
        /// </summary>
        /// <param name="connection">The connection to be added.</param>
        public void addConnection(RenderedConnection connection)
        {
            if (connection.inDB_)
            {
                throw new Exception("Connection already in database.");
            }
            if (connection.getSourceBlock().isInFlyout)
            {
                // Don't bother maintaining a database of connections in a flyout.
                return;
            }
            var position = this.findPositionForConnection_(connection);

            this.array_.Splice(position, 0, connection);
            connection.inDB_ = true;
        }
Example #2
0
        /// <summary>
        /// Find the closest compatible connection to this connection.
        /// </summary>
        /// <param name="conn">The connection searching for a compatible
        /// mate.</param>
        /// <param name="maxRadius">The maximum radius to another connection.</param>
        /// <param name="dxy">Offset between this connection's location
        /// in the database and the current location (as a result of dragging).</param>
        /// <returns>Contains two properties:' connection' which is either another connection or null,
        /// and 'radius' which is the distance.</returns>
        public RenderedConnection.Closest searchForClosest(RenderedConnection conn, double maxRadius,
                                                           goog.math.Coordinate dxy)
        {
            // Don't bother.
            if (this.array_.Length == 0)
            {
                return(new RenderedConnection.Closest {
                    connection = null, radius = maxRadius
                });
            }

            // Stash the values of x and y from before the drag.
            var baseY = conn.y_;
            var baseX = conn.x_;

            conn.x_ = baseX + dxy.x;
            conn.y_ = baseY + dxy.y;

            // findPositionForConnection finds an index for insertion, which is always
            // after any block with the same y index.  We want to search both forward
            // and back, so search on both sides of the index.
            var closestIndex = this.findPositionForConnection_(conn);

            Connection         bestConnection = null;
            var                bestRadius     = maxRadius;
            RenderedConnection temp;

            // Walk forward and back on the y axis looking for the closest x,y point.
            var pointerMin = closestIndex - 1;

            while (pointerMin >= 0 && this.isInYRange_(pointerMin, conn.y_, maxRadius))
            {
                temp = this.array_[pointerMin];
                if (conn.isConnectionAllowed(temp, bestRadius))
                {
                    bestConnection = temp;
                    bestRadius     = temp.distanceFrom(conn);
                }
                pointerMin--;
            }

            var pointerMax = closestIndex;

            while (pointerMax < this.array_.Length && this.isInYRange_(pointerMax, conn.y_,
                                                                       maxRadius))
            {
                temp = this.array_[pointerMax];
                if (conn.isConnectionAllowed(temp, bestRadius))
                {
                    bestConnection = temp;
                    bestRadius     = temp.distanceFrom(conn);
                }
                pointerMax++;
            }

            // Reset the values of x and y.
            conn.x_ = baseX;
            conn.y_ = baseY;

            // If there were no valid connections, bestConnection will be null.
            return(new RenderedConnection.Closest {
                connection = bestConnection, radius = bestRadius
            });
        }
Example #3
0
        /// <summary>
        /// Find all nearby connections to the given connection.
        /// Type checking does not apply, since this function is used for bumping.
        /// </summary>
        /// <param name="connection">The connection whose neighbours
        /// should be returned.</param>
        /// <param name="maxRadius">The maximum radius to another connection.</param>
        /// <returns>List of connections.</returns>
        public Connection[] getNeighbours(RenderedConnection connection, double maxRadius)
        {
            var db       = this.array_;
            var currentX = connection.x_;
            var currentY = connection.y_;

            // Binary search to find the closest y location.
            var pointerMin = 0;
            var pointerMax = db.Length - 2;
            var pointerMid = pointerMax;

            while (pointerMin < pointerMid)
            {
                if (db[pointerMid].y_ < currentY)
                {
                    pointerMin = pointerMid;
                }
                else
                {
                    pointerMax = pointerMid;
                }
                pointerMid = (int)System.Math.Floor((pointerMin + pointerMax) / 2.0);
            }

            var neighbours = new JsArray <Connection>();

            /**
             * Computes if the current connection is within the allowed radius of another
             * connection.
             * This function is a closure and has access to outside variables.
             * @param {number} yIndex The other connection's index in the database.
             * @return {boolean} True if the current connection's vertical distance from
             *     the other connection is less than the allowed radius.
             */
            var checkConnection_ = new Func <int, bool>((yIndex) => {
                var dx = currentX - db[yIndex].x_;
                var dy = currentY - db[yIndex].y_;
                var r  = System.Math.Sqrt(dx * dx + dy * dy);
                if (r <= maxRadius)
                {
                    neighbours.Push(db[yIndex]);
                }
                return(dy < maxRadius);
            });

            // Walk forward and back on the y axis looking for the closest x,y point.
            pointerMin = pointerMid;
            pointerMax = pointerMid;
            if (db.Length != 0)
            {
                while (pointerMin >= 0 && checkConnection_(pointerMin))
                {
                    pointerMin--;
                }
                do
                {
                    pointerMax++;
                } while (pointerMax < db.Length && checkConnection_(pointerMax));
            }

            return(neighbours);
        }