I’ve managed to get this working, but feel I’ve gone the long way around, and not really got the satisfaction of knowing why it’s right / was wrong.
# Perpendicular Vectors
import rhinoscriptsyntax as rs
import Rhino
vector = rs.VectorCreate( [0,0,0] , [2,10,0] )
vector_perp = Rhino.Geometry.Vector3d(vector) #New instance
vector_perp.PerpendicularTo(vector_perp) # Operate on copy vs original
print vector
print vector_perp
-2,-10,0
-10,2,0
I thought the below would have worked. But I got an exception for only providing one argument when two were required. Documentation says there is one parameter though for perpTo, ‘other’, and I can’t see how I’ve used two arguments when it worked.
# Thought it was good, Except it wasn't
import rhinoscriptsyntax as rs
import Rhino
vector = rs.VectorCreate( [0,0,0] , [2,10,0] )
vector_perp = Rhino.Geometry.Vector3d.PerpendicularTo(vector)
The thing is, PerpendicularTo mutates its first argument, and returns bool. In your first snippet you are calling it as an instance method of vector_perp, and in the second python is complaining because you are calling it without an instance, when it expects an explicit first self argument. See if this helps explain:
# calling instance method
#
x = Rhino.Geometry.Vector3d(1, 0, 0)
y = Rhino.Geometry.Vector3d(0, 1, 0)
ok = x.PerpendicularTo(y)
print("ok: %s, x: %s, y: %s"% (ok, x, y))
# calling instance method as static by providing explicit self
#
x = Rhino.Geometry.Vector3d(1, 0, 0)
y = Rhino.Geometry.Vector3d(0, 1, 0)
ok = Rhino.Geometry.Vector3d.PerpendicularTo(x, y)
print("ok: %s, x: %s, y: %s"% (ok, x, y))
This makes some sense, and with some print statements I noticed the mutation that was going on. Then it got a bit confusing as to which vector was being changed, the documentation threw me off ( ‘this’ to ‘another’ … which to what )
I think what I’ve overlooked is that my ‘starting point’ is two Point3d; I can simply treat them as Vector3d … although it isn’t what my mind would rush to immediately, even though I know a point describes a vector assuming it’s to that point from [0,0,0]. The centre of the transformation I’m doing isn’t from the origin though. This is all for a perpendicular plane, also.
So my desire to explicitly declare vector = rs.VectorCreate( [0,0,0] , [2,10,0] ) seems to be hampering me.
And so also with your example, the x vector is basically a redundant vector that can be set to anything?
I’m not really sure what you are asking, but I think of the difference between points & vectors as the difference ordinal & cardinal numbers, where a point refers to a specific location in space, and a vector describes only a direction & magnitude. So your use of rs.VectorCreate here is the same as saying Vector(-2,-10,0), since you are passing zero to VectorCreate as the to point.
In the example, x can be anything since it will be altered by the call.
This method is not static, meaning you need to call it on an instance of a vector object so it can operate on that data. It also returns a boolean value if it is perpendicular to the input vector.
*Note: you can also create a Vector by subtracting two Points
Point3d a = new Point3d(1,2,8);
Point3d b = new Point3d(6,2,1);
Vector3d vecA = a-b; // b-a will be reversed
Vector3d vecB = Vector3d.ZAxis;
bool perp = vecA.PerpendicularTo(VecB)
if(perp) Print("VecA is orthogonal to VecB");
else Print("VecA is not orthogonal to VecB");
//bool perp = vecA.PerpendicularTo(VecB, 0.01) takes a tolerance
So yes, vectors are not points, they have magnitudes and directions and you can do many important geometrical operations with them.
I only see that on the IsPerpendicularTo method - is it for PerpendicularTo as well? Main takeaway is to learn applications of Static and Non-Static better, anyway.
I think this answers it for me anyway, that I hadn’t missed a neater way than declaring a placeholder vector (x) and mutating to be perp to (y), as opposed to ‘declaring(x), which is just perpendicular version of (y)’?
# Plane Definition
length_vector = rs.VectorCreate(extremities [0], length_midpoint) # midpoint to extreme
length_vector_perp = Rhino.Geometry.Vector3d(length_vector) # Placeholder Vector
length_vector_perp.PerpendicularTo(length_vector_perp) # perp dir from mid
vector_dir = Rhino.Geometry.Plane( length_midpoint , length_vector_perp , length_vector )
transformation_matrix = Rhino.Geometry.Transform.Scale(vector_dir, 1, scale_factor, 1) # 1 for holding
# Transform.Scale Method (Plane, Double, Double, Double) Custom X / Y / Z dir
transformed = rs.TransformObject(base_pattern_curve, transformation_matrix, copy=True)
So it’s defining a 1d scale, starting from Midpoint of a line which is drawn between the Y extremes of a closed curve. The scale_factor is driven by what the length between the Y extremes of the next object needs to be. (Y2 / Y1 = ~ 1.05, or whatever)