Command rotate 4 straight lines average parallel to Cplane?

I have imported a tractor mesh which is very close to being oriented ready for making 3D, but needs a tweak now I have access to rhino tools.
Having created sections through cab and bonnet I have then placed four lines plotted base door to same other side, window base, gutter rim and bonnet feature.
Aim is to orient as best level as is possible in front view. (tractor mesh grouped to lines).

In front view (headlights radiator etc) I want to select the four lines and have Rhino establish average of them and make that average level, i.e. parallel to XY plane.

Then I will deal with side view and get datum level.

How best can I get that front view level using mean of the four lines ?
make lines average level tractor.3dm (27.9 KB)



Hi Steve - you can average the lines by:

  • Divide all of them to get a sampling of points.
  • Select the points and LineThroughPt.

Then Orient your mesh from the new line end points to the X axis or whatever makes sense.


Hi Pascal,
can you just expand a bit on what that entails.

Divide command, select all lines and enter a value, creates points along the lines, then select the points en masse and LineThroughPt, is how I see that but with lines in various locations in side view, I do that and get a vertical line appear in front view 2 deg out from vertical, whilst the horiz lines were almost parallel to Cplane. rotating to get that new line vert sees aa 2 deg tilt to tractor.

Clearly I have errored in understanding this,



Maybe use PlaneThroughPt to create a plane through the sampled lines’ points, then do your rotation based on the orientation of the plane.

Hi Steve I do not have your file, so hard to tell but a better way to average the lines might be to average the end points - (1.2 KB)

To use the Python script use RunPythonScript, or a macro:

_-RunPythonScript "Full path to py file inside double-quotes"


oops forgot to attach the file, now added to initial post.

Take a look then establish best method.

I need an average of the 4 lines in front view, then take that, group it to the lines and tractor (tractor not in uploaded file as its a mesh and huge file size) and rotate it to horizontal,

I had a Pascal script and perhaps this might do it.
I make a new button, then add the script, which is to be found in the following the thread:-

and run it, and in Front view I get a short line which is an average of the lines, .
Group that to the lines and rotate that line to horiz.

That would seem to do what I require.

However why is that average curve much shorter than the others ?

make lines average level tractor_AverageCurves macro.3dm (34.5 KB)

I extend the line either end to compensate and have something larger to work with.

Now I realise perhaps average is not quite the right thing.

Say I have lines 0.1deg 0.0deg (level), another 0.0 , 0.05 and 0.9 degs
Average would allow 0.9 to have too much of an influence, clearly my object is almost level, averageCurve would be 0.2deg and throw my object out if I rotated that to level. I need something that takes account of the most prolific of the curves, standard deviation etc school stuff ! what is in the centre of the hump !
How is that done ?



Hi Steve- most likely the curve averager does not take into account the curve direction - I’ll take a look

But the line averager a couple of posts up does.


Hi Pascal,
I need a tweak to the py code then if that is so.

However using both py codes I get different results !
0.123754 deg to the horiz using
0.244968 deg to the horiz using Average Line by End Point

I can see one showing differently under the other, so prompting an angle check.

also and I realise its a better approach, my need of the ‘standard deviation’ to be allowed for, as one cannot have a 0.9deg line influencing too much if at all others that are almost level (fictional example)

so what code for that ?
make lines average level tractor_AverageCurves macro 2 results.3dm (43.5 KB)


I am not really sure I undertstand - did you even try the average lines script I posted above?


Hi Pascal,
yes, I made another button and used that script.
Obviously the 2 buttons won’t appear on your rhino as they have code to a specific address on my PC for the two .py scripts.

It made the second line in the attached 3dm file. It was longer in length as you said it would be, but also a different angle to a horiz line I drew compared to the script.

why should the angles differ ?

and what code that takes account of a standard deviation in the angles of lines, as per fictional example one cannot have a 0.9deg curve applying too much if any influence over others of a similar angle as they may all be about right and it (0.9) an error.


OK, well the line averager simply averages the end points of the input lines and creates a new line there. As far as I know it does that accurately. If you need more sophisication than that, at he moment, you’re on your own. The previous curve averager averages a sets of points on each input - not just the end points - I do not think it handled curve direction - if you make sure that all the lines are pointed in the same direction, you should get a very similar result from both scripts with these lines.


I have now run dir and will run the script again, to see if the results lies in the same angle as the AverageLinebyEndPoint.

As they were 0.12 deg different that to me doesnt seem right.

I will report back on the result with all dir in same direction.

and BINGO…with dir all same direction, the result of AverageCurves matches that of

As such the needs a stage where it asks to check all dir are same direction.

Can you edit that or what would the macro code be to put into the button replacing that which is already there that runs the .py for AverageCurve ?

Probably better to have it within the .py else for others it may not prompt a dir check.
and here is the result now:-
make lines average level tractor_AverageCurves same dir match AverageLinebyEndPoint.3dm (44.5 KB)


So… why not just use the latter and be done? It makes sure all the directions are the same.


Hi Pascal,

For straight lines yes I will, I was considering the which I will be using, and have used once already, on curvy wavy ones, not realising that they all need to have same dir, and other folk would also get caught out in the same way, so could that .py code be altered to prompt for dir check first ?

I also need something that takes into account any oddball lines not in the usual ballpark of angles and considers ‘standard deviation’ remembering my school days, see my fictional example of 0.9deg as the oddball.