WPF/Silverlight 如何计算控件中的总立方单位/像素?

发布于 2024-09-10 02:08:25 字数 340 浏览 3 评论 0原文

我的 silverlight 应用程序中有一个 scribbale inkpresenter,我在不同的形状中多次使用它,我想计算 inkpresenter 被乱写的百分比,

我的问题是,由于 inkpresenter 的形状可以是圆形或多边形我不知道如何获得可涂鸦表面上可用的单位/像素。

据我了解,actualWidth和actualHeight属性只会通过计算帮助我计算矩形形状,

units = uielemnt.Actualwidth * uielement.ActualHeight

但对于服装形状,我不确定如何计算actualWidth/Height。

I have a scribbale inkpresenter in my silverlight app that I'm using multiple times in different shapes, I want to calculate how much percent of the inkpresenter has been scribbled,

My problem is that since the shape of the ink presenter can be circular or poly I don't know how i can get the units/pixels there is available on the scribbable surface.

As far as i understand is that the actualWidth and actualHeight properties will only help me for rectangular shape by calculating

units = uielemnt.Actualwidth * uielement.ActualHeight

but for costum shapes I'm not sure how the actualWidth/Height are calculated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

痴梦一场 2024-09-17 02:08:25

WPF 答案

在 WPF 中,您只需使用 Geometry.Combine 组合笔划几何图形,然后对组合几何图形调用 GetArea 即可获取覆盖的总面积。

Silverlight 答案

在 Silverlight 中,您没有 Geomerty.Combine 或 Geometry.GetArea,也没有 RenderTargetBitmap。所以在Silverlight中我认为你必须自己进行计算。

以下是设置步骤:

  1. 将几何图形转换为三次贝塞尔曲线(近似弧,其他一切都是精确的)
  2. 在 x 最小值和 x 最大值处分割所有曲线
  3. 重新排列坐标,使每条曲线从低 x 到高 x
  4. 按 x 排序,然后按 y 排序第一个坐标
  5. 从最小 x 坐标开始,没有活动曲线段

这是主循环:

  1. 将所有从当前 x 坐标开始的贝塞尔曲线添加到活动列表 从活动列表
  2. 中删除所有以当前 x 坐标结束的贝塞尔曲线
  3. 计算交点活跃的贝塞尔曲线。找到该交点的下一个 x 坐标。
  4. 让“end x”是贝塞尔曲线的下一条线交点和下一个开始或停止坐标中最早的坐标
  5. 计算从当前x到“end x”的面积,然后将当前设置为end
  6. 重复直到“end x”达到任何曲线的最大x坐标

这里是计算面积的内循环:

  1. 通过增加 y 的活动曲线。
  2. 每次通过曲线时,都会翻转该曲线原始几何图形的“内部”位。
  3. 每次 y 更改设置的任何“内部”位时,计算前一个贝塞尔曲线和当前贝塞尔曲线之间的面积并将其添加到总面积中

就是这样。

有关 Silverlight 答案的更多详细信息

将 PathGeometry 的段转换为三次贝塞尔近似值的公式:

  • BezierSegment:三次控制点为 P0、P1、P2、P3(无变化)
  • LineSegment:三次控制点为 P0, P0、P1、P1
  • QuadraticBezierSegment:三次方控制点为 P0、(P0+2P1)/3、(2P1+P2)/3、P2
  • ArcSegment:分为八分圆,并为每个八分圆计算起始点和起始点处的单位切向量 T0、T1。端点指向圆弧,生成 P0 的控制点(近似值),P0 + T0 * 4/3*(Sqrt(2)-1)*R,P1 + T1 * 4/3(Sqrt(2)-1)*R ,P1,然后修改大小和旋转角度
  • Poly...Segment:分成单独的段,然后在每个段上使用上述公式

计算活动贝塞尔曲线的交点:

  • 由于曲线已经在其最小值/最大值处分割,因此每条曲线都是平滑的, x 的连续函数,您可以使用这些技术来计算它们的交集
  • 如果您检查 y 可以节省一些计算在实际计算交集之前查看最小值/最大值是否存在任何可能的重叠

WPF Answer

In WPF you can just use Geometry.Combine to combine the stroke geometries, then call GetArea on the combined geometry to get the total area covered.

Silverlight Answer

In Silverlight you don't have Geomerty.Combine or Geometry.GetArea, and you also don't have RenderTargetBitmap. So in Silverlight I think you have to do the calculations yourself.

Here are the setup steps:

  1. Convert the geometries to cubic bezier curves (approximate arcs, all else are exact)
  2. Split all curves at their x minima and x maxima
  3. Rearrange coordinates so each curve goes from low x to high x
  4. Sort by x then y of first coordinate
  5. Start at minimum x coordinate with no active curve segments

Here is the main loop:

  1. Add any bezier curves that start at the current x coordinate to the active list
  2. Remove any bezier curves that end at the current x coordinate from the active list
  3. Compute intersections of active bezier curves. Find next x coordinate of such intersection.
  4. Let "end x" be earliest of next line intersection and next start or stop coordinate of a bezier curve
  5. Compute area from current x to "end x" then set current to end
  6. Repeat until "end x" reaches macimum x coordinate of any curve

Here is the inner loop that computes the area:

  1. Go through active curves in increasing y.
  2. Every time a curve is passed flip the "inside" bit for the original geometry for that curve.
  3. Every time y changes any "inside" bit is set, compute the area between the previous bezier curve and the current one and add it to the grand total area

That's it.

More details on Silverlight answer

Formulas to convert segments of a PathGeometry into a cubic bezier approximation:

  • BezierSegment: Cubic control points are P0, P1, P2, P3 (no change)
  • LineSegment: Cubic control points are P0, P0, P1, P1
  • QuadraticBezierSegment: Cubic control points are P0, (P0+2P1)/3, (2P1+P2)/3, P2
  • ArcSegment: Divide into octants and for each, compute unit tangent vectors T0, T1 at start & end pointing toward arc, generate control points (approximation) of P0, P0 + T0 * 4/3*(Sqrt(2)-1)*R, P1 + T1 * 4/3(Sqrt(2)-1)*R, P1, then modify with size and RotationAngle
  • Poly...Segment: Break into individual segments, then use above formulas on each

Computing intersections of active Bezier curves:

  • Since the curves have already been split at their minima / maxima, each is a smooth, continuous function of x, you can use these techniques to compute their intersection
  • It can save some computation if you check y minima/maxima to see if there is any possible overlap before actually computing the intersection
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文