WPF 自定义形状交替弧段
WPF Custom Shape Alternating Arc Segments
我正在尝试使用一系列圆弧段在 WPF 中创建自定义形状。形状本质上是一个带有断线的圆,像这样
虽然我知道我可以使用椭圆并设置破折号数组来实现类似的效果 属性,但我需要处理不断变化的厚度和半径,即,我必须保持可见线段的数量不变,并且使用破折号数组 属性 会变得很困难,因为它与笔画粗细有关。
因此,我正在尝试创建一个类似于 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
}
}
这可能吗?我是否以正确的方式处理这个问题?
为每个 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,每个 PathFigures 都有两条弧线和两条端线。
计算出合适的笔划破折号模式真的并不困难。
给定一个带有 EllipseGeometry 的路径(其中半径的定义比椭圆元素的定义更精确)
<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;
我正在尝试使用一系列圆弧段在 WPF 中创建自定义形状。形状本质上是一个带有断线的圆,像这样
虽然我知道我可以使用椭圆并设置破折号数组来实现类似的效果 属性,但我需要处理不断变化的厚度和半径,即,我必须保持可见线段的数量不变,并且使用破折号数组 属性 会变得很困难,因为它与笔画粗细有关。
因此,我正在尝试创建一个类似于 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
}
}
这可能吗?我是否以正确的方式处理这个问题?
为每个 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,每个 PathFigures 都有两条弧线和两条端线。
计算出合适的笔划破折号模式真的并不困难。
给定一个带有 EllipseGeometry 的路径(其中半径的定义比椭圆元素的定义更精确)
<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;