1 of 4
1
Touchlib rotate scale bug
Posted: 08 June 2008 06:52 PM   [ Ignore ]
New Member
Rank
Total Posts:  87
Joined  2007-10-23

I’ve seen this bug everywhere and I realised that my AS3 classes didn’t have the bug that means the object doesn’t rotate and scale around the correct point.

Profile
 
 
Posted: 08 June 2008 07:56 PM   [ Ignore ]   [ # 1 ]
Administrator
Avatar
RankRankRankRank
Total Posts:  1358
Joined  2007-04-08

Yes, the rotation is around the center point, not around the point between the fingers. We hadn’t implemented that yet.

Since you seem to fix it, can you post the class? I’ve been meaning to add in the fix, but didn’t have time. I’m sure you thought of a better way to do it than I would have anyway =)

 Signature 

My Multitouch Blog
My Youtube
Multitouch FAQ - Need Help? Click here!

Profile
 
 
Posted: 08 June 2008 08:11 PM   [ Ignore ]   [ # 2 ]
Administrator
Avatar
RankRankRankRank
Total Posts:  537
Joined  2006-11-09

Yea this is a great fix… I’ve been meaning to fix this for a while :/

Thanks weyforth! smile

 Signature 

~

Profile
 
 
Posted: 09 June 2008 08:43 AM   [ Ignore ]   [ # 3 ]
New Member
Rank
Total Posts:  87
Joined  2007-10-23

Thanks guys. A bit more information about it: Since I have build my classes from the ground up they are different than those in the touchlib SVN, so there is no straightforward way of updating the SVN classes without alot of reworking. If I have time I’ll try and work the fix in, but I’m a bit busy this week and so I won’t will be able to get on it for a while.

Profile
 
 
Posted: 09 June 2008 01:04 PM   [ Ignore ]   [ # 4 ]
Administrator
Avatar
RankRankRankRank
Total Posts:  1358
Joined  2007-04-08

Well, I’m more interested in the way you choose to fix it as we have a way to fix, just haven’t implemented it. I’m interested to see if your way is different and/or better/easier. So if you could just explain the way you’re doing it, that would be better. You’re not using the dynamic registration class are you?

 Signature 

My Multitouch Blog
My Youtube
Multitouch FAQ - Need Help? Click here!

Profile
 
 
Posted: 09 June 2008 01:38 PM   [ Ignore ]   [ # 5 ]
New Member
Rank
Total Posts:  87
Joined  2007-10-23

Yes I’m using the dynamic registration class, is this the method you have in mind? If so then it’s probably the right way to go, I’m sure someone could come up with some complex maths to do the same thing but for simplicity’s sake the dynamic registration class works fine, you just have to remember to use the extra properties instead of the normal ones (as I have forgotton to do to my frustration many times)

Profile
 
 
Posted: 09 June 2008 01:43 PM   [ Ignore ]   [ # 6 ]
Administrator
Avatar
RankRankRankRank
Total Posts:  1358
Joined  2007-04-08

Yup. Just never had time to implement it.

So are you just putting every movable object into a dynamic registration, moving that registration point to be in between the center of the 2 fingers, and then using the x2, y2, rotation2, scaleX2, scaleY2 etc to move and rotate?

I’m thinking since just about all the classes use the rotateablesclable class for moving/scaling/rotating, it might be possible to just integrate it into using the dynamic registration class. This way, wouldn’t have to go in and edit every application (just compile it with the updated rotateablesclable class).

I’ll look into it tonight to see if it’ll be as simple as updating the rotateablesclable class.

 Signature 

My Multitouch Blog
My Youtube
Multitouch FAQ - Need Help? Click here!

Profile
 
 
Posted: 09 June 2008 01:51 PM   [ Ignore ]   [ # 7 ]
New Member
Rank
Total Posts:  87
Joined  2007-10-23

Yes thats exactly how I’m doing it. I created a class like the Multitouchable class in the SVN which simply handles the collecting of blobs (except with a few modifications so you can set the maximum blobs, and so you don’t have to worry about checking fot blobs existing outside this class which always annoyed me). This class extends the dynamic registration class and then the rotate/scale class extends Multitouchable

I suppose you could just integrate the methods into the rotate scale class yes; I’m still thinking if my methods are the most effecient way to do things

Profile
 
 
Posted: 09 June 2008 02:00 PM   [ Ignore ]   [ # 8 ]
Administrator
Avatar
RankRankRankRank
Total Posts:  1358
Joined  2007-04-08

Yeah, i’ll have to see which way I do it for now. I’m not sure if it would be optimized to have the multitouchable class use the dynamic registration class since not all things that will use multitouchable class will want to scale, move, or rotate and that means you’re using the added dynamic registration when it’s not needed (or do you have a way around that)? That is why I was thinking of just adding it to the rotate/scale class maybe since objects that are moving/rotating/scaling will be using one of those classes.

I know you and nuiman have talked before, maybe we can get a chance to talk live together (you, me and nuiman/cmoore). If you’re willing to release any of your stuff, it would be nice to contribute to the same project if possible and make the current SVN better.

 Signature 

My Multitouch Blog
My Youtube
Multitouch FAQ - Need Help? Click here!

Profile
 
 
Posted: 09 June 2008 02:17 PM   [ Ignore ]   [ # 9 ]
New Member
Rank
Total Posts:  87
Joined  2007-10-23

Cool sounds good. I’m the middle of exams at school at the moment but when they’re over I’ve got a few months free! I’ll be submitting to the showcase forum soon as well to show some of the applications I’ve been working on smile

About the multitouchable class extending the dynamic registration class there isn’t alot of heavy programing in it, and it’s methods are only really used when dynamic registration is needed (i.e. when using x2, y2 etc.) If you use normal x, y etc. properties it’s just like extending the normal Sprite or Movieclip sprite. I’ll look more into it, as I’ve altered the dynamic registration class slightly to make it function slightly better.

Profile
 
 
Posted: 15 June 2008 10:10 PM   [ Ignore ]   [ # 10 ]
New Member
Rank
Total Posts:  31
Joined  2007-07-10

Can you share you code here? I tried your solution but I’m experiencing a flickering.

Profile
 
 
Posted: 17 June 2008 12:26 PM   [ Ignore ]   [ # 11 ]
New Member
Rank
Total Posts:  31
Joined  2007-07-10
weyforth - 09 June 2008 01:38 PM

I’m using the dynamic registration class

I tried this solution after I read this post, but I had many problems. I suppose that you use this class DYNAMIC MOVIECLIP REGISTRATION WITH AS3

In Flex the scaleX2 and scaleY2 doesn’t work, but I found a fix. If any is trying to use DynamicMovieClip in Flex, this is my fix:

public function setProperty2(prop:Stringn:Number):void
{
    
var a:Point this.parent.globalToLocal(this.localToGlobal(rp));

    
this[prop] n;

    
// La propiedad de rotación pertenece a DisplayObject y hace el render
    // de inmediato, mientras que las propiedades scaleX y scaleY pertenecen
    // a UIComponent y el render no se hace de inmediato
    
if (prop == "rotation"finishSetProperty(a);
    else 
callLater(finishSetProperty[a]);
}
        
private function finishSetProperty(a:Point):void
{
    
var b:Point this.parent.globalToLocal(this.localToGlobal(rp));

    
this.-= b.a.x;
    
this.-= b.a.y;
}

I had other problems whit DynamicMovieClip, so I tried another solution and use matrix transformations. I rewrite the RotateScale class and extends Multitouchable. There is the important part of the code of RotateScale, so others can implement my solution. The function doTransform has the code that translate, rotate and scale around an internal point:

public override function handleDownEvent(id:intmx:Numbermy:Number
    
targetObj:Object):void
{
    
var curPt1:PointcurPt2:Point;

    
// Si solo hay un blob en el control, se pasa al estado dragging, para 
    // indicar que el control se va a mover
    
if (blobs.length == 1)
    
{
        state 
"dragging";
        
blob1 blobs[0];
        
// La posición de los blob están definidas con respecto al origen del
        // control y se deben convertir a las coordenadas del control padre
        
curPt1 this.localToParent( new Point(blob1.xblob1.y) );
        
blob1.oldX curPt1.x;
        
blob1.oldY curPt1.y;
    
// Si hay dos blob en el control, se pasa al estado rotatescale, para
    // indicar que el control se va a rotar y escalar
    
}
    
else if(blobs.length == 2)
    
{
        state 
"rotatescale";
            
        
blob1 blobs[0];                                
        
curPt1 this.localToParent( new Point(blob1.xblob1.y) );                                    
        
blob1.oldX curPt1.x;
        
blob1.oldY curPt1.y;

        
blob2 blobs[1];        
        
curPt2 this.localToParent( new Point(blob2.xblob2.y) );    
        
blob2.oldX curPt2.x;
        
blob2.oldY curPt2.y;
    
}
}

public override function handleMoveEvent(id:intmx:Numbermy:Number
    
targetObj:Object):void
{
    
var dx:Number 0;
    var 
dy:Number 0;
    var 
da:Number 0;
    var 
ds:Number 1;
    
    if (
state == "dragging")
    
{
        
if(this._moveEnabled)
        
{
            
var tuioObj:TUIOObject TUIO.getObjectById(blob1.id);
            if (!
tuioObj)
            
{
                handleBlobRemoved
(blob1.id);
                return;
            
}
            
var curPt:Point parent.globalToLocal(new Point(tuioObj.xtuioObj.y));
            
dx curPt.blob1.oldX;
            
dy curPt.blob1.oldY;
            
blob1.oldX curPt.x;
            
blob1.oldY curPt.y;
            
this.doTransform(dxdy01);
        
}
    }
    
else if (state == "rotatescale")
    
{
        
var tuioObj1:TUIOObject TUIO.getObjectById(blob1.id);
        if (!
tuioObj1)
        
{
            handleBlobRemoved
(blob1.id);
            return;
        
}
        
var curPt1:Point parent.globalToLocal(new Point(tuioObj1.xtuioObj1.y));

        var 
tuioObj2:TUIOObject TUIO.getObjectById(blob2.id);
        if (!
tuioObj2)
        
{
            handleBlobRemoved
(blob2.id);
            return
        
}
        
var curPt2:Point parent.globalToLocal(new Point(tuioObj2.xtuioObj2.y));
        
        
// Halla el centro entre los dos blob en coordenadas locales del
        // componente padre
        
var curCenter:Point Point.interpolate(curPt1curPt20.5);

        
// Obtiene el punto de registro sobre el que se hará la rotación y
        // el escalado y lo convierte a coordenadas locales para asignarlo
        
var regPt:Point this.globalToLocal(this.parent.localToGlobal(curCenter));
        
this.setRegistration(regPt.xregPt.y);
        
        if (
this._moveEnabled)
        
{
            
// Obtiene el centro anterior en coordenadas del componente padre
            
var oldPt1:Point = new Point(blob1.oldXblob1.oldY);
            var 
oldPt2:Point = new Point(blob2.oldXblob2.oldY);
            var 
oldCenter:Point Point.interpolate(oldPt1oldPt20.5);

            
dx curCenter.oldCenter.x;
            
dy curCenter.oldCenter.y;
        
}

        
if (this._rotateEnabled)
        
{
            
// Halla una línea con origen en la posición 0,0 del componente padre y 
            // paralela a la línea formada por la posición anterior de los blob 
            
var oldLine:Point oldPt1;
            
oldLine oldLine.subtract(oldPt2);
            var 
oldAngle:Number getAngleTrig(oldLine.xoldLine.y);

            
// Halla una línea con origen en la posición 0,0 del componente padre y 
            // paralela a la línea formada por la posición actual de los blob
            
var curLine:Point curPt1;
            
curLine curLine.subtract(curPt2);
            var 
curAngle:Number getAngleTrig(curLine.xcurLine.y);
        
            
da curAngle oldAngle;
        
}
        
        
if (this._scaleEnabled)
        
{
            
// Halla la distancia entre las posiciones de los blob anteriores
            // y los blob actuales para determinar la escala
            
var oldLenght:Number Point.distance(oldPt1oldPt2);
            var 
curLenght:Number Point.distance(curPt1curPt2);
            
            
ds curLenght oldLenght;
        
}
        
        this
.doTransform(dxdydads);
        
        
// Los puntos actuales se convierten en las coordenadas viejas
        // para el siguiente ciclo
        
blob1.oldX curPt1.x;
        
blob1.oldY curPt1.y;
        
blob2.oldX curPt2.x;
        
blob2.oldY curPt2.y;
    
}
}

public function doTransform(dx:Numberdy:Numberda:Numberds:Number):void
{
    
var matrix:Matrix = new Matrix();

    
// Configura la matriz de transformación y la concatena con la matriz del
    // componente. 
     
matrix.translate(-this._x2, -this._y2);
    
matrix.rotate(da Math.PI 180);
    
matrix.scale(dsds);
    
matrix.translate(this._x2this._y2);
    
matrix.concat(this.transform.matrix);
    
matrix.translate(dxdy);
    
    
this.transform.matrix matrix;
}

public function setRegistration(x:Numbery:Number):void
{
    this
._x2 x;
    
this._y2 y;
}

private function localToParent(pt:Point):Point
{
    
return parent.globalToLocal(this.localToGlobal(pt));
}

Profile
 
 
Posted: 17 June 2008 12:55 PM   [ Ignore ]   [ # 12 ]
Administrator
Avatar
RankRankRankRank
Total Posts:  1358
Joined  2007-04-08

Cool camilosw, if this works you’ve saved me some time wink

I’ll test this out soon and if it works right, i’ll commit it to the svn. I’ll probably have to implement the other method too (non matrix) to test to see which is faster. Do you mind adding comments in English to yours?

 Signature 

My Multitouch Blog
My Youtube
Multitouch FAQ - Need Help? Click here!

Profile
 
 
Posted: 17 June 2008 01:04 PM   [ Ignore ]   [ # 13 ]
New Member
Rank
Total Posts:  87
Joined  2007-10-23

Yeh this is great, I’m wondering which method is faster as well, but I have to say I do like the matrix method. I might try implementing it into the dynamic registration class

Profile
 
 
Posted: 17 June 2008 01:55 PM   [ Ignore ]   [ # 14 ]
New Member
Rank
Total Posts:  31
Joined  2007-07-10

You also saved me many time with the code in the svn wink

My english is not so good so translate the comments in a correct way take a lot of time to me and I don’t have many time at this moment. I tried to name the variables and functions and structure the code in a way that any can undestand it easily.

Profile
 
 
Posted: 17 June 2008 02:12 PM   [ Ignore ]   [ # 15 ]
Administrator
Avatar
RankRankRankRank
Total Posts:  1358
Joined  2007-04-08

That’s fine, I should be able to translate them decently. I’ll try to get to this this week.

 Signature 

My Multitouch Blog
My Youtube</