C# & Unity: Drawing circles with the help of standard equations for circles

I have some free time recently to review my high school mathematics knowledge~


Know the standard equation for a circle: (xa)²+(yb)²=r²

(xa)²+(yb)²=r² represents a circle whose center coordinate is (a, b) and radius is r.


Personal thoughts:

Knowing the coordinates of the center of the circle and the radius of the circle , we can also know the coordinates of the leftmost end and the rightmost end of the circle . Here we only need to know the x value of the leftmost coordinate and the x value of the rightmost coordinate . For multiple points, substitute these points into the equation to find the y value, and you will get two or one y value, both of which are stored as two-dimensional vector data, and finally connect the points according to the two-dimensional vector data. (Limited ability to express knowledge level)
Please add image description


C# implements the standard equation function of a circle:

Which needs to solve the quadratic equation in one variable:

 标准形式: ax²+bx+c=0(a≠0)  
 求根公式: x=[-b±√(b²-4ac)]/2a
using UnityEngine;

public class BiaoZhunFangCheng
{
    
    
    /// <summary>
    /// (x-a)²+(y-b)²=R²
    /// 已知a、b、R,给出x,求y
    /// </summary>
    /// <param name="x">x</param>
    /// <param name="center">中心点坐标(a,b)</param>
    /// <param name="r"></param>
    /// <returns>y一般有两值</returns>
    private Vector2 GetYValue(float x, Vector2 center, float r = 1f)
    {
    
    
        //求出(x-a)²
        float x_a2 = Mathf.Pow(x - center.x, 2);
        //求出R²
        float R2 = Mathf.Pow(r, 2);
        //(x-a)² 减去 R²  得到一个值
        float value = x_a2 - R2;
        //(y-b)²与这个减值的和等于 0 
        //于是得到 (y-b)² + value = 0
        //在根据平方根公式:(y-b)²就等于  y²+b²-2yb
        //于是得到 y²+b²-2yb + value = 0,其中的b和value是已知的,于是得到
        //y²-2by + (value+b²) = 0,就得到了一个一元二次方程 ax²+bx+c=0
        //其中 a = 1,b = 2b , c = (value+b²)
        //代入写好的函数得到y值
        Vector2 yValue = YiYuanErCi(a: 1, b: 2 * center.y, c: value + Mathf.Pow(center.y, 2));
        return yValue;
    }
    /// <summary>
    /// ax²+bx+c=0(a≠0)
    /// 一元二次方程求根公式:x=[-b±√(b²-4ac)]/2a
    /// </summary>
    /// <param name="a">a</param>
    /// <param name="b">b</param>
    /// <param name="c">c</param>
    /// <returns>结果一般会有两个值</returns>
    private Vector2 YiYuanErCi(float a, float b, float c)
    {
    
    
        //x=[-b±√(b²-4ac)]/2a
        float v1 = (-b + Mathf.Sqrt(Mathf.Pow(b, 2) - 4 * a * c)) / (2 * a);
        float v2 = (-b - Mathf.Sqrt(Mathf.Pow(b, 2) - 4 * a * c)) / (2 * a);
        return new Vector2(v1, v2);
    }
}


Segmentation

For example: from 0 to 1,
I want to divide it into three points, that is, 0, 0.5,
1. I want to divide it into four points, that is, 0, 0.3333..., 0.6666..., 1
How should I implement it?

    /// <summary>
    /// 获得从某点到某点分割的点
    /// </summary>
    /// <param name="formPoint">起始点</param>
    /// <param name="toPoint">结束点</param>
    /// <param name="whatPoint">分割为几点</param>
    /// <returns>点值列表</returns>
    public List<float> GetPoints(float formPoint, float toPoint, int whatPoint)
    {
    
    
        if (whatPoint <= 2)//最少两个点
            return new List<float>() {
    
     formPoint, toPoint };
        if (formPoint == toPoint)
        {
    
    
            Debug.LogError("起始点与结束点位置相同!");
            return new List<float>() {
    
     formPoint };
        }

        //获取线段的长度
        float chaZhi = toPoint - formPoint;
        //段数比点数少一个
        //像“10米距离能种11棵树”一个到了
        int whatDuan = whatPoint - 1;
        //通过段数获取每段的长度
        float one = chaZhi / whatDuan;
        List<float> points = new List<float>();
        //首先增加第一个点
        points.Add(formPoint);
        //去掉首和尾值,只为取中间的值而循环,“这样能避免遇到例如 0.999999...这样的值后再循环执行” 的情况
        int loopCount = whatPoint - 2;
        for (int i = 1; i < loopCount + 1; i++)
        {
    
    
            points.Add(formPoint + (one * i));
        }
        //首先增加最后一个点
        points.Add(toPoint);
        return points;
    }

test:

Combining my ideas, I try to divide the diameter of the circle into 100 points, and then substitute the x values ​​of the 100 points into the standard equation of the circle to get two or one y value, and then combine to get the point on the circle. Coordinates, the result of drawing is not satisfactory. Okay... So from the end point to the center point, the points on the circle are getting more and more compact, as if the exponential function's growth form, well it involves my knowledge blind spot...
insert image description here
1000?
insert image description here
It's hard to write here, who can think of this result (T_T), I don't understand the law from the end point to the center point, sorry for wasting a few minutes of your life... As compensation, I will use another method to achieve a moment


Another way of drawing is: take the center of the circle as the starting point, the radius as the length, draw a vector at a certain angle, and get the coordinates of the end point of the vector at this angle, so that a point is drawn every certain degree, and finally the points are connected. OK ,
refer to the article of the big guy: Know the coordinates of the starting point, angle, and length to find the coordinates of the end point

Full code:

using UnityEngine;

public class CreatCircle : MonoBehaviour
{
    
    
    public GameObject obj;
    public int pointCount = 12;//圆的点数

    private void Start()
    {
    
    
        float perDu = 360f / pointCount;
        int loopIndex = pointCount - 1;

        if (obj)
        {
    
    
            for (int i = 0; i <= loopIndex; i++)
            {
    
    
                Vector2 v2 = GetEndPointByTrigonometric(i * perDu, Vector2.zero, 1f);
                Instantiate(obj, v2, Quaternion.identity);
            }
        }
    }

    /// <summary>
    /// 通过三角函数求终点坐标
    /// </summary>
    /// <param name="angle">角度</param>
    /// <param name="startPoint">起点</param>
    /// <param name="distance">距离</param>
    /// <returns>终点坐标</returns>
    public static Vector2 GetEndPointByTrigonometric(float angle, Vector2 startPoint, float distance)
    {
    
    
        Vector2 endPoint;
        //角度转弧度
        float radian = (angle * Mathf.PI) / 180;
        //计算新坐标 r 就是两者的距离
        endPoint.x = startPoint.x + distance * Mathf.Cos(radian);
        endPoint.y = startPoint.y + distance * Mathf.Sin(radian);
        return endPoint;
    }
}

12 points:
insert image description here

100 points:
insert image description here

Guess you like

Origin blog.csdn.net/m0_55907341/article/details/123412883