0
\$\begingroup\$
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

[RequireComponent(typeof(LineRenderer))]
public class DrawCircle : MonoBehaviour
{
    [Range(0, 50)]
    public int segments = 50;
    [Range(0, 50)]
    public float xradius = 5;
    [Range(0, 50)]
    public float yradius = 5;
    LineRenderer line;

    void Start()
    {
        line = gameObject.GetComponent<LineRenderer>();

        line.positionCount = (segments + 1);
        line.useWorldSpace = false;

    }

    private void Update()
    {
        CreatePoints();
    }

    void CreatePoints()
    {
        float x;
        float y;
        float z;

        float angle = 20f;

        for (int i = 0; i < (segments + 1); i++)
        {
            x = Mathf.Sin(Mathf.Deg2Rad * angle) * xradius;
            z = Mathf.Cos(Mathf.Deg2Rad * angle) * yradius;

            line.SetPosition(i, new Vector3(x, 0, z));

            angle += (360f / segments);
        }
    }
}

Circle

In the screenshot in the left of the circle there is a gap the circle is not perfect completed.

\$\endgroup\$
2
\$\begingroup\$

Were I to guess there are two things that jump out at me:

float angle = 20f;

Notice how this is a different length segment than the rest of the circle, as defined here?:

angle += (360f / segments);

So your first segment is 20 length and your following segments are 360/50; which is 7.2. That could be enough to make it look a bit funky.


Second thing, which compounds the first, is that you're talking to everything in degrees, converting to radians, then adjusting by degrees again. This introduces a lot of possibility for rounding error.

I'd make the following changes:

public int segments = 50;
void CreatePoints()
{
    float x;
    float z;

    float change = 2 * Math.Pi / segments;
    float angle = change;

    for (int i = 0; i < (segments + 1); i++)
    {
        x = Mathf.Sin(angle) * xradius;
        z = Mathf.Cos(angle) * yradius;

        line.SetPosition(i, new Vector3(x, 0, z));

        angle += change;
    }
}

This is not only going to reduce the possible rounding errors and move a consistent amount each time it loops, but it also gets rid of (in this case) 50 extra divide operations you didn't need, 100 multiplies you didn't need, and you're talking in radians, which is just good practice.


An aside for the above: I highly recommend getting used to the Unit Circle and memorizing common values.


Update: In the comments it was mentioned that LineSegment.loop needs to be called at the end of the function to connect the beginning to the end.

The above code will still solve the "circle isn't quite circular" problem that would have occurred (I think) and be more efficient than the original code.

\$\endgroup\$
  • \$\begingroup\$ Don't forget the lineRenderer.loop parameter to join the start & end. \$\endgroup\$ – DMGregory Jun 5 '18 at 11:26
  • \$\begingroup\$ @DMGregory I'll edit that into the answer. That is something I didn't know and it may be important for his actual fix. \$\endgroup\$ – blurry Jun 5 '18 at 15:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.