我正在尝试使用一系列弧段在WPF中创建自定义形状。该形状本质上是一个带有折断线段的圆形,类似这样
虽然我知道我可以使用Ellipse并设置破折号数组属性来实现类似的效果,但是我需要处理厚度和半径的变化,即我必须保持可见段的数量不变,并且使用破折号变得很困难数组属性,因为它相对于笔触厚度。
因此,我尝试创建类似于SO问题here的自定义形状。该答案中描述的形状仅与绘制单个弧有关,而我需要绘制之间具有间隙的一系列弧。这就是我正在尝试的
for ( int i = 1; i <= Segments; i++ )
{
var endpoint = PolarToCartesian(sweepAngle * i, Radius);
var drawArcSegment = i % 2 == 0;
if (drawArcSegment)
{
var arcSegment = new ArcSegment
{
Point = endpoint,
Size = new Size(Radius, Radius),
IsLargeArc = false,
SweepDirection = SweepDirection.Clockwise
};
}
else
{
// WHAT TO DO HERE?
// Need to either draw an arc segment that can't be seen but I can't apply
// style properties to an arc segment OR need to move the current point of the
// parent path figure to a new point that is the start of the following segment
}
}
这可能吗?我以正确的方式来处理这个问题吗?
答案 0 :(得分:3)
计算适当的笔划破折号并不困难,
给出一个具有EllipseGeometry的路径(半径比Ellipse元素定义得更精确)
<Path x:Name="path" StrokeThickness="20" Stroke="Black">
<Path.Data>
<EllipseGeometry RadiusX="100" RadiusY="100"/>
</Path.Data>
</Path>
您可以像这样计算StrokeDashArray
和StrokeDashOffset
属性:
var ellipse = (EllipseGeometry)path.Data;
var strokeLength = 2 * Math.PI * ellipse.RadiusX / path.StrokeThickness;
var numSegments = 8;
var relativeSegmentLength = 0.75;
var segmentLength = strokeLength / numSegments * relativeSegmentLength;
var gapLength = strokeLength / numSegments * (1 - relativeSegmentLength);
path.StrokeDashArray = new DoubleCollection { segmentLength, gapLength };
path.StrokeDashOffset = -gapLength / 2;
答案 1 :(得分:2)
为每个ArcSegment启动一个新的PathFigure,因此路径不必是连续的。
或者使用Clemens的答案,效果更好。
public PathGeometry CreateGeometry(int segmentCount, double radius)
{
double sweepAngle = 360.0 / (double)segmentCount;
double segmentAngle = sweepAngle / 2;
double startAngleOffset = segmentAngle * 0.3;
double endAngleOffset = segmentAngle * 1.7;
var pg = new PathGeometry();
for (int i = 0; i < segmentCount; ++i)
{
double currentSegmentAngle = i * sweepAngle;
pg.Figures.Add(new PathFigure
{
StartPoint = PolarToCartesian(currentSegmentAngle + startAngleOffset, radius),
Segments = {
new ArcSegment{
Size = new Size(radius, radius),
SweepDirection = SweepDirection.Clockwise,
IsLargeArc = false,
Point = PolarToCartesian(currentSegmentAngle + endAngleOffset, radius)
}
}
});
}
return pg;
}
笔触粗细与您的笔触粗细并不相同,但是您可以弄清楚。此中的线帽为半径。在您的人中,他们不是:您的人就像是在半径上抹掉一条宽线。如果需要的话,就不能让笔画为您完成工作。您将必须绘制封闭且填充的PathFigures,每个都有两个弧和两个结束线。