jscad / csg.js

DEPRECATED: CSG Library for JSCAD (See the link below)
https://github.com/jscad/OpenJSCAD.org/tree/master/packages/modeling
MIT License
218 stars 56 forks source link

future directions, what does a user need? #135

Open hg42 opened 5 years ago

hg42 commented 5 years ago

i first wrote this in another issue, but it's not the place for this discussion, but you triggered it by a statement in issue #96:

I REALLY dislike the imperative "lineTo", and "bezierTo"

declarative is fine, and I am voting for it, but...

please keep in mind, that lineTo, moveTo, ... usually makes sense with relative movement. lineTo with relative coordinates is about adding vectors instead of defining points.

One reason to use functions like this is the possibility to allow different kinds (like bezier or arc) for each segment. Most declarative systems lack the possibility to define different properties for segments and nodes.

Also, I don't really agree that lineTo is imperative in nature (though I understand why you are saying this). From my POV lineTo declares(!) a line just like start and end point do. It only reuses (=connects to) the end of the previous object. So it's not stateless in some way, which might look bad at first. But, in graphics there is a difference between single, separate lines and connected lines. Connections are different from ends, they can have a radius or be smoothed, they could even have extra shapes like spheres. In general there must be some definition how to connect one object to the next, which is not always obvious (e.g. how do you connect two rectangular bars, with different rotations? The ends can also have their own shapes, e.g. spherical, rectangular, arrow, etc. In this respect line and lineTo is something very different.

Actually, you can do both absolute and relative coordinates in both declarative and imperative systems. But unfortunately most systems have only one of them.

Systems that have all of this usually need words for three kinds:

A library uses a mathematical model and usually prefers absolute points in a consistent way. And programmers tend to export this interface to the user. Less work, less errors.

But users don't think so. They think mostly in relative terms. Actually, they need both ways dependent on the situation. And they like to use definitions that can use the values they measured.

Let's imagine my right arm. It's connected to my shoulder = upper right edge of my body. It has two parts, the first is a kind of cylinder starting at a circumference of 50cm, 27 cm long, 30° to the right, 20° to the front both relative to my body axis, it ends in a circumference of 40cm. the second is another kind of cylinder continuing the first, 25 cm long, ending at a circumference of 20cm, and it is directed horizontally to the front.

As a human you choose terms that fit the purpose. So it's mostly relative, but sometimes absolute. You would certainly use measurements directly if you would be allowed to. At least in systems where this is possible I do it all the time, saving a lot of calculations. Which especially means, you nearly never use a radius, because you never measure it this way. You are thinking in diameters or in some cases in circumference depending on your equipment. And you also don't position a sphere by its center.

I think, jscad would benefit from having more "relative" or other "easy" features. Users do not really like to calculate (e.g. start points), especially if it's not necessary. The computer should do the work as much as possible. There should be alternative ways to describe something (the python way is academic, not natural).

Let's look at a rounded rectangle size 100x200 at position 500,600 with radius 5 at the top corners and radius 0 at bottom corners. Now write that down as a path 1. in absolute coordinates and 2. in relative coordinates. Say we want to describe a tube running along this path.

  1. absolute points, counter clock:
    • 500|600
    • 500+100|600
    • 500+100|600+200-5
    • arc center=500+100-5|600+200-5 radius=5 start=0° end=90°
    • 5|600+200
    • arc center=5|600+200-5 radius=5 start=90° end=180°
    • 500|600
    • => lots of calculations, lots of repeated terms
  2. relative positioning, absolute directions, counter clock:
    • jump 500|600
    • straight 0|100
    • straight 200-5|0
    • arc 90° r=5
    • straight -(100-5-5)|0
    • arc 90° r=5
    • straight 0|-(200-5)
    • => MUCH quicker to write, some thoughts remain about absolute coordinate directions
  3. relative positioning, relative directions, counter clock:
    • jump 500|600 direction=0°
    • straight 100
    • turn 90°
    • straight 200-5
    • arc 90° r=5
    • straight 100-5-5
    • arc 90° r=5
    • straight 100-5
    • => even faster, nicer to think, more human, no more fiddling with x|y when I really think in lengths
  4. (what you really want...) define the length without the radius and declare how it should be rounded
    • jump 500|600 direction=0°
    • straight 100
    • corner 90°
    • straight 200 (!)
    • corner 90° r=5
    • straight 100
    • corner 90° r=5
    • straight 100
    • => faster again, no more differences (think of r=3.7564), the computer does all the work

For users it's definetly a lot easier to define a figure by method 4 than by method 1.

From another POV: My usual 3D designs are full of calculations to find absolute coordinates. I have to do trigonometrics, pythagoras etc. even for very simple designs. Everything that is non-rectangular and cannot be expressed with rotation etc. quickly becomes a real mess. While I am thinking very simple constructions I have to compile it for the graphical language.

So, please try to keep mathematics and programming separate from what a user wants to use. Or would you program in assembler? How would a user construct something, if not forced by a language to think in a special way? Also find NEW ways to help users...

jscad already offers some of this: rotation around a point (in some other software you have to move the object to 0|0 rotate and then move back, wtf...) chainHull (very simple, but very useful, especially 3D, I programmed this little function myself for openscad) connectors (huge possibilities, but from my first contacts it seems to get not much love, it heavily depends on the connection points available)

some future wishes:

hg42 commented 5 years ago

more wishes:

kaosat-dev commented 5 years ago

@hg42 Thanks for posting your thoughts : some things I agree on , some others not, I'll reply In detail later: but in the meantime: V2 is meant

Sorry if I do not go into more depth about your other points yet, very short on time :)

hg42 commented 5 years ago

to be clear, this was only meant as a kind of brain storming (mainly because @z3dev encouraged me to do). I generally appreciate what I see in V2 and what you are communicating about it. The whole thing getting more modular makes jscad much more attractive for me.

Especially, I noticed, that you are going to drop dependencies to openscad compatibility (while this might be maintained as one of the possible front ends). This probably breaks some chains and creates more openness to new possibilities. My comment was a kind of explosion, some things that are in my brain for a long time now and somehow blocked by leaning on openscad (while I already used python to extend it in several ways).

z3dev commented 5 years ago

@hg42 please keep those thoughts coming. :)

These are all good points, some new and some known. Later, we can pick out some of these as possible work, and see if JSCAD can be even more useable.

And like @kaosat-dev mentioned; V1 CSG is the stable version. You can wait for V2, or prototype a few more fixes using V1. I’m not finding the mental shift difficult so, whatever you do should be possible in V2.

pentacular commented 5 years ago

I think that the 'scad api' is a good approach to this problem.

We can provide a number of apis which provide convenience to the user.

This can include things like lineTo(), which can then do something line incrementally building a path using a declarative approach.

Which means that we can focus on keeping the core clean for development, and focus on keeping user apis convenient for users.