vinick
Topic Author
Posts: 3
Joined: 19 Jul 2021, 13:42

Positioning element at screen coordinates

22 Feb 2023, 20:08

Hello. I'm trying to implement HUD markers.
<Grid x:Name="WorkGrid">
                <Ellipse
                    x:Name="DestinationMarker"
                    Width="55"
                    Height="55"
                    Background="Transparent"
                    Margin="{Binding DestinationMarkerMargin}"
                    Visibility="{Binding DestinationMarkerVisibility}"
                    HorizontalAlignment="Left"
                    VerticalAlignment="Top"
                    Stroke="White" StrokeThickness="2" />
</Grid>
And in the following code I try to position the ellipse so that its center is at the given screen coordinates.
void GameScreenViewModel::updateMarkerMargin(
    Noesis::FrameworkElement const* workGrid,
    float screenX, float screenY,
    Noesis::Thickness& markerMargin)
{
    const Noesis::Point size = workGrid->PointToScreen(Noesis::Point{ 55, 55});
    const Noesis::Point origin = workGrid->PointToScreen(Noesis::Point{ 0, 0 });
    float width = size.x - origin.x;
    float height = size.y - origin.y;

    const Noesis::Point point = workGrid->PointFromScreen(Noesis::Point(screenX - width/2 , screenY - height/2));
    markerMargin.left = std::clamp(point.x, 0.0f, workGrid->GetActualWidth() - markerSize.x);
    markerMargin.top = std::clamp(point.y, 0.0f, workGrid->GetActualHeight() - markerSize.y);
}
But the marker turns out to be shifted to the left and up relative to the desired point.
Image

If I try to do so, visually the marker seems to be in the right place, but I do not understand why it is so:
    const Noesis::Point point = workGrid->PointFromScreen(Noesis::Point(screenX - width/4 , screenY - height/4));
 
User avatar
sfernandez
Site Admin
Posts: 3363
Joined: 22 Dec 2011, 19:20

Re: Positioning element at screen coordinates

23 Feb 2023, 12:13

I think it will be easier to offset the Ellipse to its center, so you just need transform the screen coordinate to the WorkGrid element:
<Grid x:Name="WorkGrid">
    <Ellipse x:Name="DestinationMarker"
             Width="55" Height="55"
             Background="Transparent"
             Margin="{Binding DestinationMarkerMargin}"
             Visibility="{Binding DestinationMarkerVisibility}"
             HorizontalAlignment="Left" VerticalAlignment="Top"
             Stroke="White" StrokeThickness="2">
        <Ellipse.RenderTransform>
            <TranslateTransform X="-27.5" Y="-27.5"/>
        </Ellipse.RenderTransform>
    </Ellipse>
</Grid>
void GameScreenViewModel::updateMarkerMargin(Noesis::FrameworkElement const* workGrid,
    float screenX, float screenY, Noesis::Thickness& markerMargin)
{
    const Noesis::Point point = workGrid->PointFromScreen(Noesis::Point(screenX, screenY));
    markerMargin.left = std::clamp(point.x, 0.0f, workGrid->GetActualWidth() - markerSize.x);
    markerMargin.top = std::clamp(point.y, 0.0f, workGrid->GetActualHeight() - markerSize.y);
}

Who is online

Users browsing this forum: No registered users and 4 guests