- Home /
(Solved) How to position Handles.DrawSolidArc()
I have two lines I'm drawing with Handles.DrawLine(). I'm using three points: an origin, pos1, and pos2. These points will change and I'll want to draw an arc between them, positioned at the origin, to illustrate the angle between them. Here's a gif so you can see what I mean Lines
Here's the example code I made that draws the two lines Handles.color = Color.red; Vector3 _origin = new Vector3 (0, 0, 0); Vector3 _pos1 = new Vector3 (1, 5, 2); Vector3 _pos2 = new Vector3 (5, 0, 0); Handles.DrawLine (_origin, _pos1); Handles.DrawLine (_origin, _pos2);
I have the angle between the lines. As an example here's the information I have for the solid arc function. Handles.DrawSolidArc(_origin, X, X, _angle, 1). X means I don't have that information yet.
This is all being done from an editor window script. Any help is great! If you need me to explain anything please ask. Thank you.
I'm by no means an expert in this area, but AFAI$$anonymous$$ the way to accomplish this involves creating a method that takes two 3D vectors, uses cross-product to find the plane on which they lie, then draws multiple lines on that plane to create the illusion of curve.
You already know the origin of the arc, and you can find the plane with cross-product. Then loop over a function N times, where N is the desired resolution of the arc. For each iteration, you're adding a single point, then drawing a line between it and the previously-added point.
Thanks for the comment. Ins$$anonymous$$d of making my own way of drawing the arc, I would like and try to use Handles.DrawSolidArc(). $$anonymous$$y problem is that the method takes a vector for the normal of the arc and a vector called "from" which I also don't know how to use or get. Here's the documentation of the method https://docs.unity3d.com/ScriptReference/Handles.DrawSolidArc.html
Your way does sound like it will work, but ins$$anonymous$$d of reinventing the wheel I'd like to see if it's possible to use the Handles method first.
You say you're not an expert but that is a pretty solid answer. Thank you.
Answer by AlwaysSunny · Dec 28, 2016 at 01:08 AM
Oh neat! I have not worked with handles for many years. This is brand new information to me.
It looks to me (though I'm not testing it), that what you should supply for the "from" vector is one of the two vectors you've got. The angle would be the angle between the two vectors. The normal can be found by taking the cross-product of the two vectors.
Edit: Comments contain additional followup info if needed.
You're a genius. It works perfectly now. I did exactly like you said and now it works every time. Here's a screenshot
It was such a simple solution as well. Thank you!
No problem! Sorry for the initial confusion: I learned something new too! Best,
Thanks again. As I've played around with this a little more I've found that as long as the origin of the arc is (0, 0, 0) everything is great, but otherwise, it starts going off axis.
Here's is the full code where I draw and calculate everything.
//$$anonymous$$ethod to get normal (taken from https://docs.unity3d.com/ScriptReference/Vector3.Cross.html)
Vector3 GetNormal(Vector3 a, Vector3 b, Vector3 c) {
Vector3 side1 = b - a;
Vector3 side2 = c - a;
return Vector3.Cross(side1, side2).normalized;
}
//This is the color of the lines
Handles.color = Color.red;
//The postions of the points between lines
Vector3 _origin = new Vector3 (0, 0, 0);
Vector3 _pos1 = new Vector3 (1, 5, -10);
Vector3 _pos2 = new Vector3 (-5, 0, 2);
//Legs to calculate the angle (maybe a better way to do this)
float leg1 = Vector3.Distance (_pos1, _origin);
float leg2 = Vector3.Distance (_pos2, _origin);
float leg3 = Vector3.Distance (_pos1, _pos2);
//Calculate the angle
float _angle = ($$anonymous$$athf.Acos (((leg1 * leg1) + (leg2 * leg2) - (leg3 * leg3)) / (2 * leg1 * leg2))) * (180.0f / $$anonymous$$athf.PI);
//Draw the lines
Handles.DrawLine (_origin, _pos1);
Handles.DrawLine (_origin, _pos2);
//Get the normal (method at the top)
Vector3 _cross = GetNormal (_origin, _pos1, _pos2);
//This is the color of the arc
Handles.color = Color.green;
//Draw the arc using everything that was just calculated
Handles.DrawSolidArc (_origin, _cross, _pos1, _angle, 0.5f);
So that codes works, but changing the _origin to anything else means the arc is drawn off axis. Here's is what it looks like with _origin at (0, 0, 4)
I'm wondering if this has to do with normalizing the cross-product vector from the GetNormal() method, and I've tried doing it without, but I end up with the same results. Using Vector.Cross gives me the same results as the GetNormal method.
I'm not sure what is wrong here, but if you have an idea I will be very grateful. Thanks again.
Hey, you're quite welcome. I like helping, plus I'm learning this right along with you.
I'm fairly certain that Angle and Cross calculations shouldn't care about the origin, but maybe the call to DrawSolidArc does?
Handles.DrawSolidArc( _origin, _cross, _pos1 + _origin, _angle, 0.5f );
If this doesn't solve it, I'm afraid I might be at a loss to explain why. You could try adding the origin to pos1 and pos2 when defining the angle and cross arguments too, though I'm thinking that shouldn't matter. It's been quite a long time since I've done any vector math. :)
Thanks to AlwaysSunny it works perfectly now. If you refer to this comment you can see what he said
Hooray! Glad we got it figured out! See ya 'round. :)
Yes, it ended up being that I needed to subtract the origin from both _pos1 and _pos2 when calculating the angle and when calculating the cross-product. Then, finally, I subtracted the origin from the "from" parameter in the Handles.DrawSolidarc() method.
Thank you one last time for all the help! I bet I'll see you around as well. You were very helpful in this endeavor!
To put it in cement (or however stable the Unity servers are), I'll put the code right here to hopefully help someone else in the future.
//This is the color of the lines
Handles.color = Color.red;
//The postions of the points between lines (these can be anything)
Vector3 _origin = new Vector3 (2, 0, 1);
Vector3 _pos1 = new Vector3 (-1, 5, -8);
Vector3 _pos2 = new Vector3 (5, 8, 2);
//Calculate the angle between the lines
float _angle = Vector3.Angle(_pos1 - _origin, _pos2 - _origin);
//Draw the lines
Handles.DrawLine (_origin, _pos1);
Handles.DrawLine (_origin, _pos2);
//Get the normal
Vector3 _cross = Vector3.Cross(_pos1 - _origin, _pos2 - _origin);
//This is the color of the arc
Handles.color = Color.green;
//Draw the arc using everything that was just calculated (use whatever radius)
Handles.DrawSolidArc( _origin, _cross, _pos1 - _origin, _angle, 0.5f );
Answer by Nabak · Feb 28, 2019 at 04:47 PM
Sorry for resurrecting the topic. How is this in execute mode? Handles works fine in editor mode, i need in execute mode. Dows anyone know what i can use?