GetBounds() { AssertValid(); if (m_oEdge.IsSelfLoop) { Debug.Assert(false); throw new InvalidOperationException("Edge is self-loop."); } // Start with a rectangle that has the same dimensions as the edge, but // that starts at the origin and has an angle of zero. Point oVertex1Location = WpfGraphicsUtil.PointFToWpfPoint( m_oEdge.Vertex1.Location); Point oVertex2Location = WpfGraphicsUtil.PointFToWpfPoint( m_oEdge.Vertex2.Location); Double dLength = WpfGraphicsUtil.GetDistanceBetweenPoints( oVertex1Location, oVertex2Location); Double dAngleDegrees = MathUtil.RadiansToDegrees( WpfGraphicsUtil.GetAngleBetweenPointsRadians( oVertex1Location, oVertex2Location)); Double dHalfWidth = m_dWidth / 2.0; Point[] ao4BoundingPoints = new Point[4] { new Point(0, -dHalfWidth), new Point(dLength, -dHalfWidth), new Point(dLength, dHalfWidth), new Point(0, dHalfWidth), }; // Rotate the rectangle so it is at the same angle as the edge. TransformPoints(new RotateTransform(dAngleDegrees), ao4BoundingPoints); // Translate the rotated rectangle to the location of the edge's first // endpoint. TransformPoints( new TranslateTransform(oVertex1Location.X, oVertex1Location.Y), ao4BoundingPoints); // Create a PathGeometry from the bounding points. return(WpfPathGeometryUtil.GetPathGeometryFromPoints( ao4BoundingPoints[0], ao4BoundingPoints[1], ao4BoundingPoints[2], ao4BoundingPoints[3] )); }
GetEdgeEndpointOnCircle ( Point oVertexALocation, Double dVertexARadius, Point oVertexBLocation, out Point oEdgeEndpoint ) { Debug.Assert(dVertexARadius >= 0); AssertValid(); Double dEdgeAngle = WpfGraphicsUtil.GetAngleBetweenPointsRadians( oVertexALocation, oVertexBLocation); oEdgeEndpoint = new Point( oVertexALocation.X + (dVertexARadius * Math.Cos(dEdgeAngle)), oVertexALocation.Y - (dVertexARadius * Math.Sin(dEdgeAngle)) ); }
GetEdgeEndpointOnRectangle ( Point oVertexALocation, Rect oVertexARectangle, Point oVertexBLocation, out Point oEdgeEndpoint ) { AssertValid(); if (oVertexALocation == oVertexBLocation) { oEdgeEndpoint = oVertexALocation; return; } Double dVertexAX = oVertexALocation.X; Double dVertexAY = oVertexALocation.Y; Double dVertexBX = oVertexBLocation.X; Double dVertexBY = oVertexBLocation.Y; Double dHalfVertexARectangleWidth = oVertexARectangle.Width / 2.0; Double dHalfVertexARectangleHeight = oVertexARectangle.Height / 2.0; // Get the angle between vertex A and vertex B. Double dEdgeAngle = WpfGraphicsUtil.GetAngleBetweenPointsRadians( oVertexALocation, oVertexBLocation); // Get the angle that defines the aspect ratio of vertex A's rectangle. Double dAspectAngle = Math.Atan2( dHalfVertexARectangleHeight, dHalfVertexARectangleWidth); if (dEdgeAngle >= -dAspectAngle && dEdgeAngle < dAspectAngle) { // For a square, this is -45 degrees to 45 degrees. Debug.Assert(dVertexBX != dVertexAX); oEdgeEndpoint = new Point( dVertexAX + dHalfVertexARectangleWidth, dVertexAY + dHalfVertexARectangleWidth * ((dVertexBY - dVertexAY) / (dVertexBX - dVertexAX)) ); return; } if (dEdgeAngle >= dAspectAngle && dEdgeAngle < Math.PI - dAspectAngle) { // For a square, this is 45 degrees to 135 degrees. Debug.Assert(dVertexBY != dVertexAY); oEdgeEndpoint = new Point( dVertexAX + dHalfVertexARectangleHeight * ((dVertexBX - dVertexAX) / (dVertexAY - dVertexBY)), dVertexAY - dHalfVertexARectangleHeight ); return; } if (dEdgeAngle < -dAspectAngle && dEdgeAngle >= -Math.PI + dAspectAngle) { // For a square, this is -45 degrees to -135 degrees. Debug.Assert(dVertexBY != dVertexAY); oEdgeEndpoint = new Point( dVertexAX + dHalfVertexARectangleHeight * ((dVertexBX - dVertexAX) / (dVertexBY - dVertexAY)), dVertexAY + dHalfVertexARectangleHeight ); return; } // For a square, this is 135 degrees to 180 degrees and -135 degrees to // -180 degrees. Debug.Assert(dVertexAX != dVertexBX); oEdgeEndpoint = new Point( dVertexAX - dHalfVertexARectangleWidth, dVertexAY + dHalfVertexARectangleWidth * ((dVertexBY - dVertexAY) / (dVertexAX - dVertexBX)) ); }
GetEdgeEndpoint ( Point otherEndpoint, out Point edgeEndpoint ) { AssertValid(); Point oVertexLocation = this.VertexLocation; // Instead of doing geometry calculations similar to what is done in // VertexDrawingHistory.GetEdgePointOnRectangle(), make use of that // method by making the triangle look like a rectangle. First, figure // out how to rotate the triangle about the vertex location so that the // side containing the endpoint is vertical and to the right of the // vertex location. Double dEdgeAngle = WpfGraphicsUtil.GetAngleBetweenPointsRadians( oVertexLocation, otherEndpoint); Double dEdgeAngleDegrees = MathUtil.RadiansToDegrees(dEdgeAngle); Double dAngleToRotateDegrees; if (dEdgeAngleDegrees >= -30.0 && dEdgeAngleDegrees < 90.0) { dAngleToRotateDegrees = 30.0; } else if (dEdgeAngleDegrees >= -150.0 && dEdgeAngleDegrees < -30.0) { dAngleToRotateDegrees = 270.0; } else { dAngleToRotateDegrees = 150.0; } // Now create a rotated rectangle that is centered on the vertex // location and that has the vertical, endpoint-containing triangle // side as the rectangle's right edge. Double dWidth = 2.0 * m_dHalfWidth; Rect oRotatedRectangle = new Rect( oVertexLocation.X, oVertexLocation.Y - m_dHalfWidth, dWidth * WpfGraphicsUtil.Tangent30Degrees, dWidth ); Matrix oMatrix = WpfGraphicsUtil.GetRotatedMatrix(oVertexLocation, dAngleToRotateDegrees); // Rotate the other vertex location. Point oRotatedOtherVertexLocation = oMatrix.Transform(otherEndpoint); // GetEdgeEndpointOnRectangle will compute an endpoint on the // rectangle's right edge. Point oRotatedEdgeEndpoint; GetEdgeEndpointOnRectangle(oVertexLocation, oRotatedRectangle, oRotatedOtherVertexLocation, out oRotatedEdgeEndpoint); // Now rotate the edge endpoint in the other direction. oMatrix = WpfGraphicsUtil.GetRotatedMatrix(oVertexLocation, -dAngleToRotateDegrees); edgeEndpoint = oMatrix.Transform(oRotatedEdgeEndpoint); }