3

What I want to do overall is add an ellipse to a canvas to represent the position of a golf ball on the Circumference of a circle when it is struck at a certain angle by a golf putter from the center of that circle. To do this I am using two images one which is a circle divided up into sections to represent the angle the ball was struck at. The other image is just a putter head that is rotated to represent the angle which the club hits the ball at. This image sits on top of the circle image. The blue ellipse represents the position of the ball.See the image output got from my application in the link below:

Required application output

To do this I basically calculated the width and height of the grid using this code:

public FacePage()
{
    InitializeComponent();
    GridGraphs.SizeChanged += GridGraphs_SizeChanged;
}

void GridGraphs_SizeChanged(object sender, SizeChangedEventArgs e)
{
    GetMeasurements();
}

private void GetMeasurements()
{
    GridGraphs.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));

    double width = GridGraphs.DesiredSize.Width;
    double height = GridGraphs.DesiredSize.Height;

    RotatePutter(width, height);
}

and then passed the width and height into RotatePutter() where the the width and height was divided by two to get the centre point of the grid see below:

public void RotatePutter(double width, double height)
{

    double radius = width * 0.5;
    double centerX = width * 0.5;
    double centerY = height * 0.5;

    Random ran = new Random();
    double angle = ran.Next(-15, 15);

    if (angle >= 0)
    {
        if (angle <= 5)
        {
            lblShotStaus.Content = "Square";
        }
        else
        {
            lblShotStaus.Content = "Open";
        }
    }
    else
    {
        lblShotStaus.Content = "Closed";
    }

    double angleradians = (angle * (Math.PI / 180));

    Point putterCentre = new Point(0.5, 0.5);

    imgPutter.RenderTransformOrigin = putterCentre;

    RotateTransform rt = new RotateTransform(angle, 0.5, 0.5);
    imgPutter.RenderTransform = rt;

    BallLocation(radius, angleradians, centerX, centerY);
}

The centre point,radius,angle and the putter Image is rotated here and the radius, angleradians,centerX and centerY are passed to BallLocation to calculate the position of the Ball like so:

public void BallLocation(double rad, double anglerad, double centerX, double centerY)
{
    Ellipse ellipse = new Ellipse();

    double xBallPoint = (centerX - (rad * Math.Cos(anglerad)));
    double yBallPoint = (centerY - (rad * Math.Sin(anglerad)));

    ellipse.Height = 10;
    ellipse.Width = 10;
    ellipse.Fill = new SolidColorBrush(Colors.Aqua);

    Canvas.SetLeft(ellipse, xBallPoint);
    Canvas.SetTop(ellipse, yBallPoint);
    canvasFaceAngle.Children.Add(ellipse);
}

This works ok in full screen put once I change the size of the window the position of the ball for the angle it was hit at is all wrong.

Would anyone have any idea how to dynamically get the grid width and height as the window size changes so to calculate the correct position for the ellipse (ball). Or any other alternative ways of completing this is also welcomed. Thanks in advance.

Here is my xaml:

<UserControl x:Class="HoleMorePuttsApplication.Pages.FacePage"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="40*"/>
        <ColumnDefinition Width="60*"/>
    </Grid.ColumnDefinitions>
    <Viewbox Grid.ColumnSpan="1">
        <Label Content="Face Angle Page" FontWeight="Bold" />
    </Viewbox>
    <Grid Name="GridGraphs" Column="1">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Name="columnLeft" Width="50*"/>
            <ColumnDefinition Name="columnRight" Width="50*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Name="rowTop" Height="70*"/>
            <RowDefinition Name="rowBottom" Height="30*"/>
        </Grid.RowDefinitions>

        <Image x:Name="imgAngles"  Source="C:\Users\BernardWork\Documents\Work\Net\PuttingApp\Images\360Angles.jpg" Grid.ColumnSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top"/>
        <Image x:Name="imgPutter"   Source="C:\Users\BernardWork\Documents\Work\Net\PuttingApp\Images\Putter.jpg" Opacity="0.5" Margin="130,105,70,105" Grid.ColumnSpan="2" HorizontalAlignment="Left" VerticalAlignment="Bottom"/>
        <Label x:Name="lblShotStaus" Content="Label" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top"/>
        <Canvas Name="canvasFaceAngle" Grid.ColumnSpan="2" Grid.Row="0" RenderTransformOrigin="0.543,0.511"></Canvas>


    </Grid>

</Grid>

Marc
  • 3,905
  • 4
  • 21
  • 37
user1948787
  • 63
  • 2
  • 8

2 Answers2

1

If I understand correct, I believe the problem may be with:

double width = GridGraphs.DesiredSize.Width;
double height = GridGraphs.DesiredSize.Height;

You are calling Measure with no bounds provided which means that it will tell you the size the Grid would be were there no limitations (hence, the DesiredSize). The DesiredSize and the ActualSize may be two very different values.

In the case above, the args of the SizeChanged method will provide you with what you need.

void GridGraphs_SizeChanged(object sender, SizeChangedEventArgs e)
{
    RotatePutter(e.NewSize.Width, e.NewSize.Height);
}
Brian S
  • 5,675
  • 1
  • 22
  • 22
  • Hi Thanks for the reply ye you are right the problem was with the double width = GridGraphs.DesiredSize.Width; double height = GridGraphs.DesiredSize.Height; – user1948787 Feb 05 '13 at 19:03
  • Hi Thanks for the reply ye you are right the problem was with the double width = GridGraphs.DesiredSize.Width; double height = GridGraphs.DesiredSize.Height; I changed it to use the canvas ActualWidth and ActualHeight and it is working but ye it the answer you proposed also works perfectly.Thanks Again – user1948787 Feb 05 '13 at 19:25
  • You're welcome, glad it worked. Please mark this as the answer so that others can benefit from it as well. – Brian S Feb 05 '13 at 20:59
0

So if the goal is just to get the grid width/height, the ActualWidth and ActualHeight properties should give you that information. One thing to be careful about though: while the Grid control changes size along with the window, the Canvas control does not. In other words, if you read the actualwidth/height of a grid, it should correspond to the side of the window, but if you read the actualwith/height of a canvas, it will probably give you incorrect information.

sircodesalot
  • 11,231
  • 8
  • 50
  • 83
  • Thanks for your answer but I used the canvas in the end to get the actual Width and Height and it worked.This could be due to the fact that the canvas was set to stretch to fill the grid maybe.Thanks again for your reply much appreciated. – user1948787 Feb 05 '13 at 19:24