I have a five-pointed star.

<ed:RegularPolygon x:Name="regularPolygon" Fill="{StaticResource RatingButtonNormalFill}" InnerRadius="0.55" PointCount="5" Stroke="Black" StrokeThickness="0.5" RenderTransformOrigin="0.5,0.5" Width="{TemplateBinding ActualWidth}" Height="{TemplateBinding ActualHeight}"> 

There is a problem with her. On the form it is small (20x20) and it rotates when clicked. So when rotating it seems to shift a little.

I suppose that this is due to the fact that when a star rotates, the dimensions of the rectangle describing it change (the container does not rotate with it) and it adjusts its dimensions on the move. I do not know what to do with yet. Maybe this is not the reason.

UPD

I guessed the reason. The star does not fit into the square. Here, I will show with the example of a regular pentagon and a square what is happening. Here is an image without turning.

Picture 1 (no rotation)

But I turned the pentagon at 72 degrees (that is, to be at the top of its next vertex).

Picture 2 (turn at 72 degrees)

I don't know what to do with this yet.

UPD2

In short, I found a geometric solution ... I just need to transfer it to xaml. The point is that the square in which I have a star should describe the circle in which the star is inscribed. How to transfer it to xaml I do not know :(

enter image description here

UPD3

It is necessary to transfer the center of rotation to the center of the circle describing the star. The circle itself is of course not. It is necessary to change the property RenderTransformOrigin="0.5,0.5" , but I still do not know what

  • No, you have the same RenderTransform , the sizes do not change. Apparently, ed:RegularPolygon does not accurately center your star. Show his code. - VladD
  • @VladD, the star rotates 72 degrees (that is, its next vertex should be at the top). The problem is that the regular pentagon does not fit into the square. I just turned a pentagon on a square in a Word. In short, I guessed the reason, but I don’t know what to do with it yet - iRumba
  • @VladD, see the update - iRumba
  • It is true, the regular pentagon does not fit into the square. But it must be located so that its center coincides exactly with the center of the square. In this case, the upper vertex will not rest on the upper side of the square, but this is normal. - VladD
  • Otherwise, when rotating around the center of the square there will be problems. That is, the error should be in ed:RegularPolygon . Let's get his code :) - VladD

1 answer 1

The RegularPolygon class, unfortunately, is no good: it does not center the shape around the geometric center, but rather stretches its height and width, so it turns out that it is not a regular polygon!

To be correct, the easiest way to find yourself. I have the following code:

 <Grid Background="#D08435"> <Path Data="M -1,-1 M 0,-1 L 0.95105651629515357211643933337938,-0.30901699437494742410229341718282 L 0.58778525229247312916870595463907,0.80901699437494742410229341718282 L -0.58778525229247312916870595463907,0.80901699437494742410229341718282 L -0.95105651629515357211643933337938,-0.30901699437494742410229341718282 L 0,-1 M 1,1" Stretch="Uniform" Fill="#7093D0" RenderTransformOrigin="0.5,0.5"/> </Grid> 

(Coefficients at L are sines and cosines of angles multiple of 72 °.)

I added a rotation to the Path , it turned out this:

animated cartoon


If you need a variable inner radius, it is probably easier to do it through a converter.

 class StarGeometryConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return CreateStarGeometry((int)parameter, (double)value); } Geometry CreateStarGeometry(int numberOfVertices, double innerRadius) { var edge1 = new PathFigure() { StartPoint = new Point(-1, -1) }; var edge2 = new PathFigure() { StartPoint = new Point(1, 1) }; var segments = new List<PathSegment>(); var step = Math.PI * 2 / numberOfVertices; foreach (var angle in Enumerable.Range(0, numberOfVertices).Select(n => n * step)) { segments.Add(new LineSegment( new Point(Math.Sin(angle), -Math.Cos(angle)), isStroked: true)); segments.Add(new LineSegment( new Point(innerRadius * Math.Sin(angle + step / 2), -innerRadius * Math.Cos(angle + step / 2)), isStroked: true)); } var figure = new PathFigure(new Point(0, -1), segments, closed: true); return new PathGeometry(new[] { edge1, figure, edge2 }); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotSupportedException(); } } 

With it we get the following XAML:

 <Window.Resources> <sys:Int32 x:Key="NumberOfVertices">5</sys:Int32> <sys:Double x:Key="InnerRadius">0.6</sys:Double> <local:StarGeometryConverter x:Key="StarConverter"/> </Window.Resources> 
 <Grid Background="#D08435"> <Path Data="{Binding Source={StaticResource InnerRadius}, Converter={StaticResource StarConverter}, ConverterParameter={StaticResource NumberOfVertices}}" Stretch="Uniform" Fill="#7093D0" RenderTransformOrigin="0.5,0.5"/> </Grid> 

Result:

More anima

  • Thanks, but in the end I still have a lot of problems with using Path . First, RegularPolygon allows RegularPolygon to set the inner radius to make a star from a polygon, and this allows me to flexibly change the appearance of a star with one parameter (I don’t like the right one). - iRumba
  • Secondly, everything is centered on the same geometric center. It is just that a regular pentagon is inside a rectangle, not a square, but for correct rotation it is necessary to have a square. That is, the center of rotation should be where the center of the circle describing the star is located. I will look in this direction for now. - iRumba
  • @iRumba: Well, you can’t please you. Updated the answer. - VladD
  • Thank! :) I just wanted to abstract as much as possible from geometry (as a science). I don't remember her :( - iRumba
  • @iRumba: Please! I understand, I want ready and correct controls, but unfortunately RegularPolygon still requires the use of trigonometry. In general, do not escape from her :) - VladD