Example #1
0
        public void DrawWhiteboardRoomObjects(WhiteboardRoom wbRoom, Canvas canvas)
        {
            if (wbRoom == null)
            {
                return;
            }

            // Draw all whiteboard commands
            Array drawingCommands = wbRoom.GetCurrentDrawingCommands();

            foreach (object obj in drawingCommands)
            {
                if (obj is LineObject)
                {
                    LineObject line = (LineObject)obj;
                    LocationValue start = new LocationValue();
                    LocationValue end = new LocationValue();
                    int drawPointSize = (int)(line.Width * _playfield.Scale);

                    if ((drawPointSize == 0) && (line.Width > 0))
                    {
                        drawPointSize = 1;
                    }

                    if ((line.Mode == DrawModes.Line) || (line.Mode == DrawModes.Circle) ||
                        (line.Mode == DrawModes.Arrow))
                    {
                        start.X = line.Start.X * _playfield.Scale + Map.Position.X;
                        start.Y = line.Start.Y * _playfield.Scale + Map.Position.Y;

                        end.X = line.End.X * _playfield.Scale + Map.Position.X;
                        end.Y = line.End.Y * _playfield.Scale + Map.Position.Y;

                        if (line.Mode == DrawModes.Line)
                        {
                            if ((line.Text != null) && (line.Text.Length > 0))
                            {
                                int lineTextSize = (int) ((LineTextSize / line.OriginalScale) * _playfield.Scale);

                                DrawShortenedLine(canvas, line.Color, drawPointSize, (float)start.X, (float)start.Y,
                                    (float)end.X, (float)end.Y, (float) (_playfield.Scale / line.OriginalScale));

                                if (lineTextSize > MaxFontSize)
                                {
                                    lineTextSize = MaxFontSize;
                                }
                                if (lineTextSize < 1)
                                {
                                    lineTextSize = 1;
                                }
                                if (wbFonts[lineTextSize] == null)
                                {
                                    wbFonts[lineTextSize] = canvas.CreateFont(new System.Drawing.Font("Arial", lineTextSize, FontStyle.Bold, GraphicsUnit.Pixel));
                                }
                                DrawCenteredText(wbFonts[lineTextSize], line.Text, (int)end.X, (int)end.Y, line.Color);
                            }
                            else
                            {
                                canvas.DrawLine(line.Color, drawPointSize, (float)start.X, (float)start.Y,
                                    (float)end.X, (float)end.Y);
                            }
                        }
                        else if (line.Mode == DrawModes.Circle)
                        {
                            canvas.DrawCircle(line.Color, drawPointSize, (float)start.X, (float)start.Y,
                                (float)end.X, (float)end.Y);
                        }
                        else if (line.Mode == DrawModes.Arrow)
                        {
                            canvas.DrawArrow(line.Color, drawPointSize, (float)start.X, (float)start.Y,
                                (float)end.X, (float)end.Y);
                        }
                    }
                    else if ((line.Mode == DrawModes.Text) && (line.Text != null) &&
                        (line.Text.Length > 0))
                    {
                        start.X = line.Start.X * _playfield.Scale + Map.Position.X;
                        start.Y = line.Start.Y * _playfield.Scale + Map.Position.Y;

                        if (drawPointSize > MaxFontSize)
                        {
                            drawPointSize = MaxFontSize;
                        }
                        if (wbFonts[drawPointSize] == null)
                        {
                            wbFonts[drawPointSize] = canvas.CreateFont(new System.Drawing.Font("Arial", drawPointSize, FontStyle.Bold, GraphicsUnit.Pixel));
                        }
                        DrawCenteredText(wbFonts[drawPointSize], line.Text, (int)start.X, (int)start.Y, line.Color);

                        // Update the bounding box if needed
                        if ((line.BoundingPolygon == null) || (wbRoom == WBRoom))
                        {
                            RectangleF textRect;
                            Polygon textPoly;
                            float width;
                            float height;
                            PointF boundStart = new PointF();

                            textRect = wbFonts[drawPointSize].MeasureString(null, line.Text, DrawTextFormat.None, line.Color);

                            width = textRect.Right / _playfield.Scale;
                            if ((width * line.OriginalScale) < 5)
                            {
                                width = 5 / (float) line.OriginalScale;
                            }
                            height = textRect.Bottom / _playfield.Scale;
                            if ((height * line.OriginalScale) < 5)
                            {
                                height = 5 / (float) line.OriginalScale;
                            }
                            boundStart.X = (float)line.Start.X - (width / 2);
                            boundStart.Y = (float)line.Start.Y - (height / 2);

                            textPoly = new Polygon();
                            textPoly.Points.Add(new Vector(boundStart.X, boundStart.Y));
                            textPoly.Points.Add(new Vector(boundStart.X + width, boundStart.Y));
                            textPoly.Points.Add(new Vector(boundStart.X + width, boundStart.Y + height));
                            textPoly.Points.Add(new Vector(boundStart.X, boundStart.Y + height));
                            textPoly.Offset(0, 0);
                            textPoly.BuildEdges();

                            line.BoundingPolygon = textPoly;
                        }
                    }

                    // Draw Bounding rectable if object is selected
                    if ((line.ObjectSelected) && (line.BoundingPolygon != null) && (line.BoundingPolygon.Points.Count >= 2))
                    {
                        LocationValue boundStart = new LocationValue();
                        LocationValue boundEnd = new LocationValue();
                        Vector prevPoint = line.BoundingPolygon.Points[line.BoundingPolygon.Points.Count - 1]; 
                        foreach (Vector curPoint in line.BoundingPolygon.Points)
                        {
                            boundStart.X = prevPoint.X * _playfield.Scale + Map.Position.X;
                            boundStart.Y = prevPoint.Y * _playfield.Scale + Map.Position.Y;

                            boundEnd.X = curPoint.X * _playfield.Scale + Map.Position.X;
                            boundEnd.Y = curPoint.Y * _playfield.Scale + Map.Position.Y;

                            canvas.DrawLine(Color.Black.ToArgb(), 1, (float)boundStart.X, (float)boundStart.Y,
                                (float)boundEnd.X, (float)boundEnd.Y);

                            prevPoint = curPoint;
                        }
                    }
                }
            }
        }
Example #2
0
        public void AddSelection(RectangleF selectionRect, bool areaSelection)
        {
            Polygon selectionPolygon = null;
            LineObject lineObject;
            PolygonCollisionResult result;
            LineObject prevSelectedObject = null;

            // Create Selection Polygon
            selectionPolygon = new Polygon();
            selectionPolygon.Points.Add(new Vector(selectionRect.Left, selectionRect.Top));
            selectionPolygon.Points.Add(new Vector(selectionRect.Right, selectionRect.Top));
            selectionPolygon.Points.Add(new Vector(selectionRect.Right, selectionRect.Bottom));
            selectionPolygon.Points.Add(new Vector(selectionRect.Left, selectionRect.Bottom));
            selectionPolygon.Offset(0, 0);
            selectionPolygon.BuildEdges();

            if (areaSelection)
            {
                // Select an area of objects
                lock (drawingCommandLock)
                {
                    foreach (Object command in drawingCommands)
                    {
                        if (command is LineObject)
                        {
                            lineObject = command as LineObject;

                            if ((lineObject.BoundingPolygon != null) && (lineObject.Mode != DrawModes.Circle))
                            {
                                result = PolygonCollision(lineObject.BoundingPolygon, selectionPolygon, new Vector(0, 0));
                                if ((result.Intersect) && (IsAllowedSelection(lineObject)))
                                {
                                    lineObject.ObjectSelected = true;
                                    numObjectsSelected++;
                                }
                            }
                            else if (lineObject.Mode == DrawModes.Circle)
                            {
                                if ((CircleSelectedByRect(lineObject, selectionRect)) && (IsAllowedSelection(lineObject)))
                                {
                                    lineObject.ObjectSelected = true;
                                    numObjectsSelected++;
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                // Select a single object
                if (numObjectsSelected > 1)
                {
                    ClearSelectionList();
                }
                else if (numObjectsSelected == 1)
                {
                    // Locate the previously selected object
                    lock (drawingCommandLock)
                    {
                        foreach (Object command in drawingCommands)
                        {
                            if ((command is LineObject) && ((LineObject) command).ObjectSelected)
                            {
                                prevSelectedObject = command as LineObject;
                                break;
                            }
                        }
                    }
                }

                LineObject selectedObject = null;
                LineObject firstSelectedObject = null;
                bool prevSelectionFound = false;

                lock (drawingCommandLock)
                {
                    foreach (Object command in drawingCommands)
                    {
                        if (command is LineObject)
                        {
                            bool objectSelected = false;
                            lineObject = command as LineObject;

                            if ((lineObject.BoundingPolygon != null) && (lineObject.Mode != DrawModes.Circle))
                            {
                                result = PolygonCollision(lineObject.BoundingPolygon, selectionPolygon, new Vector(0, 0));
                                if ((result.Intersect) && (IsAllowedSelection(lineObject)))
                                {
                                    objectSelected = true;
                                }
                            }
                            else if (lineObject.Mode == DrawModes.Circle)
                            {
                                if ((CircleSelectedByRect(lineObject, selectionRect)) && (IsAllowedSelection(lineObject)))
                                {
                                    objectSelected = true;
                                }
                            }

                            if (objectSelected)
                            {
                                if (firstSelectedObject == null)
                                {
                                    firstSelectedObject = lineObject;
                                }

                                if ((prevSelectionFound) && (lineObject != prevSelectedObject))
                                {
                                    selectedObject = lineObject;
                                    break;
                                }

                                if (lineObject == prevSelectedObject)
                                {
                                    selectedObject = lineObject;
                                    prevSelectionFound = true;
                                }
                            }
                        }
                    }
                }

                if ((selectedObject == prevSelectedObject) || (selectedObject == null))
                {
                    selectedObject = firstSelectedObject;
                }

                ClearSelectionList();

                if ((selectedObject != null) && (IsAllowedSelection(selectedObject)))
                {
                    selectedObject.ObjectSelected = true;
                    numObjectsSelected++;
                }
            }
        }
Example #3
0
        private void GetCircleBoundingPoly(float x1, float y1, float x2, float y2,
                                         float width, float originalScale,
                                         out Polygon boundingPolygon, out float outterRadius,
                                         out float innerRadius)
        {
            float minDist;

            width = width / 2;
            if ((width * originalScale) < 5)
            {
                minDist = 5 / originalScale;
            }
            else
            {
                minDist = width;
            }

            float radius = (float)Math.Sqrt(Math.Pow((double)Math.Abs(x1 - x2), 2) + Math.Pow((double)Math.Abs(y1 - y2), 2));
            radius += minDist;

            boundingPolygon = new Polygon();
            boundingPolygon.Points.Add(new Vector(x1 + radius, y1 - radius));
            boundingPolygon.Points.Add(new Vector(x1 + radius, y1 + radius));
            boundingPolygon.Points.Add(new Vector(x1 - radius, y1 + radius));
            boundingPolygon.Points.Add(new Vector(x1 - radius, y1 - radius));
            boundingPolygon.Offset(0, 0);
            boundingPolygon.BuildEdges();

            // Setup the radius selection range for a circle
            outterRadius = radius;
            innerRadius = radius - (2 * minDist);
            if (innerRadius < 0)
            {
                innerRadius = 0;
            }
        }
Example #4
0
        private void GetLineBoundingPoly(float x1, float y1, float x2, float y2,
                                         float width, float originalScale,
                                         out Polygon boundingPolygon)
        {
            float minDist;
            
            width = width / 2;
            if ((width * originalScale) < 5) 
            {
                minDist = 5 / originalScale;
            }
            else
            {
                minDist = width;
            }

            float angle = (float)Math.Atan2(y2 - y1, x2 - x1);
            float t2sina1 = minDist * (float)Math.Sin(angle);
            float t2cosa1 = minDist * (float)Math.Cos(angle);

            boundingPolygon = new Polygon();
            boundingPolygon.Points.Add(new Vector(x1 + t2sina1, y1 - t2cosa1));
            boundingPolygon.Points.Add(new Vector(x2 + t2sina1, y2 - t2cosa1));
            boundingPolygon.Points.Add(new Vector(x2 - t2sina1, y2 + t2cosa1));
            boundingPolygon.Points.Add(new Vector(x1 - t2sina1, y1 + t2cosa1));
            boundingPolygon.Offset(0, 0);
            boundingPolygon.BuildEdges();
        }
Example #5
0
 // Calculate the projection of a polygon on an axis and returns it as a [min, max] interval
 public void ProjectPolygon(Vector axis, Polygon polygon, ref float min, ref float max)
 {
     // To project a point on an axis use the dot product
     float d = axis.DotProduct(polygon.Points[0]);
     min = d;
     max = d;
     for (int i = 0; i < polygon.Points.Count; i++)
     {
         d = polygon.Points[i].DotProduct(axis);
         if (d < min)
         {
             min = d;
         }
         else
         {
             if (d > max)
             {
                 max = d;
             }
         }
     }
 }
Example #6
0
        // Check if polygon A is going to collide with polygon B for the given velocity
        public PolygonCollisionResult PolygonCollision(Polygon polygonA, Polygon polygonB, Vector velocity)
        {
            PolygonCollisionResult result = new PolygonCollisionResult();
            result.Intersect = true;
            result.WillIntersect = true;

            int edgeCountA = polygonA.Edges.Count;
            int edgeCountB = polygonB.Edges.Count;
            float minIntervalDistance = float.PositiveInfinity;
            Vector translationAxis = new Vector();
            Vector edge;

            // Loop through all the edges of both polygons
            for (int edgeIndex = 0; edgeIndex < edgeCountA + edgeCountB; edgeIndex++)
            {
                if (edgeIndex < edgeCountA)
                {
                    edge = polygonA.Edges[edgeIndex];
                }
                else
                {
                    edge = polygonB.Edges[edgeIndex - edgeCountA];
                }

                // ===== 1. Find if the polygons are currently intersecting =====

                // Find the axis perpendicular to the current edge
                Vector axis = new Vector(-edge.Y, edge.X);
                axis.Normalize();

                // Find the projection of the polygon on the current axis
                float minA = 0; float minB = 0; float maxA = 0; float maxB = 0;
                ProjectPolygon(axis, polygonA, ref minA, ref maxA);
                ProjectPolygon(axis, polygonB, ref minB, ref maxB);

                // Check if the polygon projections are currentlty intersecting
                if (IntervalDistance(minA, maxA, minB, maxB) > 0) result.Intersect = false;

                // ===== 2. Now find if the polygons *will* intersect =====

                // Project the velocity on the current axis
                float velocityProjection = axis.DotProduct(velocity);

                // Get the projection of polygon A during the movement
                if (velocityProjection < 0)
                {
                    minA += velocityProjection;
                }
                else
                {
                    maxA += velocityProjection;
                }

                // Do the same test as above for the new projection
                float intervalDistance = IntervalDistance(minA, maxA, minB, maxB);
                if (intervalDistance > 0) result.WillIntersect = false;

                // If the polygons are not intersecting and won't intersect, exit the loop
                if (!result.Intersect && !result.WillIntersect) break;

                // Check if the current interval distance is the minimum one. If so store
                // the interval distance and the current distance.
                // This will be used to calculate the minimum translation vector
                intervalDistance = Math.Abs(intervalDistance);
                if (intervalDistance < minIntervalDistance)
                {
                    minIntervalDistance = intervalDistance;
                    translationAxis = axis;

                    Vector d = polygonA.Center - polygonB.Center;
                    if (d.DotProduct(translationAxis) < 0) translationAxis = -translationAxis;
                }
            }

            // The minimum translation vector can be used to push the polygons appart.
            // First moves the polygons by their velocity
            // then move polygonA by MinimumTranslationVector.
            if (result.WillIntersect) result.MinimumTranslationVector = translationAxis * minIntervalDistance;

            return result;
        }