Unity3d 获取球体上的点';从一个随机点开始旋转曲面

Unity3d 获取球体上的点';从一个随机点开始旋转曲面,unity3d,math,geometry,Unity3d,Math,Geometry,我正在创造一个统一的游戏,我有一个数学问题。 我有一个半径为10,中心为(0,0,0)的球体。 我想让相机绕着球体移动,但我找不到任何地方可以做我想做的事情。 我在X轴和Y轴上移动相机(因此在球体外得到一个点),我想设置它的Z轴,这样相机就会回到球体上,我使用这个方程:r^2=X^2+Y^2+Z^2=>Z^2=r^2-X^2-Y^2 但它不起作用…请帮帮我 编辑 这是我的代码(c#): 正如你所看到的,我使用夹具使X和Y小于半径,但它没有帮助…你必须通过圆边界限制2D坐标 len = Mathf

我正在创造一个统一的游戏,我有一个数学问题。 我有一个半径为10,中心为(0,0,0)的球体。 我想让相机绕着球体移动,但我找不到任何地方可以做我想做的事情。 我在X轴和Y轴上移动相机(因此在球体外得到一个点),我想设置它的Z轴,这样相机就会回到球体上,我使用这个方程:r^2=X^2+Y^2+Z^2=>Z^2=r^2-X^2-Y^2 但它不起作用…请帮帮我

编辑

这是我的代码(c#):


正如你所看到的,我使用夹具使X和Y小于半径,但它没有帮助…

你必须通过圆边界限制2D坐标

len = Mathf.Sqrt(newX * newX + newY * newY);
//perhaps you have Len or Hypot function in your Math library

if len > maxDistance then
     newX = maxDistance * newX / len
     newY = maxDistance * newY / len;

这没有经过测试,但应该非常接近

private void OnMouseDrag(){
    Vector3 newPos =  mainCameraTransform.position;
    newPos += mainCameraTransform.up * Input.GetAxis("Mouse Y");
    newPos += mainCameraTransform.right * Input.GetAxis("Mouse X");
    newPos = newPos.normalized * 10f;
    mainCameraTransform.position = newPos;
    mainCameraTransform.LookAt(Vector3.zero, mainCameraTransform.up);
}

将此脚本拖放到摄影机上,以使用鼠标右键围绕目标动态观察它

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class OrbitAroundObject : MonoBehaviour {

    public Transform target;
    public float distance = 10.0f;
    public float xSpeed = 120.0f;
    public float ySpeed = 120.0f;

    public float yMinLimit = -20f;
    public float yMaxLimit = 80f;

    public float distanceMin = .5f;
    public float distanceMax = 15f;

    public float smoothTime = 2f;

    public float zoomSpeed = 1;

    float rotationYAxis = 0.0f;
    float rotationXAxis = 0.0f;

    float velocityX = 0.0f;
    float velocityY = 0.0f;

    // Use this for initialization
    void Start() {
        Vector3 angles = transform.eulerAngles;
        rotationYAxis = angles.y;
        rotationXAxis = angles.x;

        // Make the rigid body not change rotation
        if (GetComponent<Rigidbody>()) {
            GetComponent<Rigidbody>().freezeRotation = true;
        }
    }

    void LateUpdate() {
        if (target) {
            if (Input.GetMouseButton(1)) {
                velocityX += xSpeed * Input.GetAxis("Mouse X") * 0.02f;
                velocityY += ySpeed * Input.GetAxis("Mouse Y") * 0.02f;
            }

            //distance -= (Input.mouseScrollDelta.y*Time.deltaTime);
            distance = Mathf.Lerp(distance, distance-(Input.mouseScrollDelta.y*zoomSpeed) , Time.deltaTime * smoothTime);
            distance = Mathf.Clamp(distance, distanceMin, distanceMax);

            rotationYAxis += velocityX;
            rotationXAxis -= velocityY;

            rotationXAxis = ClampAngle(rotationXAxis, yMinLimit, yMaxLimit);

            //Quaternion fromRotation = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, 0);
            Quaternion toRotation = Quaternion.Euler(rotationXAxis, rotationYAxis, 0);
            Quaternion rotation = toRotation;


            Vector3 negDistance = new Vector3(0.0f, 0.0f, -distance);
            Vector3 position = rotation * negDistance + target.position;

            transform.rotation = rotation;
            transform.position = position;

            velocityX = Mathf.Lerp(velocityX, 0, Time.deltaTime * smoothTime);
            velocityY = Mathf.Lerp(velocityY, 0, Time.deltaTime * smoothTime);
        }

    }

    public static float ClampAngle(float angle, float min, float max) {
        if (angle < -360F)
            angle += 360F;
        if (angle > 360F)
            angle -= 360F;
        return Mathf.Clamp(angle, min, max);
    }
}
使用系统集合;
使用System.Collections.Generic;
使用UnityEngine;
公共类轨道对象:单行为{
公共转型目标;
公共浮动距离=10.0f;
公共浮点数xSpeed=120.0f;
公共浮动Y速度=120.0f;
公共浮动yMinLimit=-20f;
公共浮动yMaxLimit=80f;
公共浮动距离最小值=0.5f;
公共浮动距离最大值=15f;
公共浮动平滑时间=2f;
公共浮动缩放速度=1;
浮动旋转Y轴=0.0f;
浮动旋转X轴=0.0f;
浮动速度x=0.0f;
浮动速度y=0.0f;
//用于初始化
void Start(){
Vector3角度=transform.eulerAngles;
旋转y轴=角度y;
旋转x轴=角度x;
//使刚体不改变旋转
if(GetComponent()){
GetComponent().freezeRotation=true;
}
}
void LateUpdate(){
如果(目标){
if(输入。GetMouseButton(1)){
velocityX+=xSpeed*Input.GetAxis(“鼠标X”)*0.02f;
velocityY+=ySpeed*Input.GetAxis(“鼠标Y”)*0.02f;
}
//距离-=(Input.mousescrollldelta.y*Time.deltaTime);
距离=Mathf.Lerp(距离,距离-(Input.mousescrollldelta.y*缩放速度),Time.deltaTime*平滑时间);
距离=数学夹具(距离、距离最小值、距离最大值);
旋转Y轴+=速度X;
旋转X轴-=速度Y;
rotationXAxis=ClampAngle(rotationXAxis,yMinLimit,yMaxLimit);
//来自旋转的四元数=四元数.Euler(transform.rotation.eulerAngles.x,transform.rotation.eulerAngles.y,0);
四元数旋转=四元数.Euler(旋转X轴,旋转Y轴,0);
四元数旋转=旋转;
矢量3负距离=新矢量3(0.0f,0.0f,-距离);
矢量3位置=旋转*负距离+目标位置;
transform.rotation=旋转;
变换位置=位置;
velocityX=Mathf.Lerp(velocityX,0,Time.deltaTime*smoothTime);
velocityY=Mathf.Lerp(velocityY,0,Time.deltaTime*smoothTime);
}
}
公共静态浮子夹持器(浮子角度、浮子最小值、浮子最大值){
如果(角度<-360F)
角度+=360F;
如果(角度>360F)
角度-=360F;
返回数学夹具(角度、最小值、最大值);
}
}

只要x²+y²,是否要在球体表面上生成3d随机点?是否只是尝试将相机约束到球体上?使用旋转而不是设置x和y是否更容易?如果没有更多的细节,就有点难以猜测哪里出了问题。你能发布代码吗?我想做的就是创建三维视图,相机可以随时查看模型,我可以通过拖动鼠标来改变视角。为此,我根据拖动方向移动相机,并使用内置代码将其旋转到中心。我唯一不知道的是如何将相机保持在球体中(或至少在其表面中)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class OrbitAroundObject : MonoBehaviour {

    public Transform target;
    public float distance = 10.0f;
    public float xSpeed = 120.0f;
    public float ySpeed = 120.0f;

    public float yMinLimit = -20f;
    public float yMaxLimit = 80f;

    public float distanceMin = .5f;
    public float distanceMax = 15f;

    public float smoothTime = 2f;

    public float zoomSpeed = 1;

    float rotationYAxis = 0.0f;
    float rotationXAxis = 0.0f;

    float velocityX = 0.0f;
    float velocityY = 0.0f;

    // Use this for initialization
    void Start() {
        Vector3 angles = transform.eulerAngles;
        rotationYAxis = angles.y;
        rotationXAxis = angles.x;

        // Make the rigid body not change rotation
        if (GetComponent<Rigidbody>()) {
            GetComponent<Rigidbody>().freezeRotation = true;
        }
    }

    void LateUpdate() {
        if (target) {
            if (Input.GetMouseButton(1)) {
                velocityX += xSpeed * Input.GetAxis("Mouse X") * 0.02f;
                velocityY += ySpeed * Input.GetAxis("Mouse Y") * 0.02f;
            }

            //distance -= (Input.mouseScrollDelta.y*Time.deltaTime);
            distance = Mathf.Lerp(distance, distance-(Input.mouseScrollDelta.y*zoomSpeed) , Time.deltaTime * smoothTime);
            distance = Mathf.Clamp(distance, distanceMin, distanceMax);

            rotationYAxis += velocityX;
            rotationXAxis -= velocityY;

            rotationXAxis = ClampAngle(rotationXAxis, yMinLimit, yMaxLimit);

            //Quaternion fromRotation = Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y, 0);
            Quaternion toRotation = Quaternion.Euler(rotationXAxis, rotationYAxis, 0);
            Quaternion rotation = toRotation;


            Vector3 negDistance = new Vector3(0.0f, 0.0f, -distance);
            Vector3 position = rotation * negDistance + target.position;

            transform.rotation = rotation;
            transform.position = position;

            velocityX = Mathf.Lerp(velocityX, 0, Time.deltaTime * smoothTime);
            velocityY = Mathf.Lerp(velocityY, 0, Time.deltaTime * smoothTime);
        }

    }

    public static float ClampAngle(float angle, float min, float max) {
        if (angle < -360F)
            angle += 360F;
        if (angle > 360F)
            angle -= 360F;
        return Mathf.Clamp(angle, min, max);
    }
}