locked
How do I set Boundary and ElasticMargin? RRS feed

  • Question

  • Hi there...
    I am doing a multi touch application..
    I am quite new to this..
    I want to make an object bounce when hitting the edge of the form..
    After looking through the forums..
    I found out that to make an object bounce there need to be a Boundary and Elastic margin..
    How do I set the Boundary and ElasticMargin?
    I am coding in csharp..
    I tried something like    
      _processor.InertiaProcessor.ElasticMargin = 1200;

    But I got an error..
    I did a search and I can't find any examples of setting a boundary using the intertia processor..
    Can anyone help me?
    Sunday, September 13, 2009 8:02 AM

Answers

  • Hmm..
    I added in your codes and it seems abit jerky?
    It is very hard for me to explain..
    You can download the project file and take a look..
    Set MultitouchHOLSolution as start up project..
    Thanks
    Download Link :
    http://cid-8f095b2907113973.skydrive.live.com/self.aspx/.Public/Source.zip

    I think I figured it out... it looks like you have an extra call to:

    Picture.X += e.TranslationDelta.Width;
    Picture.Y += e.TranslationDelta.Height;

    after the line:

     

    if (Picture == null)
    return;

    Here's my complete code for ProcessManipulationDelta:

     

            private void ProcessManipulationDelta(object sender, ManipulationDeltaEventArgs e)
            {
                if (Picture == null)
                    return;
    
                if ((Picture.X + e.TranslationDelta.Width > 0 && Picture.X + e.TranslationDelta.Width < 1024))
                {
                    Picture.X += e.TranslationDelta.Width;
                }
                else
                {
                    if (Picture.X + e.TranslationDelta.Width < 0)
                    {
                        Picture.X = 1;
                    }
                    else
                    {
                        Picture.X = 1000;
                    }
                }
    
                if ((Picture.Y + e.TranslationDelta.Height > 0 && Picture.Y + e.TranslationDelta.Height < 768))
                {
                    Picture.Y += e.TranslationDelta.Height;
                }
                else
                {
                    if (Picture.Y + e.TranslationDelta.Height < 0)
                    {
                        Picture.Y = 1;
                    }
                    else
                    {
                        Picture.Y = 700;
                    }
                }
    
                Picture.Angle += e.RotationDelta * 180 / Math.PI;
    
                Picture.ScaleX *= e.ScaleDelta;
                Picture.ScaleY *= e.ScaleDelta;
    
                //Update inertia calculation. Take 40 percent from the previos data
                _inertiaParam.Update(e, 0.4F);
            }
    
    I moved your check for

    if (picture == null)

    to the top, this should fail earlier.  I also removed the extra call to Picture (X/Y) += which was causing both the objects to get removed off of the screen and to have the objects move too quickly.

    Regards,
    Gus
    • Marked as answer by ChengTeck90 Thursday, September 17, 2009 1:18 AM
    Wednesday, September 16, 2009 5:13 PM
    Moderator

All replies

  • The elastic bounds will actually enable a gutter rather than bouncing.  If you want to enable bouncing, you will need to perform bounds detection yourself and reset the inertia processor.  Also, your code above will probably not be working because you need to set the Top, Bottom, Left, and Right bounds.  E.g.

    _processor.InertiaProcessor.ElasticMarginLeft      = 0;
    _processor.InertiaProcessor.ElasticMarginTop      = 0;
    _processor.InertiaProcessor.ElasticMarginRight    = 1200;
    _processor.InertiaProcessor.ElasticMarginBottom = 800;

    There is a great resource on the Inertia processor and elastic margins here:

    http://msdn.microsoft.com/en-us/library/dd562169(VS.85).aspx

    Regards,
    Gus
    Monday, September 14, 2009 8:14 PM
    Moderator
  • The elastic bounds will actually enable a gutter rather than bouncing.  If you want to enable bouncing, you will need to perform bounds detection yourself and reset the inertia processor.  Also, your code above will probably not be working because you need to set the Top, Bottom, Left, and Right bounds.  E.g.

    _processor.InertiaProcessor.ElasticMarginLeft      = 0;
    _processor.InertiaProcessor.ElasticMarginTop      = 0;
    _processor.InertiaProcessor.ElasticMarginRight    = 1200;
    _processor.InertiaProcessor.ElasticMarginBottom = 800;

    There is a great resource on the Inertia processor and elastic margins here:

    http://msdn.microsoft.com/en-us/library/dd562169(VS.85).aspx

    Regards,
    Gus
    Thanks for the reply..
    If I do something like that..


                 _processor.InertiaProcessor.Boundary.Left = 0;
                _processor.InertiaProcessor.Boundary.Top = 0;
                _processor.InertiaProcessor.Boundary.Right = 1200;
                _processor.InertiaProcessor.Boundary.Bottom = 800;

                _processor.InertiaProcessor.ElasticMarginLeft = 0;
                _processor.InertiaProcessor.ElasticMarginTop = 0;
                _processor.InertiaProcessor.ElasticMarginRight = 1000;
                _processor.InertiaProcessor.ElasticMarginBottom = 600;

    I got a list of errors like..

    Error    1    Property or indexer 'System.Drawing.RectangleF.Left' cannot be assigned to -- it is read only   

    Error    2    Property or indexer 'System.Drawing.RectangleF.Top' cannot be assigned to -- it is read only   

    Error    3    Property or indexer 'System.Drawing.RectangleF.Right' cannot be assigned to -- it is read only  

    Error    4    Property or indexer 'System.Drawing.RectangleF.Bottom' cannot be assigned to -- it is read only   

    Error    5    'Windows7.Multitouch.Manipulation.InertiaProcessor' does not contain a definition for 'ElasticMarginLeft' and no extension method 'ElasticMarginLeft' accepting a first argument of type 'Windows7.Multitouch.Manipulation.InertiaProcessor' could be found (are you missing a using directive or an assembly reference?)  

    Error    6    'Windows7.Multitouch.Manipulation.InertiaProcessor' does not contain a definition for 'ElasticMarginTop' and no extension method 'ElasticMarginTop' accepting a first argument of type 'Windows7.Multitouch.Manipulation.InertiaProcessor' could be found (are you missing a using directive or an assembly reference?)  

    Error    7    'Windows7.Multitouch.Manipulation.InertiaProcessor' does not contain a definition for 'ElasticMarginRight' and no extension method 'ElasticMarginRight' accepting a first argument of type 'Windows7.Multitouch.Manipulation.InertiaProcessor' could be found (are you missing a using directive or an assembly reference?)

    Error    8    'Windows7.Multitouch.Manipulation.InertiaProcessor' does not contain a definition for 'ElasticMarginBottom' and no extension method 'ElasticMarginBottom' accepting a first argument of type 'Windows7.Multitouch.Manipulation.InertiaProcessor' could be found (are you missing a using directive or an assembly reference?)  

    Error    9    Property or indexer 'System.Drawing.RectangleF.Left' cannot be assigned to -- it is read only   

    Error    10    Property or indexer 'System.Drawing.RectangleF.Top' cannot be assigned to -- it is read only  

    Error    11    Property or indexer 'System.Drawing.RectangleF.Right' cannot be assigned to -- it is read only  

    Error    12    Property or indexer 'System.Drawing.RectangleF.Bottom' cannot be assigned to -- it is read only  

    Error    13    'Windows7.Multitouch.Manipulation.InertiaProcessor' does not contain a definition for 'ElasticMarginLeft' and no extension method 'ElasticMarginLeft' accepting a first argument of type 'Windows7.Multitouch.Manipulation.InertiaProcessor' could be found (are you missing a using directive or an assembly reference?)   

    Error    14    'Windows7.Multitouch.Manipulation.InertiaProcessor' does not contain a definition for 'ElasticMarginTop' and no extension method 'ElasticMarginTop' accepting a first argument of type 'Windows7.Multitouch.Manipulation.InertiaProcessor' could be found (are you missing a using directive or an assembly reference?) 

    Error    15    'Windows7.Multitouch.Manipulation.InertiaProcessor' does not contain a definition for 'ElasticMarginRight' and no extension method 'ElasticMarginRight' accepting a first argument of type 'Windows7.Multitouch.Manipulation.InertiaProcessor' could be found (are you missing a using directive or an assembly reference?) 

    Error    16    'Windows7.Multitouch.Manipulation.InertiaProcessor' does not contain a definition for 'ElasticMarginBottom' and no extension method 'ElasticMarginBottom' accepting a first argument of type 'Windows7.Multitouch.Manipulation.InertiaProcessor' could be found (are you missing a using directive or an assembly reference?)  

    However, I found another way to implement the boundary..

              System.Drawing.RectangleF r1 = new System.Drawing.RectangleF(0, 0, 1200, 800);
                _processor.InertiaProcessor.Boundary = r1;

                System.Drawing.RectangleF r2 = new System.Drawing.RectangleF(200, 50, 800, 700);
                _processor.InertiaProcessor.ElasticMargin = r2;

    This method works.. Except for sometime, the boundary do not work... =/
    Any ideas?



    Tuesday, September 15, 2009 1:33 AM
  • This method works.. Except for sometime, the boundary do not work... =/
    Any ideas?


    There are a few known quirks with elastic boundaries.  Are you checking for very large positive and negative values on the _IManipulationEvents::ManipulationCompleted event handler?  Sometimes, when ManipulationCompleted is forced by calls to ManipulationProcessor::Complete, the current manipulation is extrapolated resulting in large delta values.  These calls can be triggered by the inertia processor.

    Also, what managed wrapper are you using for the Manipulation / Inertia processor?
    Tuesday, September 15, 2009 2:27 PM
    Moderator
  • This method works.. Except for sometime, the boundary do not work... =/
    Any ideas?


    There are a few known quirks with elastic boundaries.  Are you checking for very large positive and negative values on the _IManipulationEvents::ManipulationCompleted event handler?  Sometimes, when ManipulationCompleted is forced by calls to ManipulationProcessor::Complete, the current manipulation is extrapolated resulting in large delta values.  These calls can be triggered by the inertia processor.

    Also, what managed wrapper are you using for the Manipulation / Inertia processor?
    I am using the wrapper from the example found in this link..
    http://code.msdn.microsoft.com/WindowsTouch/Release/ProjectReleases.aspx?ReleaseId=2127
    Tuesday, September 15, 2009 2:34 PM
  • I am using the wrapper from the example found in this link..
    http://code.msdn.microsoft.com/WindowsTouch/Release/ProjectReleases.aspx?ReleaseId=2127

    OK, I have played with Yochay's samples a bit.  The final change that you might want to try is to update your ProcessManipulationDelta method to check bounds (again, this is rather strange...).  For simplicity, I have hardcoded my example for 1024 x 768 and just reset the object position to an arbitrary x/y position on screen when the object goes out of bounds.

                if ((Picture.X + e.TranslationDelta.Width > 0 && Picture.X + e.TranslationDelta.Width < 1024))
                {
                    Picture.X += e.TranslationDelta.Width;
                }
                else
                {
                    if (Picture.X + e.TranslationDelta.Width < 0)
                    {
                        Picture.X = 1;
                    }
                    else
                    {                    
                        Picture.X = 1000;
                    }
                }
    
                if ((Picture.Y + e.TranslationDelta.Height > 0 && Picture.Y + e.TranslationDelta.Height < 768))
                {
                    Picture.Y += e.TranslationDelta.Height;
                }
                else
                {
                    if (Picture.Y + e.TranslationDelta.Height < 0)
                    {
                        Picture.Y = 1;
                    }
                    else
                    {
                        Picture.Y = 700;
                    }                
                }
    
    Tuesday, September 15, 2009 3:56 PM
    Moderator
  • I am using the wrapper from the example found in this link..
    http://code.msdn.microsoft.com/WindowsTouch/Release/ProjectReleases.aspx?ReleaseId=2127

    OK, I have played with Yochay's samples a bit.  The final change that you might want to try is to update your ProcessManipulationDelta method to check bounds (again, this is rather strange...).  For simplicity, I have hardcoded my example for 1024 x 768 and just reset the object position to an arbitrary x/y position on screen when the object goes out of bounds.

                if ((Picture.X + e.TranslationDelta.Width > 0 && Picture.X + e.TranslationDelta.Width < 1024))
                {
                    Picture.X += e.TranslationDelta.Width;
                }
                else
                {
                    if (Picture.X + e.TranslationDelta.Width < 0)
                    {
                        Picture.X = 1;
                    }
                    else
                    {                    
                        Picture.X = 1000;
                    }
                }
    
                if ((Picture.Y + e.TranslationDelta.Height > 0 && Picture.Y + e.TranslationDelta.Height < 768))
                {
                    Picture.Y += e.TranslationDelta.Height;
                }
                else
                {
                    if (Picture.Y + e.TranslationDelta.Height < 0)
                    {
                        Picture.Y = 1;
                    }
                    else
                    {
                        Picture.Y = 700;
                    }                
                }
    

    Hmm..
    I added in your codes and it seems abit jerky?
    It is very hard for me to explain..
    You can download the project file and take a look..
    Set MultitouchHOLSolution as start up project..
    Thanks
    Download Link :
    http://cid-8f095b2907113973.skydrive.live.com/self.aspx/.Public/Source.zip
    Wednesday, September 16, 2009 1:33 AM
  • Hmm..
    I added in your codes and it seems abit jerky?
    It is very hard for me to explain..
    You can download the project file and take a look..
    Set MultitouchHOLSolution as start up project..
    Thanks
    Download Link :
    http://cid-8f095b2907113973.skydrive.live.com/self.aspx/.Public/Source.zip

    I think I figured it out... it looks like you have an extra call to:

    Picture.X += e.TranslationDelta.Width;
    Picture.Y += e.TranslationDelta.Height;

    after the line:

     

    if (Picture == null)
    return;

    Here's my complete code for ProcessManipulationDelta:

     

            private void ProcessManipulationDelta(object sender, ManipulationDeltaEventArgs e)
            {
                if (Picture == null)
                    return;
    
                if ((Picture.X + e.TranslationDelta.Width > 0 && Picture.X + e.TranslationDelta.Width < 1024))
                {
                    Picture.X += e.TranslationDelta.Width;
                }
                else
                {
                    if (Picture.X + e.TranslationDelta.Width < 0)
                    {
                        Picture.X = 1;
                    }
                    else
                    {
                        Picture.X = 1000;
                    }
                }
    
                if ((Picture.Y + e.TranslationDelta.Height > 0 && Picture.Y + e.TranslationDelta.Height < 768))
                {
                    Picture.Y += e.TranslationDelta.Height;
                }
                else
                {
                    if (Picture.Y + e.TranslationDelta.Height < 0)
                    {
                        Picture.Y = 1;
                    }
                    else
                    {
                        Picture.Y = 700;
                    }
                }
    
                Picture.Angle += e.RotationDelta * 180 / Math.PI;
    
                Picture.ScaleX *= e.ScaleDelta;
                Picture.ScaleY *= e.ScaleDelta;
    
                //Update inertia calculation. Take 40 percent from the previos data
                _inertiaParam.Update(e, 0.4F);
            }
    
    I moved your check for

    if (picture == null)

    to the top, this should fail earlier.  I also removed the extra call to Picture (X/Y) += which was causing both the objects to get removed off of the screen and to have the objects move too quickly.

    Regards,
    Gus
    • Marked as answer by ChengTeck90 Thursday, September 17, 2009 1:18 AM
    Wednesday, September 16, 2009 5:13 PM
    Moderator
  • Hmm..
    I added in your codes and it seems abit jerky?
    It is very hard for me to explain..
    You can download the project file and take a look..
    Set MultitouchHOLSolution as start up project..
    Thanks
    Download Link :
    http://cid-8f095b2907113973.skydrive.live.com/self.aspx/.Public/Source.zip

    I think I figured it out... it looks like you have an extra call to:

    Picture.X += e.TranslationDelta.Width;
    Picture.Y += e.TranslationDelta.Height;

    after the line:

     

    if (Picture == null )
    return ;

    Here's my complete code for ProcessManipulationDelta:

     

            private void ProcessManipulationDelta(object sender, ManipulationDeltaEventArgs e)
    {
    if (Picture == null)
    return;


    if ((Picture.X + e.TranslationDelta.Width > 0 && Picture.X + e.TranslationDelta.Width < 1024))
    {
    Picture.X += e.TranslationDelta.Width;
    }
    else
    {
    if (Picture.X + e.TranslationDelta.Width < 0)
    {
    Picture.X = 1;
    }
    else
    {
    Picture.X = 1000;
    }
    }

    if ((Picture.Y + e.TranslationDelta.Height > 0 && Picture.Y + e.TranslationDelta.Height < 768))
    {
    Picture.Y += e.TranslationDelta.Height;
    }
    else
    {
    if (Picture.Y + e.TranslationDelta.Height < 0)
    {
    Picture.Y = 1;
    }
    else
    {
    Picture.Y = 700;
    }
    }

    Picture.Angle += e.RotationDelta * 180 / Math.PI;

    Picture.ScaleX *= e.ScaleDelta;
    Picture.ScaleY *= e.ScaleDelta;

    //Update inertia calculation. Take 40 percent from the previos data
    _inertiaParam.Update(e, 0.4F);
    }
    I moved your check for

    if (picture == null)

    to the top, this should fail earlier.  I also removed the extra call to Picture (X/Y) += which was causing both the objects to get removed off of the screen and to have the objects move too quickly.

    Regards,
    Gus
    Thanks alot man.. :)
    It worked nicely.. :)
    Thursday, September 17, 2009 1:18 AM
  • Hi,
    I have two requirements.

    1. Managing boundries for moving objects
    2. Manging Minimum size for image while somebody expands it using multi touch

    First requirement is fulfilled by last post.

    Now, I am not able to restric my image to scal down to the desired size. It should not scale down less than the desired size.

    Can anyone guide me on how to do that?

    One more thing....when I move the image by touching it ..the image moves exponentialy ahead of the touch point. Actually the image should be right in accordance with the touchpoint on the screen.

    I also like to have solution for both of the above issues.
    cool
    Wednesday, December 9, 2009 10:33 AM
  • For 2) You should use the put_MinimumScaleRotateRadius property of the manipulation processor in centipixels.
    Wednesday, December 9, 2009 11:17 PM
    Moderator