Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在两个顶点高度可定制的点之间沿弧线路径查找航路点&;距离_C#_Unity3d_Trigonometry - Fatal编程技术网

C# 在两个顶点高度可定制的点之间沿弧线路径查找航路点&;距离

C# 在两个顶点高度可定制的点之间沿弧线路径查找航路点&;距离,c#,unity3d,trigonometry,C#,Unity3d,Trigonometry,我有一个功能性脚本,可以在两个游戏对象(vector3)之间为cinemachine轨迹创建一条弧,我想添加一个变量,以便控制弧的高度,如图所示: 目前,我所使用的方法是基于两点之间距离的半径创建圆弧,我希望能够控制圆弧的高度,以便它计算出与图中绘制的线类似的点。以及控制最大高度出现在弧中与posA和posB之间的距离相关的位置 下面是我用来创建当前圆弧的代码,用于计算半径为两点之间距离一半的圆弧: static void CalcWaypoints(CinemachineSmoothPath

我有一个功能性脚本,可以在两个游戏对象(vector3)之间为cinemachine轨迹创建一条弧,我想添加一个变量,以便控制弧的高度,如图所示:

目前,我所使用的方法是基于两点之间距离的半径创建圆弧,我希望能够控制圆弧的高度,以便它计算出与图中绘制的线类似的点。以及控制最大高度出现在弧中与posA和posB之间的距离相关的位置

下面是我用来创建当前圆弧的代码,用于计算半径为两点之间距离一半的圆弧:

static void CalcWaypoints(CinemachineSmoothPath path, Vector3 posA, Vector3 posB)
{
    int greenRingPointsNum = 8;
    float metersPerWaypoint = 10;
    //Here we calculate how many segments will fit between the two points
    int segmentsToCreate = Mathf.RoundToInt(Vector3.Distance(posA, posB) / metersPerWaypoint);
    path.m_Waypoints = new CinemachineSmoothPath.Waypoint[segmentsToCreate + greenRingPointsNum];
    Debug.Log("Creating " + segmentsToCreate + " waypoints");
    
    
    // get circle center and radius
    var radius = Vector3.Distance(posA, posB) / 2f;
    var centerPos = (posA + posB) / 2f;

    // get a rotation that looks in the direction of the target gameobject
    var centerDirection = Quaternion.LookRotation((posA - posB).normalized);

    for (var i = 0; i < segmentsToCreate; i++)
    {
        
        var angle = Mathf.PI * (i) / (segmentsToCreate + 1f);
        var y = Mathf.Sin(angle) * radius;
        var z = Mathf.Cos(angle) * radius;
        var pos = new Vector3(0, y, z);
        // Rotate the pos vector according to the centerDirection
        pos = centerDirection * pos;
        path.m_Waypoints[i] = new CinemachineSmoothPath.Waypoint();
        path.m_Waypoints[i].position = centerPos + pos;
    }

    //create a circle of points around the target gameobject at a give radius
    float greenRadius = 20f;
    int waypointNum = segmentsToCreate;
    for (int i = 0; i < greenRingPointsNum; i++)
    {
        float angle = i * Mathf.PI * 2f / greenRingPointsNum;
        Vector3 newPos = posB + new Vector3(Mathf.Cos(angle) * greenRadius, posB.y, Mathf.Sin(angle) * greenRadius);
        path.m_Waypoints[waypointNum] = new CinemachineSmoothPath.Waypoint();
        path.m_Waypoints[waypointNum].position = newPos;
        waypointNum++;
    }

}
static void CalcWaypoints(路径、矢量3位置A、矢量3位置B)
{
int格林林点snum=8;
浮子流量计通过点=10;
//在这里,我们计算两点之间适合的线段数
int segmentsToCreate=Mathf.RoundToInt(矢量3.距离(位置A、位置B)/米/路径点);
path.m_航路点=新航路点[segmentsToCreate+GreenringPointsUM];
Debug.Log(“创建”+segmentsToCreate+“航路点”);
//获取圆心和半径
var半径=矢量3.距离(位置A、位置B)/2f;
var centerPos=(posA+posB)/2f;
//获得朝向目标游戏对象方向的旋转
var centerDirection=Quaternion.LookRotation((posA-posB).normalized);
对于(变量i=0;i
希望你们中的一位伟人能帮上忙:)

如下图所示的圆弧,我可以控制高度以及两点之间的距离:

最简单的方法可能是动态创建并遵循它们

首先,我们定义顶点的方向,并找到顶点:

float apexHeightFromA = 5f;  // apex is 5 world units above A
float apexDistanceFactor = 0.5f; // apex is halfway from A to B
Vector3 upDirection = Vector3.up; // direction apex is in relative to points

Vector3 aToB = posB - posA;
Vector3 flatAToB = Vector3.ProjectOnPlane(aToB, upDirection);

Vector3 posApex = posA 
        + flatAToB * apexDistanceFactor
        + apexHeightFromA * upDirection;
现在,可以定义Bézier曲线了。如果我们使用两条三次Bézier曲线,我们将需要两个控制点,一个在顶点的两侧。也就是说,一个朝向A点,一个朝向B点

Vector3 controlPointApexA;
Vector3 controlPointApexB;
如何定义这些是任意的。一个好的起点可能是水平移动到每个控制点朝向的终点的一半

Vector3 apexToA = posA - posApex;
Vector3 apexToB = posB - posApex;

float controlPointDistanceFactor = 0.5f;

controlPointA = posApex 
        + controlPointDistanceFactor * Vector3.ProjectOnPlane(apexToA, upDirection);
controlPointB = posApex 
        + controlPointDistanceFactor * Vector3.ProjectOnPlane(apexToB, upDirection);
不管我们如何定义控制点,我们都可以沿着曲线进行迭代

首先,我们需要确定顶点前后应该有多少个航路点。一个合理的假设是根据其在各点之间的位置来实现

float apexTravelFactor = apexDistanceFactor; 
然后,我们可以使用二次Bézier曲线的公式

。。。从A到顶点或从顶点到B取决于我们在曲线中的位置:

// cache for efficiency
Vector3 controlAToA = posA - controlPointA;
Vector3 controlBToB = posB - controlPointB;

Vector3 controlAToApex = posApex - controlPointA;
Vector3 controlBToApex = posApex - controlPointB;


for (var i = 0; i < segmentsToCreate; i++)
{
    float overallT = (float)i / segmentsToCreate;

    Vector3 control, controlToOrigin, controlToDest;
    float t;

    // are we going from a to apex or apex to b?
    if (overallT < apexTravelFactor)
    {
        // going from a to apex
        control = controlPointA;
        controlToOrigin = controlAToA;
        controlToDest = controlAToApex;

        t = overallT / apexTravelFactor;
    }
    else 
    {
        // going from apex to b
        control = controlPointB;
        controlToOrigin = controlBToApex;
        controlToDest = controlBToB;

        t = (overallT - apexTravelFactor) / (1f - apexTravelFactor);
    }

    Vector3 currentPos = control 
            + Mathf.Pow(1f - t, 2f) * controlToOrigin
            + Mathf.Pow(t, 2f) * controlToDest;
    
    path.m_Waypoints[i] = new CinemachineSmoothPath.Waypoint();
    path.m_Waypoints[i].position = currentPos;
}

最简单的方法可能是动态创建并遵循它们

首先,我们定义顶点的方向,并找到顶点:

float apexHeightFromA = 5f;  // apex is 5 world units above A
float apexDistanceFactor = 0.5f; // apex is halfway from A to B
Vector3 upDirection = Vector3.up; // direction apex is in relative to points

Vector3 aToB = posB - posA;
Vector3 flatAToB = Vector3.ProjectOnPlane(aToB, upDirection);

Vector3 posApex = posA 
        + flatAToB * apexDistanceFactor
        + apexHeightFromA * upDirection;
现在,可以定义Bézier曲线了。如果我们使用两条三次Bézier曲线,我们将需要两个控制点,一个在顶点的两侧。也就是说,一个朝向A点,一个朝向B点

Vector3 controlPointApexA;
Vector3 controlPointApexB;
如何定义这些是任意的。一个好的起点可能是水平移动到每个控制点朝向的终点的一半

Vector3 apexToA = posA - posApex;
Vector3 apexToB = posB - posApex;

float controlPointDistanceFactor = 0.5f;

controlPointA = posApex 
        + controlPointDistanceFactor * Vector3.ProjectOnPlane(apexToA, upDirection);
controlPointB = posApex 
        + controlPointDistanceFactor * Vector3.ProjectOnPlane(apexToB, upDirection);
不管我们如何定义控制点,我们都可以沿着曲线进行迭代

首先,我们需要确定顶点前后应该有多少个航路点。一个合理的假设是根据其在各点之间的位置来实现

float apexTravelFactor = apexDistanceFactor; 
然后,我们可以使用二次Bézier曲线的公式

。。。从A到顶点或从顶点到B取决于我们在曲线中的位置:

// cache for efficiency
Vector3 controlAToA = posA - controlPointA;
Vector3 controlBToB = posB - controlPointB;

Vector3 controlAToApex = posApex - controlPointA;
Vector3 controlBToApex = posApex - controlPointB;


for (var i = 0; i < segmentsToCreate; i++)
{
    float overallT = (float)i / segmentsToCreate;

    Vector3 control, controlToOrigin, controlToDest;
    float t;

    // are we going from a to apex or apex to b?
    if (overallT < apexTravelFactor)
    {
        // going from a to apex
        control = controlPointA;
        controlToOrigin = controlAToA;
        controlToDest = controlAToApex;

        t = overallT / apexTravelFactor;
    }
    else 
    {
        // going from apex to b
        control = controlPointB;
        controlToOrigin = controlBToApex;
        controlToDest = controlBToB;

        t = (overallT - apexTravelFactor) / (1f - apexTravelFactor);
    }

    Vector3 currentPos = control 
            + Mathf.Pow(1f - t, 2f) * controlToOrigin
            + Mathf.Pow(t, 2f) * controlToDest;
    
    path.m_Waypoints[i] = new CinemachineSmoothPath.Waypoint();
    path.m_Waypoints[i].position = currentPos;
}

不,不是抛物线,我只想在posA和PosB之间创建一个平滑的圆弧,但能够控制三个潜在圆弧的最大高度。双曲线,抛物线,双曲线(近似)再考虑一下。。。如果你想绕着圆走更长的路,那么圆弧可以达到任意高:p尽管如此,你还是怀疑这是你想要的!所以我更新了这个问题,是的,我想控制弧中的最大高度,与posA和posB之间的距离有关,感谢@Ruzihm的链接,但是公式让我困惑,我在学校做这种数学已经40年了,是的,40年了:)不,不是抛物线,我只想在posA和PosB之间创建一个平滑的圆弧,但能够控制三个潜在圆弧的最大高度。双曲线,抛物线,双曲线(近似)再考虑一下。。。如果你想绕着圆走更长的路,那么圆弧可以达到任意高:p尽管如此,你还是怀疑这是你想要的!所以我更新了这个问题,是的,我想控制弧线中的最大高度,相对于posA和posB之间的距离,感谢链接@Ruzihm,