场景是我在白色背景FrameLayout中有一个带有自定义绘图的视图。没有旋转它只是一个扁平的圆圈。但是我已经使用
设置了视图的rotationX(3D x轴)View.setRotationX(50f);
看起来像这样:
如果是圆形视图,我可以很容易地获得带有视线的黑色圆圈的位置,因为它与框架布局的大小相同。意思是如果它在X(32),Y(100)上,它在帧布局上的位置是X(32),Y(100)。但是如果旋转视图并且FrameLayout不是,我如何在FrameLayout上获得其正确的相对位置X和Y?
我只能提供的是当视图还未旋转时视点上的XY位置。
答案 0 :(得分:1)
显然我错了,因为透视投影,仅计算旋转X并不容易。所以,你可以这样做,yStar将在视图的顶部为1,在底部为-1,对于x坐标,你可以使用相同的触摸,因为你在x轴上旋转它赢了改变
final float rotationDegrees = 45 ;
final double rotationRadians = Math.toRadians(rotationDegrees);
final double ninetyDegrees = Math.toRadians(90);
customView.setRotationX(rotationDegrees);
frameLayout.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
float cy = frameLayout.getHeight() / 2;
float yt = (event.getY() - cy) / -cy;
double ms = Math.tan(ninetyDegrees + rotationRadians);
double targetX = (yt-ms) / ms;
double targetY = (Math.pow(yt, 2) - yt*ms) / ms;
double yStar = Math.sqrt(Math.pow(targetX- -1, 2) + Math.pow(targetY- 0, 2));
if(targetY>0) yStar *= -1;
Log.d("MainActivity", String.valueOf(yStar));
}
return true;
}
});
说明:
想象一下,从(1; 1)到(1; -1)的右边的段是你的FrameLayout,从侧面看。左边的行从(-1; 1)到(-1; -1)是您的自定义视图,而不是旋转。 A是您触摸FrameLayout的点。 R是触摸的投影,它穿过原点,这是焦点。 S是旋转视图所在的行。 B是旋转视图上投射FrameLayout上的触摸的点。旋转视图上触摸的y坐标(yStar)是B和F之间的距离(F是自定义视图的中心)
一旦你掌握了所有线条的图片,并指出如何计算yStar:
yt = FrameLayout上触摸的y坐标,在-1和1之间缩放
A =(1; yt)
R =(x-1)/ - 1 =(y-yt)/ -yt - >线穿过A和原点
R = y = -yt((x-1)/ -1)+ yt
R = y = -yt *( - x + 1)+ yt
R = y = yt * x
S = y = ms * x + ms - >斜率ms通过F(-1; 0)的线
ms = tan(90 + rotationAngle)
B将是R和S之间的交叉点,如果它们具有相同的斜率(ms = yt),则不会有交点。 所以
yt * x = ms * x + ms
yt * x - ms * x = ms
x *(yt - ms)= ms
x =(yt-ms)/ ms - > B的x坐标
y = yt *((yt - ms)/ ms)
y =(yt ^ 2 - yt * ms)/ ms - > B的y坐标
现在计算距离F的距离,如果y低于F,则乘以-1。