Search Unity

[SOLVED] Debug.DrawLine Circle/Ellipse and rotate locally with offset?

Discussion in 'General Graphics' started by Quatum1000, Jun 6, 2015.

  1. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    889
    Hi everyone,

    I have baked (out of some examples) a small script that draws a Circle/Ellipse with Debug.DrawLine().
    It does not use RenderLine.

    But the local rotation doesn't work if the position is not 0,0,0.
    I want the Circle to rotate locally with GO and with an additional offset rotateOffset.

    Does anyone know how to?
    Thanks a lot.

    Code (CSharp):
    1.     using UnityEngine;
    2.     using System.Collections;
    3.    
    4.     [ExecuteInEditMode]
    5.     public class Circle : MonoBehaviour
    6.     {
    7.         public int segments;
    8.         public Color col;
    9.         public float xradius;
    10.         public float zradius;
    11.         public Vector3 rotateOffset;                //Offset rotation
    12.         public float scaleFac = 1;
    13.            
    14.         void Start()
    15.         {
    16.             if (scaleFac != 0f) { } else { scaleFac = 1f;}
    17.         }
    18.    
    19.         void Update()
    20.         {
    21.             circle();
    22.         }
    23.    
    24.         void circle()
    25.         {
    26.             float x = 0f;
    27.             float xo = 0f;
    28.    
    29.             float y = 0f;
    30.             float yo = 0f;
    31.    
    32.             float z = 0f;
    33.             float zo = 0f;
    34.    
    35.             float angle = 0f;
    36.    
    37.             var vpo = transform.position;
    38.             var vro = transform.rotation * Quaternion.Euler(rotateOffset);
    39.             var vsc = transform.localScale;
    40.    
    41.             var vo = Vector3.zero;
    42.             var vn = Vector3.zero;
    43.            
    44.             for (int i = 0; i < (segments + 1); i++)
    45.             {
    46.                 x = Mathf.Sin(Mathf.Deg2Rad * angle) * xradius;
    47.                 z = Mathf.Cos(Mathf.Deg2Rad * angle) * zradius;
    48.    
    49.                 vo.x = vpo.x + xo;
    50.                 vo.y = vpo.y + yo;
    51.                 vo.z = vpo.z + zo;
    52.    
    53.                 vn.x = vpo.x + x;
    54.                 vn.y = vpo.y + y;
    55.                 vn.z = vpo.z + z;
    56.    
    57.                 // ? Rotate
    58.                 // vn = vro * vn;
    59.                 // vo = vro * vo;
    60.                            
    61.                 if (i > 0) Debug.DrawLine(vo, vn, col);
    62.    
    63.                 xo = x;
    64.                 yo = y;
    65.                 zo = z;
    66.                 angle += (360f / segments);
    67.             }
    68.         }
    69.     }
    70.  
     
  2. testure

    testure

    Joined:
    Jul 3, 2011
    Posts:
    81
    I'm not sure what the question is- are you trying to rotate a circle around an offset pivot point? IE) the moon is a circle and you want it to orbit the earth (your offset)?

    If so, you need to offset your center point and multiply it by your rotation quaternion. Right now you're using transform.position as your "center" of the circle- this vector3 should be your actual pivot point that you want to rotate around. From here you can rotate the offset

    untested off the top of my head pseudocode:
    Code (CSharp):
    1. Quaternion rotationOffset = Quaternion.Euler(new Vector3(0f, 90f, 0f));
    2.  
    3. Vector3 circleOffset = new Vector3(10f, 0f, 0f);
    4. Vector3 newCenter = rotationOffset * circleOffset;
    5.  
    6. // draw your circle using newCenter as "vpo". your "vro" related code is unneeded at this point
    Lemme know if that works
     
    Last edited: Jun 7, 2015
  3. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    889
    Does not work..Changing the rotation offset cause the circle to change position...

    Any fix?

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. [ExecuteInEditMode]
    6. public class Circle : MonoBehaviour
    7. {
    8.    public int segments;
    9.    public Color col;
    10.    public float xradius;
    11.    public float zradius;
    12.    public Vector3 rotationOffset;  //Offset rotation
    13.    public Vector3 positionOffset;  //Offset position
    14.    public float scaleFac = 1;
    15.    
    16.    void Start()
    17.    {
    18.      if (scaleFac != 0f) { } else { scaleFac = 1f;}
    19.      col.a = 1;  // cause the object not been transparent at start
    20.    }
    21.  
    22.    void Update()
    23.    {
    24.      circle();
    25.    }
    26.  
    27.    void circle()
    28.    {
    29.      float x = 0f;
    30.      float xo = 0f;
    31.      float y = 0f;
    32.      float yo = 0f;
    33.      float z = 0f;
    34.      float zo = 0f;
    35.      float angle = 0f;
    36.        
    37.      Quaternion rto = Quaternion.Euler(rotationOffset) * transform.rotation;
    38.      Vector3 circleOffset = transform.position + positionOffset;
    39.      Vector3 newCenter = rto * circleOffset;
    40.  
    41.      var vo = Vector3.zero;
    42.      var vn = Vector3.zero;
    43.    
    44.      for (int i = 0; i < (segments + 1); i++)
    45.      {
    46.        x = Mathf.Sin(Mathf.Deg2Rad * angle) * xradius;
    47.        z = Mathf.Cos(Mathf.Deg2Rad * angle) * zradius;
    48.  
    49.        vo.x = newCenter.x + xo;
    50.        vo.y = newCenter.y + yo;
    51.        vo.z = newCenter.z + zo;
    52.  
    53.        vn.x = newCenter.x + x;
    54.        vn.y = newCenter.y + y;
    55.        vn.z = newCenter.z + z;
    56.      
    57.        if (i > 0) Debug.DrawLine(vo, vn, col);
    58.  
    59.        xo = x;
    60.        yo = y;
    61.        zo = z;
    62.        angle += (360f / segments);
    63.      }
    64.    }
    65. }
    66.  
     
    Last edited: Jun 7, 2015
  4. bjennings76

    bjennings76

    Joined:
    Jun 15, 2013
    Posts:
    6
    I also really needed a solution for drawing an ellipse and this really helped me out. It's a few years too late, but here's my solution to your problem. I really just moved the rotation and position offsets into the `DrawLine` call:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class Circle : MonoBehaviour
    4. {
    5.     public int Segments = 32;
    6.     public Color Color = Color.blue;
    7.     public float XRadius = 2;
    8.     public float YRadius = 1;
    9.  
    10.     private void OnDrawGizmos()
    11.     {
    12.         DrawEllipse(transform.position, transform.forward, transform.up, XRadius * transform.localScale.x, YRadius * transform.localScale.y, Segments, Color);
    13.     }
    14.  
    15.     private static void DrawEllipse(Vector3 pos, Vector3 forward, Vector3 up, float radiusX, float radiusY, int segments, Color color, float duration = 0)
    16.     {
    17.         float angle = 0f;
    18.         Quaternion rot = Quaternion.LookRotation(forward, up);
    19.         Vector3 lastPoint = Vector3.zero;
    20.         Vector3 thisPoint = Vector3.zero;
    21.  
    22.         for (int i = 0; i < segments + 1; i++)
    23.         {
    24.             thisPoint.x = Mathf.Sin(Mathf.Deg2Rad * angle) * radiusX;
    25.             thisPoint.y = Mathf.Cos(Mathf.Deg2Rad * angle) * radiusY;
    26.  
    27.             if (i > 0)
    28.             {
    29.                 Debug.DrawLine(rot * lastPoint + pos, rot * thisPoint + pos, color, duration);
    30.             }
    31.  
    32.             lastPoint = thisPoint;
    33.             angle += 360f / segments;
    34.         }
    35.     }
    36. }
     
  5. Quatum1000

    Quatum1000

    Joined:
    Oct 5, 2014
    Posts:
    889
    Thanks it's never too late!
     
    aliaksei_k likes this.