Page 1 of 67 1234511 ... LastLast
Results 1 to 10 of 670

Thread: The LaserBoy Thread

  1. #1
    Join Date
    Mar 2012
    Location
    Akron, Ohio USA
    Posts
    2,197

    Default The LaserBoy Thread

    Quote Originally Posted by colouredmirrorball View Post
    From what I gather, there is an option to remove all "in-between" collinear points and place them back using linear interpolation and a predefined distance, for both blanked and unblanked points. That sounds like something I'm capable of. Next there is the removal of angle dwell points, which I guess are points at the same location to allow scanners to come to a pause for a sharply defined corner? And adding them again. Is there a relation between angle size and amount of points added?
    Interesting how you can find the optimised path to go between segments.
    And then there is the mysterious "q"...
    I can't even begin to imagine what I'm missing.

    I'd love to talk about this in PM, to prevent a derailing of the thread.
    You got a lot of it.

    I have no idea what your 3D vector memory model is, but in LB I wrote the whole thing using my own classes and derived my collection classes by inheriting the STL <vector> class of my own component classes.

    Then I overloaded several operators for these classes so I can get down to the business of doing math on the objects as apposed to having to keep re-writing all the 3D vector math.

    My ultimate goal is to make the most perfect wave file I can from a frame set. So some of the optimization techniques go well beyond what might be stored in an ILDA file.

    I had to create what I call the intro, bridge and coda to lead into a frame, transition from the last vertex back to the first in a frame to repeat that frame and the transition from the last vertex to lead to the first vertex of the next frame.

    I also created a scan practice I call wagging. If you want to scan something that is like a simple line, it makes more sense to leave the laser on and scan it back and forth, rather than scan it in one direction, blank, return to the first vertex and scan again. There is a timing variable for how long it takes to scan an object before wagging becomes a flicker problem of it own. You set this in the [Tab] menu.

    None of that stuff gets stored in an ILDA file.

    But all the same, if you optimize the whole set of frames in LB you do get the shortest path through all the frames. The first frame is ordered to start at the vertex closest to the origin and the next frame starts at the vertex closest to the last vertex of the previous frame.

    There is a function that looks at all the vertices in a frame in sets of 3 in a row to measure the angle of approach and departure from every vertex. This is how I find and eliminate co-linear vertices and how I determine the need for dwell.

    There is an overloaded | (or) operator that gives the distance between any two vertex locations in 3D space.

    There is a function that finds individual lit strings of vertices (segments).

    There is a function that reveres-es the order of a segment of vertices.

    A frame is a segment. A segment is made of segments.

    I have both 3D short integer and 3D double precision floating point vertices and segments to be able to do all that neat math that involves irrational numbers.

    I use the 3D doubles to represent 3D angles of rotation, distance of offset and scaling factors.

    James.
    Last edited by james; 12-09-2014 at 12:00.
    Creator of LaserBoy!
    LaserBoy is free and runs in Windows, MacOS and Linux (including Raspberry Pi!).
    Download LaserBoy!
    YouTube Tutorials
    Ask me about my LaserBoy Correction Amp Kit for sale!
    All software has a learning curve usually proportional to its capabilities and unique features. Pointing with a mouse is in no way easier than tapping a key.

  2. #2
    Join Date
    Jul 2008
    Location
    My momentum is too precisely determined :S
    Posts
    1,777

    Default

    Of course... we cross posted. But for all I care the threads can coexist.

    It appears you have a lot of extra optimisation that is specifically for conversion to wave. Are the intro, bridge and coda the star and square symbols in Laserboy? How are they used? How are they retrieved from an existing ilda frame? Can they even be stored?

    Wagging is a new concept for me but definately something to remember.

    I use Processing which has its own 3D environment. Point coordinates are stored in a PVector, together with a colour int (which stores RGB values inside a single 32 bit integer), a palette int (referring to a colour index in a palette) and a blanked boolean. It works quite well but I have noticed it's not very economic in memory useage.
    Internally it only uses the colour int (= RGB values) as colour information for displaying and transforming. The palette int can be used to change this colour variable.

    I don't care much for the steps that would result in a better wave file since that's not one of my goals but since this is the LaserBoy thread nothing stops you from giving more details :P It's always interesting to learn more.

    Can you share details over how the path optimisation happens? Useful links to algorithms? Did you calculate the shortest Euclidean distance or is there some correction for scanner ballistics? Can a segment be broken into pieces if that would result in a shorter path? Is there any regard for continuity, as in if a frame is only slightly different than the previous one, is it more or less equal to the previous one or can the blanking be completely different?

    What do you mean by overloaded | operator? How does it work?

  3. #3
    Join Date
    Mar 2012
    Location
    Akron, Ohio USA
    Posts
    2,197

    Default

    Let's see....

    The star and square symbols are part of the GUI. They appear in menus K and L. They show you the selection of vertices from the egg (square) to the spider (star). You move them with the [{ and ]} keys or you can jump from one lit segment selection to the next with the U key.

    You can see the intro, bridge and coda if you turn them on in the U menu. But they only exist in optimized frames. They are segments that exist outside of the frame data, so they are not stored in an ILDA file.

    In LB there is a color class that is just 3 chars for R G B. There is a 3D short class that has X Y Z. Both of those are inherited into a vertex. The vertex has a char for a palette color index and a char for the blanking byte. A segment is a vector of vertex with an int to index into the list of palettes. A frame inherits the segment. A frame set is a vector of frames. Meanwhile there is a vector of colors that makes a palette and a vector of palettes that makes the palette set. The frame set and palette set are inherited by the space class.

    I can't point you to any references for shortest path algorithms. I had to figure that out on my own. I do account for the change in scan angle to get from here to there. It's a matter of how many samples it takes rather than just simple 3D distance.

    The | (bitwize or operator) returns the value of one integer or-ed with another bit for bit. But in C++ you can define what it does on your own classes. So I used it to give me the distance between two vertices.

    d = p1 | p2;

    That's a lot cleaner than having to write out all the code to do the Pythagorean calculation to find the hypotenuses every time you need it!

    I messed around a lot with the idea of breaking every segment into separated vectors, randomizing them and putting them back together in the best order. It can help for some things (like DXF imports) but for the most part it is best to keep lit segments whole and just look for the shortest path from the end of one to either end of any other. That's where reversing the direction of the segment comes in.

    James.
    Last edited by james; 12-09-2014 at 14:30.
    Creator of LaserBoy!
    LaserBoy is free and runs in Windows, MacOS and Linux (including Raspberry Pi!).
    Download LaserBoy!
    YouTube Tutorials
    Ask me about my LaserBoy Correction Amp Kit for sale!
    All software has a learning curve usually proportional to its capabilities and unique features. Pointing with a mouse is in no way easier than tapping a key.

  4. #4
    Join Date
    Jul 2008
    Location
    My momentum is too precisely determined :S
    Posts
    1,777

    Default

    Quote Originally Posted by james View Post
    Let's see....

    The star and square symbols are part of the GUI. They appear in menus K and L. They show you the selection of vertices from the egg (square) to the spider (star). You move them with the [{ and ]} keys or you can jump from one lit segment selection to the next with the U key.

    You can see the intro, bridge and coda if you turn them on in the U menu. But they only exist in optimized frames. They are segments that exist outside of the frame data, so they are not stored in an ILDA file.
    Hm... I found how to enable them in the u menu but so far had no succes in making them show up. What do they look like?

    Quote Originally Posted by james View Post
    In LB there is a color class that is just 3 chars for R G B. There is a 3D short class that has X Y Z. Both of those are inherited into a vertex. The vertex has a char for a palette color index and a char for the blanking byte. A segment is a vector of vertex with an int to index into the list of palettes. A frame inherits the segment. A frame set is a vector of frames. Meanwhile there is a vector of colors that makes a palette and a vector of palettes that makes the palette set. The frame set and palette set are inherited by the space class.
    I had to read that over and over and suddenly I got that with "vector" you mean an array or a list or collection or whatever you call it! LOL I literally thought about it in the meaning of a "vector" as in linear algebra, like (a, b, c) so when you talked about a vector of frames I thought a times frame 1 and b times frame 2 and so on. And with "inherits" I thought you meant that a segment is a kind of frame... as in OOP where frame would be the super class. Terminology is not my strong point, especially not in other languages.

    Wait, does this mean a segment can only have one palette index? So all points per segment have the same colour? How about transitions?

    Quote Originally Posted by james View Post
    I can't point you to any references for shortest path algorithms. I had to figure that out on my own. I do account for the change in scan angle to get from here to there. It's a matter of how many samples it takes rather than just simple 3D distance.
    Fair enough. I don't have the feeling I'm up to the task yet. More programming practice is in order...

    Quote Originally Posted by james View Post

    The | (bitwize or operator) returns the value of one integer or-ed with another bit for bit. But in C++ you can define what it does on your own classes. So I used it to give me the distance between two vertices.

    d = p1 | p2;

    That's a lot cleaner than having to write out all the code to do the Pythagorean calculation to find the hypotenuses every time you need it!
    As a Java guy, this just appears horrible. How can you possibly keep track of what everything does in each class? What if you actually need the bitwise or operator inside that class someday? Why not just do d = diff(p1, p2); or something? These kind of tricks are what makes C++ so damn hard to read.
    This is not meant as a derogatory remark to your programming skills. I don't know the background to these things so you probably have a good reason for that.

    Quote Originally Posted by james View Post

    I messed around a lot with the idea of breaking every segment into separated vectors, randomizing them and putting them back together in the best order. It can help for some things (like DXF imports) but for the most part it is best to keep lit segments whole and just look for the shortest path from the end of one to either end of any other. That's where reversing the direction of the segment comes in.

    James.
    I can see how this gets complicated. The hardest part is to do it in real time...

  5. #5
    Join Date
    Mar 2012
    Location
    Akron, Ohio USA
    Posts
    2,197

    Default

    Oh, yeah....

    In C++ there is this marvelous thing called The Standard Template Library (STL). It is a nice collection of container classes, iterators and algorithms. A Template class can be made of elements of your own type. One of the containers is called a <vectror> (note the angle braces). A vector is like an array in C or C++, but it's managed memory so you can add to it at the front, the rear or in the middle.

    When I say inherit, I mean that in the C++ OOP way. In C++ you can do multiple inheritance. So you can bring a color together with coordinates to make a vertex or you can bring a frame set and a palette set together to form a whole set of frames with palettes in the same class.

    There is no confusion about operator overloading. I defined my own class of a 3D vertex. There is no defined behavior of any of the math operators on that class. They are only defined on the atomic numerical data types.

    I also defined the + operator to be able to add a frame to another frame or to add a frame to a frame set, etc...

    I defined all the math of addition and multiplication for 3D vertices as well.

    So I can move a point by adding a 3D coordinate used to express offset. I can scale a segment by multiplying each vertex by a 3D factor.

    It actually makes the code a lot shorter and easier to read.

    Each segment has a pointer to a palette in the list of palettes loaded into memory. But a segment can have a palette index of -1 and LB interprets that as meaning 24-bit color. If a segment has a non-negative palette index, that palette is used to find the RGB values associated with the color index of each vertex in the segment.

    The intro, bridge and coda are all straight lines and mostly blank. You can hardly see them, even if you know where to look! If you turn on option f display vector order in Z in the U menu, you can see the order in which all of the vectors are drawn. So you can really see what optimizing is doing. You need to spin space around so you can see T (the time axis).
    Creator of LaserBoy!
    LaserBoy is free and runs in Windows, MacOS and Linux (including Raspberry Pi!).
    Download LaserBoy!
    YouTube Tutorials
    Ask me about my LaserBoy Correction Amp Kit for sale!
    All software has a learning curve usually proportional to its capabilities and unique features. Pointing with a mouse is in no way easier than tapping a key.

  6. #6
    Join Date
    Jan 2014
    Location
    North Carolina, USA
    Posts
    219

    Default

    Quote Originally Posted by colouredmirrorball View Post

    As a Java guy, this just appears horrible. How can you possibly keep track of what everything does in each class? What if you actually need the bitwise or operator inside that class someday? Why not just do d = diff(p1, p2); or something? These kind of tricks are what makes C++ so damn hard to read.
    This is not meant as a derogatory remark to your programming skills. I don't know the background to these things so you probably have a good reason for that.

    Welcome to the age old religious war between C++ and Java. Well, it's not so much of a war anymore, but definitely operator overloading is one of the "features" of C++ that are frowned upon by many developers. I am pretty much agnostic with respect to this feature of C++, however as you rightfully point out, it can be the cause for lots of confusion and misuse.

    When working on a C++ project, I myself try to ovoid operator overloading, just to simplify any future efforts of migrating the code to a different language.

    When working with a vector math library, I can see how it could be useful, but also could add some confusion... for instance:

    a + b : this would most likely be the addition of two vectors
    a - b : this should most likely be the subtraction of one vector from another
    but what is this:
    a * b?
    That could either be the dot product or the cross product. Lets assume it is the cross product. So now lets define a "dot" product operator...
    a.b?

    Can't do that...

    Also, lets say you want to the magnitude of a vector - in math class we learned that this is expressed as ||a|| - yet if you try to convert that to a meaningful C++ operator, you can't really do it.

    This is just a very simple example to show the deficiencies and confusion of operator overloading. It can make for nice syntactic sugar, but generally the cons outweigh the pros.
    Last edited by BlueFang; 12-09-2014 at 16:27.

  7. #7
    Join Date
    Jul 2008
    Location
    My momentum is too precisely determined :S
    Posts
    1,777

    Default

    Quote Originally Posted by james View Post
    Oh, yeah....

    In C++ there is this marvelous thing called The Standard Template Library (STL). It is a nice collection of container classes, iterators and algorithms. A Template class can be made of elements of your own type. One of the containers is called a <vectror> (note the angle braces). A vector is like an array in C or C++, but it's managed memory so you can add to it at the front, the rear or in the middle.

    When I say inherit, I mean that in the C++ OOP way. In C++ you can do multiple inheritance. So you can bring a color together with coordinates to make a vertex or you can bring a frame set and a palette set together to form a whole set of frames with palettes in the same class.
    That sounds like just a field inside a class...

    Quote Originally Posted by james View Post

    There is no confusion about operator overloading. I defined my own class of a 3D vertex. There is no defined behavior of any of the math operators on that class. They are only defined on the atomic numerical data types.

    I also defined the + operator to be able to add a frame to another frame or to add a frame to a frame set, etc...

    I defined all the math of addition and multiplication for 3D vertices as well.

    So I can move a point by adding a 3D coordinate used to express offset. I can scale a segment by multiplying each vertex by a 3D factor.

    It actually makes the code a lot shorter and easier to read.
    That makes sense. I hadn't looked at it in that way. Still freaks me out a bit though :P

    Quote Originally Posted by james View Post

    Each segment has a pointer to a palette in the list of palettes loaded into memory. But a segment can have a palette index of -1 and LB interprets that as meaning 24-bit color. If a segment has a non-negative palette index, that palette is used to find the RGB values associated with the color index of each vertex in the segment.

    The intro, bridge and coda are all straight lines and mostly blank. You can hardly see them, even if you know where to look! If you turn on option f display vector order in Z in the U menu, you can see the order in which all of the vectors are drawn. So you can really see what optimizing is doing. You need to spin space around so you can see T (the time axis).
    I wish you could somehow change the keys in LaserBoy. I'm sure they make great sense on a qwerty keyboard but the rotation keys are just all over the place. I have to hold alt gr for two of them. All this while you have a perfectly good unused mouse around which could take care of that in such an intuitive way...

    This has been a greater help so far than many C++ tutorials I tried. They always fail to explain what they are doing, while they are explaining how they are doing it. Not that I have tried many C++ tutorials...

  8. #8
    Join Date
    Mar 2012
    Location
    Akron, Ohio USA
    Posts
    2,197

    Default

    In OOP languages there are two ways to look at classes.

    is-a and has-a

    One class can be derived from another so class B is-a class A or one class can contain a member object. Class B has-a class A inside of it.

    Where is-a gives you all the power is through the this pointer.

    this points to the class itself. And through polymorphism, it points to any of the class' ancestors.

    In the case of LB vertex class it is-a color and a 3D short int at the same time via multiple inheritance (something you can't do in Java). But both of those concepts still exist separately. A palette is a <vector> of colors and 3D short ints can be used to designate arbitrary points inside of the cube of short ints. Neither one of them is a vertex. A vertex is both of them. So a vertex is-a color and also is-a 3D short int.

    Also a segment is-a <vector> of vertex. So you can index through the vertices using standard C array notation like segment[0], segment[1], segment[segment.size() - 1], etc...

    James.
    Last edited by james; 12-09-2014 at 16:54.
    Creator of LaserBoy!
    LaserBoy is free and runs in Windows, MacOS and Linux (including Raspberry Pi!).
    Download LaserBoy!
    YouTube Tutorials
    Ask me about my LaserBoy Correction Amp Kit for sale!
    All software has a learning curve usually proportional to its capabilities and unique features. Pointing with a mouse is in no way easier than tapping a key.

  9. #9
    Join Date
    Jul 2008
    Location
    My momentum is too precisely determined :S
    Posts
    1,777

    Default

    How weird to call both inheritance. In Java, only the is-a is inheritance, the has-a is called a field (like A has-a B so B is a field of A). That's begging for confusion.

    I can't really say my view of C++ has increased with these last few posts but sadly all DAC drivers use a C++ library/driver/.dll.
    Have you ever tried doing DAC output, James? With your skills you could probably do that in two minutes.

  10. #10
    Join Date
    Mar 2010
    Location
    Raleigh, NC
    Posts
    2,292

    Default

    James, are you refactoring your code to take advantage of the newer C++ features like move semantics? The new STL containers support moves. It's all really cool.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •