我正在试图弄清楚如何将鼠标位置(屏幕坐标)转换为在direct2d表面上绘制的底层变换图像上的相应点。 这里的代码应该被认为是伪代码,因为我正在使用针对c#的direct2d修改过的c ++ / CLI包装器,你将无法在我自己的项目中编译它。
Render()
{
//The transform matrix combines a rotation, followed by a scaling then a translation
renderTarget.Transform = _rotate * _scale * _translate;
RectF imageBounds = new RectF(0, 0, _imageSize.Width, _imageSize.Height);
renderTarget.DrawBitmap(this._image, imageBounds, 1, BitmapInterpolationMode.Linear);
}
Zoom(float zoomfactor, PointF mousepos)
{
//mousePos is in screen coordinates. I need to convert it to image coordinates.
Matrix3x2 t = _translate.Invert();
Matrix3x2 s = _scale.Invert();
Matrix3x2 r = _rotate.Invert();
PointF center = (t * s * r).TransformPoint(mousePos);
_scale = Matrix3x2.Scale(zoomfactor, zoomfactor, center);
}
这是不正确的,当缩放因子平滑地增大或减小时,缩放中心开始疯狂地移动,即使鼠标指针在客户端表面的中心处不动,所得到的缩放功能也不平滑并且闪烁很多。我尝试了所有我能想到的组合,但无法理解。
如果我将刻度中心点设置为(imagewidth / 2,imageheight / 2),则得到的缩放是平滑的,但总是以图像中心为中心,所以我很确定闪烁不是由于其他一些这个程序的错误部分。
感谢。
答案 0 :(得分:0)
我终于做对了
这让我在客户中心的中心完全平滑(增量?,相对?)缩放 (我放弃了鼠标位置的想法,因为我想使用鼠标移动输入来驱动缩放)
protected float zoomf
{
get
{
//extract scale factor from scale matrix
return (float)Math.Sqrt((double)((_scale.M11 * _scale.M11)
+ (_scale.M21 * _scale.M21)));
}
}
public void Zoom(float factor)
{
factor = Math.Min(zoomf, 1) * 0.006f * factor;
factor += 1;
Matrix3x2 t = _translation;
t.Invert();
PointF center = t.TransformPoint(_clientCenter);
Matrix3x2 m = Matrix3x2.Scale(new SizeF(factor, factor), center);
_scale = _scale * m;
Invalidate();
}
答案 1 :(得分:0)
Step1:把android:scaleType =" matrix"在ImageView XML文件中 第2步:将屏幕触摸点转换为Matrix值。 第3步:将每个矩阵值除以屏幕密度参数 在所有屏幕中获得相同的坐标值。
**XML**
<ImageView
android:id="@+id/myImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="matrix"
android:src="@drawable/ga"/>
**JAVA**
@Override
public boolean onTouchEvent(MotionEvent event) {
float[] point = new float[]{event.getX(), event.getY()};
Matrix inverse = new Matrix();
getImageMatrix().invert(inverse);
inverse.mapPoints(point);
float density = getResources().getDisplayMetrics().density;
int[] imagePointArray = new int[2];
imagePointArray[0] = (int) (point[0] / density);
imagePointArray[1] = (int) (point[1] / density);
Rect rect = new Rect( imagePointArray[0] - 20, imagePointArray[1] - 20, imagePointArray[0] + 20, imagePointArray[1] + 20);//20 is the offset value near to the touch point
boolean b = rect.contains(267, 40);//267,40 are the predefine image coordiantes
Log.e("Touch inside ", b + "");
return true;
}