Search Unity

LineRenderer to create an ellipse

Discussion in 'Scripting' started by MarkPixel, Jan 15, 2011.

  1. MarkPixel

    MarkPixel

    Joined:
    Apr 15, 2010
    Posts:
    39
    I want to create an ellipse with the LineRenderer.


    Solution:

    Put this code with a LineRenderer-component on a GameObject, then set Segments, Xradius, Yradius



    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Circle : MonoBehaviour
    5. {
    6.     public int segments;
    7.     public float xradius;
    8.     public float yradius;
    9.     LineRenderer line;
    10.        
    11.     void Start ()
    12.     {
    13.         line = gameObject.GetComponent<LineRenderer>();
    14.        
    15.         line.SetVertexCount (segments + 1);
    16.         line.useWorldSpace = false;
    17.         CreatePoints ();
    18.     }
    19.    
    20.    
    21.     void CreatePoints ()
    22.     {
    23.         float x;
    24.         float y;
    25.         float z = 0f;
    26.        
    27.         float angle = 20f;
    28.        
    29.         for (int i = 0; i < (segments + 1); i++)
    30.         {
    31.             x = Mathf.Sin (Mathf.Deg2Rad * angle) * xradius;
    32.             y = Mathf.Cos (Mathf.Deg2Rad * angle) * yradius;
    33.                    
    34.             line.SetPosition (i,new Vector3(x,y,z) );
    35.                    
    36.             angle += (360f / segments);
    37.         }
    38.     }
    39. }

    Coding can be annoying fun! ;)
     
    Last edited: Jan 16, 2011
  2. paulygons

    paulygons

    Joined:
    May 6, 2010
    Posts:
    164
    This is fantastic! Thanks for sharing.
     
  3. Johanna

    Johanna

    Joined:
    Mar 1, 2014
    Posts:
    2
    I use this solution to draw a circle, but I am confused about the radius.

    With a mouse click, I create the line renderer.
    And while I drag the mouse, I adjust the radius of the circle. I want to achieve that the radius of the circle is the distance between the mouse cursor and the circle center. I managed to write code which does this - but the radius seems not to be right, although the numbers are correct.

    I attached a picture to describe the problem better. On the picture, you see the line from the skull to the volcano. The line has a length of 4.9. And you see the circle at the skull, which has a radius of 4.9.

    I would expect that the circle's radius would be as long as the line, because the numbers are the same. So why is the circle so small?

    ***EDIT***
    I finally figured it out! It was because the line renderer does not use world space!
    I've made adjustmets that suits my purpose by NOT using the world space and giving the circle an offset. Works fine now! :D
     

    Attached Files:

    Last edited: Apr 12, 2015
  4. mescalin

    mescalin

    Joined:
    Dec 19, 2012
    Posts:
    67
    Brilliant, seriously thanks so much!
     
  5. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    889
    Thanks great!
    [draw circle in editor window]

    A 2d Editor Window version based on @MarkPixel's source. Draw simple wire geometric objects with the circle function.

    Code (CSharp):
    1. // Circle
    2. Circle(100, 100, 50, 50, 26, 0);
    3.  
    4. // Rectangle
    5. Circle(100, 100, 50, 50, 4, 45);
    6.  
    7. // Triangle
    8. Circle(100, 100, 50, 50, 3, 0);
    9.  
    10. void Circle(float x, float y, float xradius, float yradius, int segments, float angle) {
    11.  
    12.             float xo = 0;
    13.             float yo = 0;
    14.             float xn = 0;
    15.             float yn = 0;
    16.  
    17.             for (int i = 0; i < (segments + 1); i++) {
    18.                 xn = Mathf.Sin(Mathf.Deg2Rad * angle) * xradius;
    19.                 yn = Mathf.Cos(Mathf.Deg2Rad * angle) * yradius;
    20.                 if (i > 0)
    21.                     Handles.DrawLine(new Vector2(x + xn, y + yn), new Vector2(x + xo, y + yo));
    22.                 xo = xn;
    23.                 yo = yn;
    24.                 angle += (360f / segments);
    25.             }
    26.         }
    27.  
     
  6. Eldoir

    Eldoir

    Joined:
    Feb 27, 2015
    Posts:
    60
    I know this post is a bit old, but as we can easily find it when we are specifically searching for "unity circle",
    I thought it was a good idea to post my solution adapted from the one given on top of this post.
    It provides more options such as possibility to change parameters in runtime, and axis.
    Thanks @MarkPixel for sharing ! :)
    Here is the code :

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. [RequireComponent(typeof(LineRenderer))]
    4.  
    5. public class DrawCircle : MonoBehaviour
    6. {
    7.     public enum Axis { X, Y, Z };
    8.  
    9.     [SerializeField]
    10.     [Tooltip("The number of lines that will be used to draw the circle. The more lines, the more the circle will be \"flexible\".")]
    11.     [Range(0, 1000)]
    12.     private int _segments = 60;
    13.  
    14.     [SerializeField]
    15.     [Tooltip("The radius of the horizontal axis.")]
    16.     private float _horizRadius = 10;
    17.  
    18.     [SerializeField]
    19.     [Tooltip("The radius of the vertical axis.")]
    20.     private float _vertRadius = 10;
    21.  
    22.     [SerializeField]
    23.     [Tooltip("The offset will be applied in the direction of the axis.")]
    24.     private float _offset = 0;
    25.  
    26.     [SerializeField]
    27.     [Tooltip("The axis about which the circle is drawn.")]
    28.     private Axis _axis = Axis.Z;
    29.  
    30.     [SerializeField]
    31.     [Tooltip("If checked, the circle will be rendered again each time one of the parameters change.")]
    32.     private bool _checkValuesChanged = true;
    33.  
    34.     private int _previousSegmentsValue;
    35.     private float _previousHorizRadiusValue;
    36.     private float _previousVertRadiusValue;
    37.     private float _previousOffsetValue;
    38.     private Axis _previousAxisValue;
    39.  
    40.     private LineRenderer _line;
    41.  
    42.     void Start()
    43.     {
    44.         _line = gameObject.GetComponent<LineRenderer>();
    45.  
    46.         _line.SetVertexCount(_segments + 1);
    47.         _line.useWorldSpace = false;
    48.  
    49.         UpdateValuesChanged();
    50.  
    51.         CreatePoints();
    52.     }
    53.  
    54.     void Update()
    55.     {
    56.         if (_checkValuesChanged)
    57.         {
    58.             if (_previousSegmentsValue != _segments ||
    59.                 _previousHorizRadiusValue != _horizRadius ||
    60.                 _previousVertRadiusValue != _vertRadius ||
    61.                 _previousOffsetValue != _offset ||
    62.                 _previousAxisValue != _axis)
    63.             {
    64.                 CreatePoints();
    65.             }
    66.  
    67.             UpdateValuesChanged();
    68.         }
    69.     }
    70.  
    71.     void UpdateValuesChanged()
    72.     {
    73.         _previousSegmentsValue = _segments;
    74.         _previousHorizRadiusValue = _horizRadius;
    75.         _previousVertRadiusValue = _vertRadius;
    76.         _previousOffsetValue = _offset;
    77.         _previousAxisValue = _axis;
    78.     }
    79.  
    80.     void CreatePoints()
    81.     {
    82.  
    83.         if (_previousSegmentsValue != _segments)
    84.         {
    85.             _line.SetVertexCount(_segments + 1);
    86.         }
    87.  
    88.         float x;
    89.         float y;
    90.         float z = _offset;
    91.  
    92.         float angle = 0f;
    93.  
    94.         for (int i = 0; i < (_segments + 1); i++)
    95.         {
    96.             x = Mathf.Sin(Mathf.Deg2Rad * angle) * _horizRadius;
    97.             y = Mathf.Cos(Mathf.Deg2Rad * angle) * _vertRadius;
    98.  
    99.             switch(_axis)
    100.             {
    101.                 case Axis.X: _line.SetPosition(i, new Vector3(z, y, x));
    102.                     break;
    103.                 case Axis.Y: _line.SetPosition(i, new Vector3(y, z, x));
    104.                     break;
    105.                 case Axis.Z: _line.SetPosition(i, new Vector3(x, y, z));
    106.                     break;
    107.                 default:
    108.                     break;
    109.             }
    110.  
    111.             angle += (360f / _segments);
    112.         }
    113.     }
    114. }
     
  7. IndieForger

    IndieForger

    Joined:
    Dec 31, 2012
    Posts:
    92
    You are right @Eldoir. It is an old post but still valid. Your circle (not only) drawing script works great. Thanks a lot!
     
  8. Kadaj

    Kadaj

    Joined:
    Jul 24, 2014
    Posts:
    19
    Thanks @MarkPixel, for sharing your code. It's work perfectly!
     
  9. Heviom

    Heviom

    Joined:
    May 7, 2013
    Posts:
    1
    Just a quick addon so you don't have to have that extra point to connect the circle.
    Linerenderer has a loop variable that connects the first and last point in the points array.
     
  10. rajanerve

    rajanerve

    Joined:
    Nov 17, 2017
    Posts:
    17
     
  11. A_Kashi

    A_Kashi

    Joined:
    Jun 30, 2018
    Posts:
    1
    good

    I think you can use LineRenderer.loop = true

    its can use too
     
  12. Toscan0

    Toscan0

    Joined:
    Oct 9, 2018
    Posts:
    11
    Hi, i'm using the code above, and i can't get a perfect circle.

    In the left image is the scene view. It is possible to see that the line render design a circle.
    But in the game view, only appears half circle. Thas because half of the circle is "inside out".

    Any idea how to solve this?
    upload_2020-4-4_17-5-18.png
     
  13. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    889
    * Both are rendered the same way half. On the left you see the outline orange editor selection.
    If you disable the outline selection in the scene view, the it would look the same.

    * Disable the gameobjects in the background. It could be possible the the cycle is drawn half into the gameobject behind.
    The reason is that the rotation setting of the cycle is wrong.
     
    Toscan0 likes this.
  14. Toscan0

    Toscan0

    Joined:
    Oct 9, 2018
    Posts:
    11
    I Disabled everything, expect the astronaut (Is the vuforia target), but it remains the same
    upload_2020-4-8_15-5-29.png

    This is my code, where numberOfVertives is 1000 and radius 0.5
    Code (CSharp):
    1. float x;
    2.         float y;
    3.         float z = 0;
    4.  
    5.         float angle = 0f;
    6.  
    7.         for (int i = 0; i < (numberOfVertices); i++)
    8.         {
    9.             x = Mathf.Sin(Mathf.Deg2Rad * angle) * radius;
    10.             y = Mathf.Cos(Mathf.Deg2Rad * angle) * radius;
    11.  
    12.             lineRenderer.SetPosition(i, new Vector3(y, z, x));
    13.  
    14.             angle += (360f / numberOfVertices);
    15.         }
    How can i fix this?
     
  15. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    889
    Sorry I can not help you with the line renderer. I never used it before.
    I can only think about the alignment to the camera. (orientation)

    https://docs.unity3d.com/ScriptReference/LineRenderer.html
     
    Toscan0 likes this.
  16. Toscan0

    Toscan0

    Joined:
    Oct 9, 2018
    Posts:
    11
    This kind solves the problem, but for a fix camera postion. Maybe can help someone with same problem.

    But since im using vuforia (augmeted reallity) , my camera is constantly changing. Maybe i can re-draw every time my camera is changed but i think there sould be a better way to fix this.

    But thanks anyway :)
     
  17. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    889
    Okay, perhaps a small solution for you.
    If you find post useful you can give a reputation by clicking on like the message.:)
     
    Toscan0 likes this.
  18. Toscan0

    Toscan0

    Joined:
    Oct 9, 2018
    Posts:
    11
    Someone told me that, the line width coulb have a bigger value than the radius, this didn't solve me the problem but can maybe solve other problems for you.

    However, i fix this problem by reducing the number of points, when the radius is small. Like 40 points, gives me a nice circle
     
  19. stefanbendrin

    stefanbendrin

    Joined:
    Dec 27, 2018
    Posts:
    1
    For the correct circle equation sin and cos must be swapped.

    Wrong:
    Code (CSharp):
    1. x = Mathf.Sin (Mathf.Deg2Rad * angle) * xradius;
    2. y = Mathf.Cos (Mathf.Deg2Rad * angle) * yradius;
    Correct:
    Code (CSharp):
    1. x = Mathf.Cos (Mathf.Deg2Rad * angle) * xradius;
    2. y = Mathf.Sin (Mathf.Deg2Rad * angle) * yradius;

    In addition, if you want the circle to be around a specific location, add the following:
    Code (CSharp):
    1. x = transform.position.x + Mathf.Cos (Mathf.Deg2Rad * angle) * xradius;
    2. y = transform.position.y + Mathf.Sin (Mathf.Deg2Rad * angle) * yradius;
     
    bharathn_unity, daisoto and Toscan0 like this.