Share via

[UWP]Spotlight - Bug Reporting

RobDev 431 Reputation points
2022-03-03T15:35:57.507+00:00

Greetings All,

in my UWP user control I'm trying to create a circle of illumination of exactly the diameter I specify, in this specific case the circle of illumination should a diameter of 20.

To do this I calculate the angle between the centre if my proposed illumination circle, the spotlight centre and its edge, double it and use the result as the InnerConeAngleInDegrees and OuterConeAngleInDegrees value. The calculation is performed as follows: the Z value of the spotlight's Offset Vector3 structure is set to 50, the desired diameter of the circle of illumination is 20, therefore the distance between the centre of my illumination circle and its edge is 10.

To calculate the angle between the centre of my proposed illumination circle, the spotlight centre and its edge I calculate the tangent of that angle by dividing the distance between the centre of my illumination circle and it edge (i.e. 10) by the distance from the centre of my illumination circle to the spotlight (i.e. the spotlight's Offset Z value - 50) - basic trigonometry tan = opposite over adjacent.

I then convert the tangent value to degrees by calling the Math.Atan() function and convert the result from radians to degrees by multiplying my 180/Math.PI. I double the returned value and use the result as the InnerConeAngleInDegrees and OuterConeAngleInDegrees value.

I placed a rectangle (size 20 x 20) at the centre of the display in order to check the diameter of the spotlight 'beam'. However, the resulting illuminated circle is much bigger than the calculations should have produced as can be seen from the following screenshot.

179716-spotlightscreenshot.png

I have included the code from my user control, below. so it can be checked.

User Control Xaml:

<UserControl  
    x:Class="UWPSpotlightTest2.TestSpotUserControl"  
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
    xmlns:local="using:UWPSpotlightTest2"  
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
    mc:Ignorable="d"  
    d:DesignHeight="300"  
    d:DesignWidth="400" Loaded="UserControl_Loaded" SizeChanged="UserControl_SizeChanged">  
  
    <Grid Name="TheGrid">  
        <Grid.Lights>  
            <local:TestAmbientLight/>  
        </Grid.Lights>  
        <Ellipse x:Name="OuterCirc" Fill="DodgerBlue" Width="300" Height="300" StrokeThickness="5" Stroke="BlueViolet"/>  
        <Rectangle Fill="DodgerBlue" Width="{x:Bind SpotLightDimension}" d:Width="20" Height="{x:Bind SpotLightDimension}" d:Height="20" Stroke="Black" StrokeThickness="1"/>  
    </Grid>  
</UserControl>  
  

User Control Code Behind:

    **public sealed partial class TestSpotUserControl : UserControl  
    {  
        private bool IsDataInitiated;  
  
        private double gridWidth;  
        private double gridHeight;  
        private Point gridCentre;  
  
        private SpotLight myLight;  
  
        private const float SpotLightZVal = 50;  
        private const float SpotLightWidth = 20;  
  
        public float SpotLightDimension  
        {  
            get { return SpotLightWidth; }  
        }  
  
        public TestSpotUserControl()  
        {  
            this.InitializeComponent();  
            IsDataInitiated = false;  
        }  
  
        private void UserControl_Loaded(object sender, RoutedEventArgs e)  
        {  
            InitInternalData();  
        }  
        private void InitInternalData()  
        {  
            gridWidth = TheGrid.ActualWidth;  
            gridHeight = TheGrid.ActualHeight;  
            gridCentre.X = gridWidth / 2;  
            gridCentre.Y = gridHeight / 2;  
  
            var gridVisual = ElementCompositionPreview.GetElementVisual(TheGrid);  
  
            var compositor = gridVisual.Compositor;  
            this.myLight = compositor.CreateSpotLight();  
            this.myLight.CoordinateSpace = gridVisual;  
            this.myLight.InnerConeColor = Colors.White;  
  
            float halfAngle = (float)Math.Atan((SpotLightWidth / 2.0) / SpotLightZVal) * (float)(180 / Math.PI);  
            this.myLight.InnerConeAngleInDegrees = this.myLight.OuterConeAngleInDegrees = (halfAngle * (float)2.0);  
  
            float topX = (float)(gridCentre.X);  
            float topY = (float)(gridCentre.Y);  
  
            this.myLight.Offset = new Vector3(topX, topY, SpotLightZVal);  
            this.myLight.Targets.Add(gridVisual);  
  
            IsDataInitiated = true;  
        }  
  
        private void UserControl_SizeChanged(object sender, SizeChangedEventArgs e)  
        {  
            if (myLight != null && myLight.Offset != null)  
            {  
                Vector3 newOffset = new Vector3();  
                newOffset.X = (float)(e.NewSize.Width / 2.0);  
                newOffset.Y = (float)(e.NewSize.Height / 2.0);  
                newOffset.Z = myLight.Offset.Z;  
                myLight.Offset = newOffset;  
            }  
        }  
    }**  

I'm quite willing to admit that I may have made a mistake in my calculations and, if so, could someone please point out the error. If not, and my calculations are correct, then it would appear that there's a bug in the UWP spotlight class.

If this is a bug then can someone please tell me exactly how I go about reporting it?

Many thanks.

Developer technologies | Universal Windows Platform (UWP)

Answer accepted by question author

Anonymous
2022-03-08T08:16:52.553+00:00

Hello,

Welcome to Microsoft Q&A!

I could reproduce your issue with the code you shared. There is nothing wrong with your calculation of the angle. The logic is correct. Now, please take a look at the SpotLight.InnerConeAngleInDegrees Property. It's an inner cone angle, expressed as a semi-vertical angle in degrees. So you don't need to double it when you assign the angle value to the property.

Change your code like this:

this.myLight.InnerConeAngleInDegrees = this.myLight.OuterConeAngleInDegrees = (halfAngle);  

And it looks like this:

180926-image.png

Please let me know if you have other questions.
Thank you.


If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

Was this answer helpful?


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.