none
关于Stroke对象缩放以后某一边界发生变化的问题? RRS feed

  • 问题

  • 对于Stroke对象应用缩放以后,再次获取其某一边界,会发现其坐标发生变化。比如我以Stroke的右边为中心,向左拉伸Stroke时,发现其Stroke的右边坐标不是固定的。我在InkCanvas里面试了一下,选中笔画以后,在最下边的边框上向上缩小笔画,笔画的上边界会不断的向上移动。期间我仅仅缩小笔画,并没有移动它。请问是什么原因造成的?有什么解决方法?谢谢!
    2011年8月8日 8:09

答案

  • 我看了你的效果了,同时我也看了Reflector反编译的代码。Stroke类的public virtual void Transform(Matrix transformMatrix, bool applyToStylusTip)方法:

    public virtual void Transform(Matrix transformMatrix, bool applyToStylusTip)
    {
      if (!transformMatrix.IsIdentity)
      {
        // ... Checking
        this._cachedGeometry = null;
        this._cachedBounds = Rect.Empty;
        if (applyToStylusTip)
        {
          this._delayRaiseInvalidated = true;
        }
        try
        {
          this._stylusPoints.Transform(new MatrixTransform(transformMatrix)); // <--- Important
          if (applyToStylusTip)
          {
            Matrix stylusTipTransform = this._drawingAttributes.StylusTipTransform;
            transformMatrix.OffsetX = 0.0;
            transformMatrix.OffsetY = 0.0;
            stylusTipTransform *= transformMatrix;
            if (stylusTipTransform.HasInverse)
            {
              this._drawingAttributes.StylusTipTransform = stylusTipTransform;
            }
          }
          if (this._delayRaiseInvalidated)
          {
            this.OnInvalidated(EventArgs.Empty);
          }
        }
        finally
        {
          this._delayRaiseInvalidated = false;
        }
      }
    }
    
    
    

    你可以看到那行 this._stylusPoints.Transform(new MatrixTransform(transformMatrix));

    所以我在Runtime的时候看了内部的_stylusPoints的X,Y位置,发现不一致的。比如我有个100宽的墨迹点,他的位置是(0,0)不过他内部的_stylusPoints的一个点的位置却是(50,50)。他只记录这个宽的点的中心点位置。所以他在应用变换时候,是对(50,50)做的。

     

    Sincerely,

     

     

     


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 张柱敏 2011年8月13日 1:14
    2011年8月11日 23:57
    版主

全部回复

  • foreach (Stroke st in this.inkCanvas1.GetSelectedStrokes()) { Matrix ma = new Matrix(); ma.ScaleAt(2, 1, st.GetBounds().X, st.GetBounds().Y); st.Transform(ma, false); } 相关代码如上,我在一个单击事件中加入上述代码,不断点击,发现选中笔画的右边界不断的移动。
    2011年8月8日 8:35
  • 我实际又测试了一下,如果笔画宽度越小,变化越不明显,越大变化就越明显。
    2011年8月8日 8:39
  • 你是否用了自定义Stroke,是否设置了FitToCurve 这个属性True: http://msdn.microsoft.com/zh-cn/library/system.windows.ink.drawingattributes.fittocurve.aspx 使用贝塞尔曲线平滑法会使得计算出来的边界点位置有偏差的。这个问题很类似于这个帖子 http://social.microsoft.com/Forums/zh-CN/wpfzhchs/thread/901223da-72ef-4732-9939-94cfe4c1604e 

    最好让我看下你的代码,或者可以分享下你的项目给我看下, 我来重现找个解决方案。你可以上传到skydrive.com网站的公开目录下,把链接贴在这。

    Sincerely,


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年8月9日 16:14
    版主
  • 他的那个帖子我看了,也是受笔画宽度影响的,但是我希望笔画宽度可以进行调整。我的目的是图形选中以后,能够围绕固定一条边缩放。代码如下:

     

            private void button2_Click(object sender, RoutedEventArgs e)

            {

                this.inkCanvas1.DefaultDrawingAttributes.Width = 1;

                this.inkCanvas1.DefaultDrawingAttributes.Height = 1;

            }

            private void button3_Click(object sender, RoutedEventArgs e)

            {

                foreach (Stroke st in this.inkCanvas1.Strokes)

                {

                    Matrix ma = new Matrix();

                    ma.ScaleAt(1.5, 1, st.GetBounds().X, st.GetBounds().Y);

                    st.Transform(ma, false);  

                }

            }

    宽度设为1是没有变化的,如果设为10,或者更大就可以看出变化来了。这里的FitToCurve,我没有修改使用的是默认值,也没有使用自定义笔画。目前我的过渡方法是让笔画围绕其中心点变化。

     


    2011年8月10日 1:09
  • 我放置了一个一般的InkCanvas用你的代码,测试下来,右边界没有太大变化啊。看来我要看下你的例子了。 还有我的测试环境是 Windows 7 Aero主题 ATI显卡。

     


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年8月10日 16:10
    版主
  • 文件我已经上传到网站了上了,网址 

    https://skydrive.live.com/redir.aspx?cid=8f125a6da8d15aee&resid=8F125A6DA8D15AEE!103

    点击 “移动” 以后 可以看到 笔画的右边界 输出数值,X是不断变化的(增加)


    2011年8月11日 2:10
  • 我看了你的效果了,同时我也看了Reflector反编译的代码。Stroke类的public virtual void Transform(Matrix transformMatrix, bool applyToStylusTip)方法:

    public virtual void Transform(Matrix transformMatrix, bool applyToStylusTip)
    {
      if (!transformMatrix.IsIdentity)
      {
        // ... Checking
        this._cachedGeometry = null;
        this._cachedBounds = Rect.Empty;
        if (applyToStylusTip)
        {
          this._delayRaiseInvalidated = true;
        }
        try
        {
          this._stylusPoints.Transform(new MatrixTransform(transformMatrix)); // <--- Important
          if (applyToStylusTip)
          {
            Matrix stylusTipTransform = this._drawingAttributes.StylusTipTransform;
            transformMatrix.OffsetX = 0.0;
            transformMatrix.OffsetY = 0.0;
            stylusTipTransform *= transformMatrix;
            if (stylusTipTransform.HasInverse)
            {
              this._drawingAttributes.StylusTipTransform = stylusTipTransform;
            }
          }
          if (this._delayRaiseInvalidated)
          {
            this.OnInvalidated(EventArgs.Empty);
          }
        }
        finally
        {
          this._delayRaiseInvalidated = false;
        }
      }
    }
    
    
    

    你可以看到那行 this._stylusPoints.Transform(new MatrixTransform(transformMatrix));

    所以我在Runtime的时候看了内部的_stylusPoints的X,Y位置,发现不一致的。比如我有个100宽的墨迹点,他的位置是(0,0)不过他内部的_stylusPoints的一个点的位置却是(50,50)。他只记录这个宽的点的中心点位置。所以他在应用变换时候,是对(50,50)做的。

     

    Sincerely,

     

     

     


    Bob Bao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 张柱敏 2011年8月13日 1:14
    2011年8月11日 23:57
    版主