首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >数学:如何通过拖拽旋转车轮(画布,2D)?

数学:如何通过拖拽旋转车轮(画布,2D)?
EN

Stack Overflow用户
提问于 2020-01-09 16:11:19
回答 1查看 77关注 0票数 0

我很难用简单的数学来旋转/旋转一个轮子,使用拖拽。

在画布中有一个径向布局(Unity ),它已经可以通过设置一个名为StartAngle的属性来旋转,该属性的范围为0-360。在这个径向有项目,所以StartAngle是为第一个项目,并将所有的子元素周围的布局半径。

我想实现拖放的项目,以便您可以拖动一个孩子和径向将相应旋转(无限)。

现在,我的出发点是:

代码语言:javascript
复制
public void OnDrag(PointerEventData eventData)
{
    var delta = eventData.delta.x * Time.deltaTime;
    var newAngle = radialLayout.StartAngle + delta;
    if (newAngle >= 360)
        newAngle = newAngle - 360;
    else if (newAngle < 0)
        newAngle = Mathf.Abs(360 - newAngle);
    radialLayout.StartAngle = newAngle;
}

它有点工作,但感觉不太平稳。这是针对移动/触摸的,所以我希望同时考虑拖动操作的X和Y增量。显然,在我的例子中没有考虑yδ,我不知道如何正确地将它合并。用户可能会在任何一个轴上做直线拖放,或者他/她也可能做类似于圆形拖动的运动。

那么,我如何将鼠标移动映射到从0到360的旋转角度,以使它感觉良好?

编辑:谢谢你的帮助,我现在就这样做了:

代码语言:javascript
复制
public void OnDrag(PointerEventData eventData)
{
    // Note the "Head-Minus-Tale rule for Vector subtraction, see http://www.maths.usyd.edu.au/u/MOW/vectors/vectors-3/v-3-7.html
    //  vSourceToDestination = vDestination - vSource;

    // First, we draw a vector from the center point of the radial to the point where we started dragging
    var from = dragStartPoint - (Vector2)radialLayout.transform.position;
    // Next, we draw a vector from the center point of the radial to the point we are currently dragging on
    var to = eventData.position - (Vector2)radialLayout.transform.position;
    // Now, we calculate the angle between these two: 
    var dragAngle = Vector2.SignedAngle(from, to);

    // Lerping makes movement fast at the beginning slow at the end
    var lerpedAngle = Mathf.Round(Mathf.LerpAngle(radialLayout.StartAngle, dragAngle, 0.5f));
    radialLayout.StartAngle = lerpedAngle;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-01-09 17:26:45

我不知道你所有的代码和类型,但我会有一个主意。我现在不能测试这个,也不能保证它能像这样工作,但我希望这个想法能弄清楚。

我可能宁愿用这样的方法

代码语言:javascript
复制
// This is the vector from the center of the object to the mouse/touch position
// (in screen pixel space)
var touchDirection = eventData.position - Camera.main.WorldToScreenPoint(transform.position);
// angle between the Up (Y) axis and this touchDirection
// for the angle the length of the up vector doesn't matter so there is 
// no need to convert it to pixel space
var targetAngle = Vector2.SignedAngle(Vector2.up, touchDirection);
// since the returned angle might be negative wrap it to get values 0-360
if(targetAngle < 0) targetAngle += 360;

// Now either simply use Lerp
// this would simply interpolate each frame to the middle of both values
// the result is a fast movement at the beginning and a very slow at the end
radialLayout.StartAngle = Mathf.Lerp(radialLayout.StartAngle, targetAngle, 0.5f);

// or maybe use a fixed speed like 30°/second
var difference = targetAngle - radialLayout.StartAngle;
radialLayout.StartAngle += Mathf.Sign(difference) * Mathf.Min(30f * Time.deltaTime, Mathf.Abs(difference));

输入智能手机,但我希望这个想法能弄清楚

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59668026

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档