Drawing a triangle in WPF that supports multiple angles

2.4k Views Asked by At

I'm using a GeometryDrawing to draw a triangle in WPF. I currently am able to bind it to my ViewModel's "Angle" property that is attached to a slider that the user can move and thus move the rectangle around an object. The problem is that I want to make the rectangle to be also able to be wider or narrower according to a specific angle that I calculate that is based on a zoom value. I'm currently unable to make the rectangle change since I don't know how to do this on a GeometryDrawing object. Perhaps another object should be used?

The GeometryDrawing object code is this:

<GeometryDrawing Geometry="M100,100 L186.6,280 A100,100,0,0,1,13.4,280 L100,100">
     <GeometryDrawing.Brush>
         <LinearGradientBrush StartPoint="0,0" EndPoint="0,1" Opacity="0.25">
               <GradientStopCollection>
                     <GradientStop Color="Black" Offset="0" />
                     <GradientStop Color="Transparent" Offset="0.9"/>
               </GradientStopCollection>
         </LinearGradientBrush>
     </GeometryDrawing.Brush>
</GeometryDrawing>

The UI for the application is this (only a test project, I've made it to test the control before I implement it in my real project)

The UI for the rectangle problem. The faded rectangle is the one in question

Thanks for all your help folks!

John.

2

There are 2 best solutions below

0
On

Ok, I've managed to cause the arc to open and close. The way I did this was by defining both of the Arc's lines like this

<PathGeometry>
      <PathFigure StartPoint="50,0" IsClosed="True">
             <LineSegment Point="0,100" x:Name="m_leftLine" />
             <LineSegment Point="100,100" x:Name="m_rightLine" />
      </PathFigure>
</PathGeometry>

And then just writing a code behind for the slider's ValueChanged event and recalculate the line's X position using the required angle. This resulted in the following code:

public partial class MyFovControl : UserControl
{
private float m_oldAngleValue;
private float m_newAngleValue;

public MyFovControl()
{
  InitializeComponent();
  this.zoomSlider.ValueChanged += new RoutedPropertyChangedEventHandler<double>(zoomSlider_ValueChanged);
  m_oldAngleValue = m_newAngleValue = 0;
}

void zoomSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
  m_newAngleValue = (float)(Convert.ToDouble((double)lblFovXAngle.Content));

  // Happens only once the first time.
  if (m_oldAngleValue == 0)
  {
    m_oldAngleValue = m_newAngleValue;
  }

  m_leftLine.Point = new Point(m_leftLine.Point.X + (m_oldAngleValue - m_newAngleValue), m_leftLine.Point.Y);
  m_rightLine.Point = new Point(m_rightLine.Point.X - (m_oldAngleValue - m_newAngleValue), m_rightLine.Point.Y);
  m_oldAngleValue = m_newAngleValue;
  }
}

I know, very messi, but that's the only way I could think of and from what I've searched online - possibly the only way there is.

2
On

You could replace the current Geometry drawing string with two LineSegments and an ArcSegment.

<ArcSegment Size="100,50" 
            IsLargeArc="True" 
            SweepDirection="CounterClockwise" 
            Point="200,100" />

Besides, an Arc is more natural for a field of vision than a triangle especially when the angle is large (near 180 degrees).

EDIT

This is harder than it looks because you'll need to calculate the end point of the arc. I seen no other solution than to calculate the endpoint in code.