Tricky Behavior project_to_line method
-
The
point3d.project_to_line line
method can take a line as an argument.
A line can be defined by a combination of two arrays , which are a point3d and a vector3d, or a point 3d and another point 3d.if you do:
a = [[x[1], y[1], z[1]], [x[2], y[2], z[2]], [x[3], y[3], z[3]]]
pt1 = a[1]
pt2 = a[2]
pt3 = a[3]
entities.add_cline pt2, pt3
is perfectly understood as 2 points in this case of creating a construction line.
But pt4 = pt1.project_to_line [pt2,pt3]
takes pt3 to be a vector (even thought the API gives a choice)
If you define a line = [pt2,pt3]
and then pt4 = pt1.project_to_line line, same broken result
if you define:
pt3 = Geom::Point3d.new before pt3 = a[3]; same broken resultThe only solution for the project_to_line method to recognize pt3 as a point is to do this:
pt3 = Geom::Point3d.new (a[3][0], a[3][1], a[3][2])
pt2 is always recognized as a point no matter which method is used (same declaration, declaring a new point before giving values, or just passing the array)I don't know if this has been noted before or where, or if I missed something, but this is the result I observed.
-
@michaelv said:
if you do:
pt1 = [x[1], y[1], z[1]]
pt2 = [x[2], y[2], z[2]]
pt3 = [x[3], y[3], z[3]]Note that the classes are
Array
.@michaelv said:
entities.add_cline pt2, pt3
is perfectly understood as 2 points in this case of creating a construction line.No surprise. Have you read how the API modified the base Ruby Array class ??
@michaelv said:
But pt4 = pt1.project_to_line [pt2,pt3]
takes pt3 to be a vector (even thought the API gives a choice)OK.. put yourself in the shoes of the API programmer.
If you pass a 2nd arg that is neither aGeom::Point3d
nor aGeom::Vector3d
, what is the method supposed to do ??
It cannot read your mind.
The API writers had to make a choice, and believed that most people will use a vector.
The only other choice, would be to do typechecking on the 2nd argument, and raise aTypeError
exception unless it was aGeom::Point3d
or aGeom::Vector3d
(even IF it was an validArray
that could be used to construct either one of the former.) -
Notice this console error:
pointonline = [10,10,10].project_to_line [0,0,0] %(#008000)[Error: #<ArgumentError: (eval):0:in
project_to_line': Cannot convert argument to Sketchup::Point3d>]`What that tells you is that internally, the
project_to_line()
method, calls the constructor methods for you onArray
arguments.
Like:
pt1 = Geom::Point3d.new(args[0]) if args[0].is_a?(Array) pt2 = Geom::Vector3d.new(args[1]) if args[1].is_a?(Array)
.. etc ...- And the error message itself has a typo. The class is within the
Geom
module, not theSketchup
module. (This bug has been reported.)
- And the error message itself has a typo. The class is within the
-
@dan rathbun said:
Notice this console error:
pointonline = [10,10,10].project_to_line [0,0,0] %(#008000)[Error: #<ArgumentError: (eval):0:in
project_to_line': Cannot convert argument to Sketchup::Point3d>]`What that tells you is that internally, the
project_to_line()
method, calls the constructor methods for you onArray
arguments.
Like:
pt1 = Geom::Point3d.new(args[0]) if args[0].is_a?(Array) pt2 = Geom::Vector3d.new(args[1]) if args[1].is_a?(Array)
.. etc ...- And the error message itself has a typo. The class is within the
Geom
module, not theSketchup
module. (This bug has been reported.)
What that tells me mostly, with all due respect, is that you cannot define a line with a single point as witness that from the ruby console:
[20,10,30].project_to_line [0,1,1], [5,1,1]
[25.5555555555556, 6.11111111111111, 6.11111111111111]
Doesn't generate an error (yes it takes the second array as a vector)So I don't know whether it calls a constructor method or any such fine and advanced details, all I know is that I can define a line such as [0,1,1], [5,1,1] as in entities.add_line [0,1,1], [5,1,1] and it works, and takes the second array as being a point. Please note too that the line definition can interpret the second array as a point or a vector too, and it defaults to point apparently (but I have a method in array (vector_to) that allows me to easily specify such array as being a vector, not so for a point.
Yet when I use that line definition, which is accepted and stated as a line definition, into the line argument for the project_to_line method, it just doesn't take it as such.I may still be wrong, but it still seems to me that it's not as originally intended, and stated. And that a statement of raised exception may help.
- And the typo is that it should be "cannot convert argument to line" I think, whatever a line is (it's not in the class list, but yet is used as valid object, and there is a geometric one (drawn), and a mathematical one.) I quote from the Geom module:
@unknownuser said:
The methods in this module take lines and planes as arguments. There is no special class for representing lines or planes. Arrays are used for both.
A line can be represented as either an Array of a point and a vector, or as an Array of two points.
NOTE: Lines and Planes are infinite.and from the add_line method:
@unknownuser said:
The add_line method is used to add an edge to the collection of entities. This is not to be confused with the concept of a "line" from a geometric sense, which is an invisible object represented by an Array of a point and a vector. (See the Array class for more information on geometric lines in SketchUp.)
- And the error message itself has a typo. The class is within the
-
@dan rathbun said:
@michaelv said:
No surprise. Have you read how the API modified the base Ruby Array class ??
Yes I did and it says:
Therefore, you can use the Array class in place of a Point3d or Vector3d as a way to pass coordinate values.@dan rathbun said:
@michaelv said:
OK.. put yourself in the shoes of the API programmer.
If you pass a 2nd arg that is neither aGeom::Point3d
nor aGeom::Vector3d
, what is the method supposed to do ??
It cannot read your mind.
The API writers had to make a choice, and believed that most people will use a vector.
The only other choice, would be to do typechecking on the 2nd argument, and raise aTypeError
exception unless it was aGeom::Point3d
or aGeom::Vector3d
(even IF it was an validArray
that could be used to construct either one of the former.)I perfectly understand the conundrum, and I perfectly understand the mindset of the API programmer. Neither are in question here, nor am I asking anything to "read my mind".
When it says an array can be used to create a point and that it works, and an argument can be a point3d or a vector (which incidentally I perfectly understand can also be a three values array), it's not my mind that has to be read but rather to conform on a logical level with its declaration.
Now whether it doesn't do as well as first thought, i.e. in case of possible confusion it doesn't sort out which is which (of a vector or a point made of a three values array) is even fine too in the end.
What merits to be pointed out, I thought, but maybe naively so, is that it precisely doesn't do that. That when faced with a choice, despite expectation, it always defers to one until it is entirely unambiguous that it is a point.
Note however that for the first argument it works, just not the second.
Me still being in the shoes of an API programmer, overlooking the fact that it would be way pretentious for me to do so, I can imagine that it could sort it out, or if not it could be mentioned as a caution. And that is all what is in question here.So all in all the issue is not with the fact that it does, which after all is understandable as you pointed out, but with the caution note about the exception to the rule.
Either the rule has no exception in print and thus it works, or it does have exception and then it would be nice to be pointed out. Which again I thought I did.I apologize if it is obvious to most seasoned programmers, and is in fact is a result of my novice status. Nevertheless some other green plugin programmers might benefit from this mention or at least so I thought. Thanks for your comments in any case.
-
I found it safer to always use
Geom::Point3d
andGeom::Vector3d
to avoid any potential ambiguity like this. -
We all know the API dictionary needs an overhaul.
I will agree it should mention that an array for arg2 will be converted to a
Geom::Vector3d
Advertisement