矩阵变换相邻精灵使子像素的差距 [英] matrix transforms on adjacent sprites causing subpixel gaps

查看:172
本文介绍了矩阵变换相邻精灵使子像素的差距的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有三个精灵,堆叠在彼此的顶部上。

我修正自己的transform.matrix给他们越来越一致的外观。

然而,小的裂缝取决于比例因子的瓷砖之间有时会出现。

我想知道如何解决这个问题。

我知道<一个href="http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/text/TextField.html#gridFitType"相对=nofollow> AS3中的文本对象有子像素渲染的选项。也许一个类似的设置存在于所有AS3的?其他的想法?

战术不工作:将cacheAsBitmap

 包
{

进口flash.display.Sprite;
进口flash.geom.Matrix;
进口flash.geom.Point;

进口mx.core.UIComponent在;

公共类TMPA扩展UIComponent的
{

私人VAR _scale:数字;

私人VAR _s1:雪碧;
私人VAR _s2:雪碧;
私人VAR _s3:雪碧;

私人VAR _s1Pt:点;
私人VAR _s2Pt:点;
私人VAR _s3Pt:点;

私人VAR _tileDim:INT;


公共职能TMPA():无效
{
_scale = 1;
_tileDim = 100;

_s1 =新的Sprite();
_s2 =新的Sprite();
_s3 =新的Sprite();

paintSprite(_s1,_tileDim);
paintSprite(_s2,_tileDim);
paintSprite(_s3,_tileDim);

_s1Pt =新的点(100,_tileDim);
_s1.x = _s1Pt.x;
_s1.y = _s1Pt.y;
_s2Pt =新的点(100,_tileDim * 2);
_s2.x = _s2Pt.x;
_s2.y = _s2Pt.y;
_s3Pt =新点(100,_tileDim * 3);
_s3.x = _s3Pt.x;
_s3.y = _s3Pt.y;

的addChild(_s1);
的addChild(_s2);
的addChild(_s3);

规模= 1.0394; //裂缝
//规模= 1.0306; // nocracks
}

私有函数paintSprite(S:雪碧,暗淡:INT,颜色:INT =为0xFF0000):无效
{s.graphics.beginFill(颜色,0.5);
s.graphics.drawRect(0,0,朦胧,朦胧);
s.graphics.endFill();
}


公共功能集规模​​(S:编号):无效
{_scale =秒;

VAR scaleFromPt:点=新的点(20,20);
updateSpriteMatrix(_s1,_s1.globalToLocal(scaleFromPt),_s1Pt);
updateSpriteMatrix(_s2,_s2.globalToLocal(scaleFromPt),_s2Pt);
updateSpriteMatrix(_s3,_s3.globalToLocal(scaleFromPt),_s3Pt);
}

公共函数来获取规模():数
{返回_scale;
}

私有函数updateSpriteMatrix(T:雪碧,ctrPt:点,regPt:点):无效
{VAR MX:矩阵= t.transform.matrix;
mx.identity();
mx.scale(_scale,_scale);
mx.translate(ctrPt.x *(1-_scale),ctrPt.y *(1-_scale));
mx.translate(regPt.x,regPt.y);
t.transform.matrix = MX;
}

}
}
 

和的MXML:

 &LT; MX:应用的xmlns:MX =htt​​p://www.adobe.com/2006/mxml
的xmlns:一个=*
宽度=100%高度=100%
paddingTop =0paddingBottom会=0以下属性来=0paddingRight =0
的backgroundColor =0x000000处
backgroundGradientAlphas =未定义&GT;
&其中;一个:TMPA的id =吨宽度=100%高度=100%×=0Y =0左=0顶=0/&GT;
&LT; / MX:用途&gt;
 

解决方案

究其原因有差距是由于舍入误差。闪存只能定位元素降到1二十像素(缇)的。你在

设置y的位置
  • 3.152000000000008
  • 7.092000000000018
  • 11.032000000000028

分别。显然,这是比二十分之一那么四舍五入发生多precise。一旦发生四舍五入你是容易出错。

在我看来,你应该把所有的项目里面的一些其他的容器,然后扩展的容器。这就是你只能执行一个转换,但得到同样的结果。

不过据我所知,可能需要对这种方法在某些情况下。这一轮的方法是执行所有规模的改造第一。然后,执行相对于previous精灵的翻译。这样,它总是要立足于previously四舍五入药水。这里有一个简单的例子砍死你的类。显然,有很多种方法来组织这一点,但我一直在努力,坚持的玩具你工作简单的方式。

 包
{

进口flash.display.Sprite;
进口flash.geom.Matrix;
进口flash.geom.Point;

进口mx.core.UIComponent在;

公共类TMPA扩展UIComponent的
{

        私人VAR _scale:数字;

        私人VAR _s1:雪碧;
        私人VAR _s2:雪碧;
        私人VAR _s3:雪碧;

        私人VAR _s1Pt:点;
        私人VAR _s2Pt:点;
        私人VAR _s3Pt:点;

        私人VAR _tileDim:INT;


        公共职能TMPA():无效
        {
                _scale = 1;
                _tileDim = 100;

                _s1 =新的Sprite();
                _s2 =新的Sprite();
                _s3 =新的Sprite();

                paintSprite(_s1,_tileDim);
                paintSprite(_s2,_tileDim);
                paintSprite(_s3,_tileDim);

                _s1Pt =新的点(100,_tileDim);
                _s1.x = _s1Pt.x;
                _s1.y = _s1Pt.y;
                _s2Pt =新的点(100,_tileDim * 2);
                _s2.x = _s2Pt.x;
                _s2.y = _s2Pt.y;
                _s3Pt =新点(100,_tileDim * 3);
                _s3.x = _s3Pt.x;
                _s3.y = _s3Pt.y;

                _s1.transform.matrix =新的Matrix();
                _s2.transform.matrix =新的Matrix();
                _s3.transform.matrix =新的Matrix();

                的addChild(_s1);
                的addChild(_s2);
                的addChild(_s3);

                规模= 1.0394; //裂缝
                //规模= 1.0306; // nocracks
        }

        私有函数paintSprite(S:雪碧,暗淡:INT,颜色:INT =为0xFF0000):无效
        {s.graphics.beginFill(颜色,0.5);
                s.graphics.drawRect(0,0,朦胧,朦胧);
                s.graphics.endFill();
        }

        公共功能集规模​​(S:编号):无效
        {_scale =秒;

                scaleSpriteMatrix(_s1);
                scaleSpriteMatrix(_s2);
                scaleSpriteMatrix(_s3);

                translateSprite(_s2,_s1);
                translateSprite(_s3,_s2);
        }

        公共函数来获取规模():数
        {返回_scale;
        }

        私有函数scaleSpriteMatrix(targetSprite:雪碧):无效
        {VAR MX:矩阵= targetSprite.transform.matrix;
                mx.scale(_scale,_scale);
                targetSprite.transform.matrix = MX;
        }

        私有函数translateSprite(targetSprite:雪碧,basedOnSprite:雪碧):无效
        {VAR MX:矩阵= targetSprite.transform.matrix;
                mx.translate(basedOnSprite.x,basedOnSprite.y + basedOnSprite.height);
                targetSprite.transform.matrix = MX;
        }

}
}
 

希望帮助

詹姆斯

I have three sprites, stacked on top of each other.

I modify their transform.matrix to give the appearance they are growing in unison.

However, small cracks sometimes appear between the tiles depending on the scaling factor.

I am wondering how to fix this.

I know that text objects in AS3 have options for sub-pixel rendering. Maybe a similiar setting exists for all of AS3? Other ideas?

Tactics which don't work: cacheAsBitmap.

package
{

import flash.display.Sprite;
import flash.geom.Matrix;
import flash.geom.Point;

import mx.core.UIComponent;

public class tmpa extends UIComponent
{

	private var _scale:Number;

	private var _s1:Sprite;
	private var _s2:Sprite;
	private var _s3:Sprite;

	private var _s1Pt:Point;
	private var _s2Pt:Point;
	private var _s3Pt:Point;

	private var _tileDim:int;


	public function tmpa( ):void
	{
		_scale = 1;
		_tileDim = 100;

		_s1 = new Sprite();
		_s2 = new Sprite();
		_s3 = new Sprite();

		paintSprite( _s1, _tileDim );
		paintSprite( _s2, _tileDim );
		paintSprite( _s3, _tileDim );

		_s1Pt = new Point( 100, _tileDim );
		_s1.x = _s1Pt.x;
		_s1.y = _s1Pt.y;
		_s2Pt = new Point( 100, _tileDim*2 );
		_s2.x = _s2Pt.x;
		_s2.y = _s2Pt.y;
		_s3Pt = new Point( 100, _tileDim*3 );
		_s3.x = _s3Pt.x;
		_s3.y = _s3Pt.y;

		addChild( _s1 );
		addChild( _s2 );
		addChild( _s3 );

		scale = 1.0394; //cracks
		//scale = 1.0306; // nocracks
	}

	private function paintSprite( s:Sprite, dim:int, color:int=0xFF0000 ):void
	{	s.graphics.beginFill( color, .5 );
		s.graphics.drawRect( 0, 0, dim, dim );
		s.graphics.endFill( );
	}


	public function set scale( s:Number ):void
	{	_scale = s;

		var scaleFromPt:Point = new Point( 20, 20 );
		updateSpriteMatrix( _s1, _s1.globalToLocal(scaleFromPt), _s1Pt );
		updateSpriteMatrix( _s2, _s2.globalToLocal(scaleFromPt), _s2Pt );
		updateSpriteMatrix( _s3, _s3.globalToLocal(scaleFromPt), _s3Pt );
	}

	public function get scale( ):Number
	{	return _scale;
	}

	private function updateSpriteMatrix( t:Sprite, ctrPt:Point, regPt:Point ):void
	{	var mx:Matrix = t.transform.matrix;
		mx.identity();
		mx.scale( _scale, _scale );
		mx.translate( ctrPt.x*(1-_scale), ctrPt.y*(1-_scale));
		mx.translate( regPt.x, regPt.y );
		t.transform.matrix = mx;
	}

}
}

And the mxml:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
			xmlns:a="*"
			width="100%" height="100%"
			paddingTop="0" paddingBottom="0" paddingLeft="0" paddingRight="0"
			backgroundColor="0x000000"
			backgroundGradientAlphas="undefined">
	<a:tmpa id="t" width="100%" height="100%" x="0" y="0" left="0" top="0"/>
</mx:Application>

解决方案

The reason there are gaps is due to rounding errors. Flash can only position elements down to 1 twentieth of a pixel (a twip). You were setting the y positions at

  • 3.152000000000008
  • 7.092000000000018
  • 11.032000000000028

respectively. Obviously this is much more precise than a twentieth so rounding occurs. Once rounding happens you are prone to errors.

In my opinion you should be putting all the items inside some other container and then scaling the container. The way you only perform one transform but get the same result.

However i understand there may be a need for this method in some situations. The way round this is to perform all the scale transforms first. Then perform the translations relative to the previous sprite. That way it's always going to be based on the previously rounded potion. Here's a quick example hacked out of your class. Obviously there are many ways to organise this but I've tried to stick toy the way you work for simplicity.

package
{

import flash.display.Sprite;
import flash.geom.Matrix;
import flash.geom.Point;

import mx.core.UIComponent;

public class tmpa extends UIComponent
{

        private var _scale:Number;

        private var _s1:Sprite;
        private var _s2:Sprite;
        private var _s3:Sprite;

        private var _s1Pt:Point;
        private var _s2Pt:Point;
        private var _s3Pt:Point;

        private var _tileDim:int;


        public function tmpa( ):void
        {
                _scale = 1;
                _tileDim = 100;

                _s1 = new Sprite();
                _s2 = new Sprite();
                _s3 = new Sprite();

                paintSprite( _s1, _tileDim );
                paintSprite( _s2, _tileDim );
                paintSprite( _s3, _tileDim );

                _s1Pt = new Point( 100, _tileDim );
                _s1.x = _s1Pt.x;
                _s1.y = _s1Pt.y;
                _s2Pt = new Point( 100, _tileDim*2 );
                _s2.x = _s2Pt.x;
                _s2.y = _s2Pt.y;
                _s3Pt = new Point( 100, _tileDim*3 );
                _s3.x = _s3Pt.x;
                _s3.y = _s3Pt.y;

                _s1.transform.matrix = new Matrix();
                _s2.transform.matrix = new Matrix();
                _s3.transform.matrix = new Matrix();

                addChild( _s1 );
                addChild( _s2 );
                addChild( _s3 );

                scale = 1.0394; //cracks
                //scale = 1.0306; // nocracks
        }

        private function paintSprite( s:Sprite, dim:int, color:int=0xFF0000 ):void
        {       s.graphics.beginFill( color, .5 );
                s.graphics.drawRect( 0, 0, dim, dim );
                s.graphics.endFill( );
        }

        public function set scale( s:Number ):void
        {       _scale = s;

                scaleSpriteMatrix( _s1 );
                scaleSpriteMatrix( _s2 );
                scaleSpriteMatrix( _s3 );

                translateSprite(_s2, _s1);
                translateSprite(_s3, _s2);
        }

        public function get scale( ):Number
        {       return _scale;
        }

        private function scaleSpriteMatrix( targetSprite:Sprite):void
        {       var mx:Matrix = targetSprite.transform.matrix;
                mx.scale( _scale, _scale );
                targetSprite.transform.matrix = mx;
        }

        private function translateSprite( targetSprite:Sprite, basedOnSprite:Sprite):void
        {       var mx:Matrix = targetSprite.transform.matrix;
                mx.translate( basedOnSprite.x, basedOnSprite.y + basedOnSprite.height);
                targetSprite.transform.matrix = mx;
        }

}
}

Hope that helps

James

这篇关于矩阵变换相邻精灵使子像素的差距的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆