• Login
sketchucation logo sketchucation
  • Login
ℹ️ GoFundMe | Our friend Gus Robatto needs some help in a challenging time Learn More

Tricky Behavior project_to_line method

Scheduled Pinned Locked Moved Developers' Forum
7 Posts 3 Posters 213 Views
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    Michaelv
    last edited by 25 May 2012, 06:27

    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 result

    The 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.

    1 Reply Last reply Reply Quote 0
    • D Offline
      Dan Rathbun
      last edited by 25 May 2012, 06:52

      @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 a Geom::Point3d nor a Geom::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 a TypeError exception unless it was a Geom::Point3d or a Geom::Vector3d (even IF it was an valid Array that could be used to construct either one of the former.)

      I'm not here much anymore.

      1 Reply Last reply Reply Quote 0
      • D Offline
        Dan Rathbun
        last edited by 25 May 2012, 07:07

        Notice this console error:

        pointonline = [10,10,10].project_to_line [0,0,0] %(#008000)[Error: #<ArgumentError: (eval):0:inproject_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 on Array 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 the Sketchup module. (This bug has been reported.)

        I'm not here much anymore.

        1 Reply Last reply Reply Quote 0
        • M Offline
          Michaelv
          last edited by 25 May 2012, 19:35

          @dan rathbun said:

          Notice this console error:

          pointonline = [10,10,10].project_to_line [0,0,0] %(#008000)[Error: #<ArgumentError: (eval):0:inproject_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 on Array 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 the Sketchup 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.)

          1 Reply Last reply Reply Quote 0
          • M Offline
            Michaelv
            last edited by 25 May 2012, 19:37

            @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 a Geom::Point3d nor a Geom::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 a TypeError exception unless it was a Geom::Point3d or a Geom::Vector3d (even IF it was an valid Array 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.

            1 Reply Last reply Reply Quote 0
            • thomthomT Offline
              thomthom
              last edited by 26 May 2012, 12:22

              I found it safer to always use Geom::Point3d and Geom::Vector3d to avoid any potential ambiguity like this.

              Thomas Thomassen — SketchUp Monkey & Coding addict
              List of my plugins and link to the CookieWare fund

              1 Reply Last reply Reply Quote 0
              • D Offline
                Dan Rathbun
                last edited by 26 May 2012, 15:24

                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

                I'm not here much anymore.

                1 Reply Last reply Reply Quote 0
                • 1 / 1
                1 / 1
                • First post
                  1/7
                  Last post
                Buy SketchPlus
                Buy SUbD
                Buy WrapR
                Buy eBook
                Buy Modelur
                Buy Vertex Tools
                Buy SketchCuisine
                Buy FormFonts

                Advertisement