J
jon
Mon, Dec 26, 2016 1:50 AM
I've been writing some more pseudo code, and it seems that I need a
variety of 3D vector routines, including
dot product
cross product
normal to a triangle
angle between two vectors
rotate points around an axis
I rooted around on the web, and found most of the above. I took trig
and calculus, but it was ... a while ago. All of this is vaguely
familiar. If you know of either of the following resources, they would
be helpful to me.
- a complete library for these kinds of routines ... written in ...
Pascal. Yeah. I know. Old habits die hard.
B) a web site that has tutorials on all of this stuff, including matrix
math (which I assume I will need for the rotation).
I wasn't planning on rolling my own, but here I go...
Thanks for any hints
Jon
I've been writing some more pseudo code, and it seems that I need a
variety of 3D vector routines, including
dot product
cross product
normal to a triangle
angle between two vectors
rotate points around an axis
I rooted around on the web, and found most of the above. I took trig
and calculus, but it was ... a while ago. All of this is vaguely
familiar. If you know of either of the following resources, they would
be helpful to me.
1) a complete library for these kinds of routines ... written in ...
Pascal. Yeah. I know. Old habits die hard.
B) a web site that has tutorials on all of this stuff, including matrix
math (which I assume I will need for the rotation).
I wasn't planning on rolling my own, but here I go...
Thanks for any hints
Jon
P
Parkinbot
Mon, Dec 26, 2016 1:28 PM
It is always a good project to brush up your math.
This is the scalar product to be used for the threshold criterium. Apply it
with the normalized (i.e. length=1) normals of your triangles.
being applied to two vectors spanned by your triag's vertices will get you
the normal of your triangle. Adapt orientation by inverting the sign. Divide
this vector by its length and you get a normalized normal. If you start from
an STL you will already find this value for each triangle there.
angle between two vectors
the scalarproduct of two normalized vectors will be cos(angle). So
acos(dot(a,b)) is your friend.
rotate points around an axis
you find the three matrices in wikipedia
- a complete library for these kinds of routines ... written in ...
Pascal. Yeah. I know. Old habits die hard.
It is always a good project to brush up your math.
> dot product
This is the scalar product to be used for the threshold criterium. Apply it
with the normalized (i.e. length=1) normals of your triangles.
> cross product
being applied to two vectors spanned by your triag's vertices will get you
the normal of your triangle. Adapt orientation by inverting the sign. Divide
this vector by its length and you get a normalized normal. If you start from
an STL you will already find this value for each triangle there.
> angle between two vectors
the scalarproduct of two normalized vectors will be cos(angle). So
acos(dot(a,b)) is your friend.
> rotate points around an axis
you find the three matrices in wikipedia
> 1) a complete library for these kinds of routines ... written in ...
> Pascal. Yeah. I know. Old habits die hard.
http://www.dtic.mil/dtic/tr/fulltext/u2/a218917.pdf
--
View this message in context: http://forum.openscad.org/flattening-curved-surfaces-tp19727p19760.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
P
Parkinbot
Mon, Dec 26, 2016 2:06 PM
I supposed that at this stage, the coordinates of each points are already
known ?
Certainly, the 3D points are known e.g. from the STL. But common-edge
triags share two points. So each triag will be represented by a structure
like in C/C++
struct triag{
point3 x, y, z, n;
triag ** CE_neighbour;
}
while the topologic sets would be implemented as list (or some similar
container type) for easy (un-)hooking.
The definite implementation of course depends on the programming paradigma
you are using. It can be done in OpenSCAD, if you are willing to juggle
around with nested lists.
--
View this message in context: http://forum.openscad.org/flattening-curved-surfaces-tp19727p19762.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
runsun wrote
> I supposed that at this stage, the coordinates of each points are already
> known ?
Certainly, the 3D points are known e.g. from the STL. But *common-edge
triags* share two points. So each triag will be represented by a structure
like in C/C++
> struct triag{
> point3 x, y, z, n;
> triag ** CE_neighbour;
> }
while the topologic sets would be implemented as list (or some similar
container type) for easy (un-)hooking.
The definite implementation of course depends on the programming paradigma
you are using. It can be done in OpenSCAD, if you are willing to juggle
around with nested lists.
--
View this message in context: http://forum.openscad.org/flattening-curved-surfaces-tp19727p19762.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
NH
nop head
Mon, Dec 26, 2016 3:17 PM
Here is an approximate solution for objects with cylindrical surfaces:
le = 10; // length
d1 = 25; // diameter of top
d2 = 35; // diameter of bottom
d3 = 30; // side cylinders
d = -8; // delta to drop center of bottom
$fn = 100;
z_offset = -6;
x_offset = 10;
module shape() {
translate([0, 0, z_offset])
intersection(c) {
translate([x_offset, 0, 0])
cylinder(h = 100, d = d3);
translate([-x_offset, 0, 0])
cylinder(h = 100, d = d3);
difference() {
rotate([0, 90, 0])
cylinder(h = le, d = d1, center = true);
translate([0, 0, d])
rotate([0, 90, 0])
cylinder(h = le + 2, d = d2, center = true);
}
}
}
%translate([0, 0, 5]) render() shape();
module flatten_cylinder(diameter, width, angle = 180, steps = 30 ) {
length = angle / 360 * PI * diameter;
for(i = [-steps / 2 + 1 : steps / 2 - 1])
translate([0, i * length / steps, 0])
offset(0.0001) projection() // expand slighly so they overlap
union() {
intersection() {
cube([width + 1, length / steps, diameter * (1 -
cos(angle / (steps * 2))) * 1.4], center = true);
translate([0, 0, -diameter / 2])
rotate([i * angle / steps, 0 , 0])
children();
}
}
}
flatten_cylinder(d1, le)
translate([0, 0, -z_offset])
shape();
translate([le + 1, 0])
flatten_cylinder(d2, le)
translate([0, 0, -z_offset - d])
shape();
translate([2 * le - 3, 0])
flatten_cylinder(d3, 2 * le)
translate([0, 0, x_offset])
rotate([0, 90, 0])
shape();
translate([-le + 3, 0])
flatten_cylinder(d3, 2 * le)
translate([0, 0, x_offset])
rotate([0, -90, 0])
shape();
It works by sampling a segment of the cylindrical surface by rotation,
projecting it flat and stitching the flat sections together. I can't
explain the *1.4 bodge, it is probably a bug in my logic or the fact that
they are not real cylinders.
On 26 December 2016 at 14:06, Parkinbot rudolf@parkinbot.com wrote:
I supposed that at this stage, the coordinates of each points are already
known ?
Certainly, the 3D points are known e.g. from the STL. But common-edge
triags share two points. So each triag will be represented by a structure
like in C/C++
struct triag{
point3 x, y, z, n;
triag ** CE_neighbour;
}
Here is an approximate solution for objects with cylindrical surfaces:
le = 10; // length
d1 = 25; // diameter of top
d2 = 35; // diameter of bottom
d3 = 30; // side cylinders
d = -8; // delta to drop center of bottom
$fn = 100;
z_offset = -6;
x_offset = 10;
module shape() {
translate([0, 0, z_offset])
intersection(c) {
translate([x_offset, 0, 0])
cylinder(h = 100, d = d3);
translate([-x_offset, 0, 0])
cylinder(h = 100, d = d3);
difference() {
rotate([0, 90, 0])
cylinder(h = le, d = d1, center = true);
translate([0, 0, d])
rotate([0, 90, 0])
cylinder(h = le + 2, d = d2, center = true);
}
}
}
%translate([0, 0, 5]) render() shape();
module flatten_cylinder(diameter, width, angle = 180, steps = 30 ) {
length = angle / 360 * PI * diameter;
for(i = [-steps / 2 + 1 : steps / 2 - 1])
translate([0, i * length / steps, 0])
offset(0.0001) projection() // expand slighly so they overlap
union() {
intersection() {
cube([width + 1, length / steps, diameter * (1 -
cos(angle / (steps * 2))) * 1.4], center = true);
translate([0, 0, -diameter / 2])
rotate([i * angle / steps, 0 , 0])
children();
}
}
}
flatten_cylinder(d1, le)
translate([0, 0, -z_offset])
shape();
translate([le + 1, 0])
flatten_cylinder(d2, le)
translate([0, 0, -z_offset - d])
shape();
translate([2 * le - 3, 0])
flatten_cylinder(d3, 2 * le)
translate([0, 0, x_offset])
rotate([0, 90, 0])
shape();
translate([-le + 3, 0])
flatten_cylinder(d3, 2 * le)
translate([0, 0, x_offset])
rotate([0, -90, 0])
shape();
It works by sampling a segment of the cylindrical surface by rotation,
projecting it flat and stitching the flat sections together. I can't
explain the *1.4 bodge, it is probably a bug in my logic or the fact that
they are not real cylinders.
On 26 December 2016 at 14:06, Parkinbot <rudolf@parkinbot.com> wrote:
> runsun wrote
> > I supposed that at this stage, the coordinates of each points are already
> > known ?
>
> Certainly, the 3D points are known e.g. from the STL. But *common-edge
> triags* share two points. So each triag will be represented by a structure
> like in C/C++
>
> > struct triag{
> > point3 x, y, z, n;
> > triag ** CE_neighbour;
> > }
>
> while the topologic sets would be implemented as list (or some similar
> container type) for easy (un-)hooking.
>
> The definite implementation of course depends on the programming paradigma
> you are using. It can be done in OpenSCAD, if you are willing to juggle
> around with nested lists.
>
>
>
>
> --
> View this message in context: http://forum.openscad.org/
> flattening-curved-surfaces-tp19727p19762.html
> Sent from the OpenSCAD mailing list archive at Nabble.com.
>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>
P
Parkinbot
Mon, Dec 26, 2016 10:11 PM
nophead,
without access to the vertex representation, but to the full set of
construction parameters this looks viable. Nevertheless, it undoutedly is a
lot of hard work, that you will have to do at least for each new object
class.
The sketched algorithm is completely unaware to how the 3D-object was
created or is formed. It uses STL (AMF) data to separate the surfaces by use
of the threshold and builds on the assumption they can be unrolled.
There might be examples, where a practicable threshold can't be found for a
given design. But in most cases this can be solved by retrying with a
rendering with increased resolution.
What, if the assumption doesn't hold? Well, the result will be bad and the
generated 2D shape will be scattered somehow. In this case, I would advise
to review the original design, but one can also try to approximately unroll
an unrollable surface by applying some regression scheme.
Since Jon came up with this idea, I don't want to spoil his enjoyment and
dedication by presenting some code. So let's give him some time and wait for
his results.
--
View this message in context: http://forum.openscad.org/flattening-curved-surfaces-tp19727p19768.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
nophead,
without access to the vertex representation, but to the full set of
construction parameters this looks viable. Nevertheless, it undoutedly is a
lot of hard work, that you will have to do at least for each new object
class.
The sketched algorithm is completely unaware to how the 3D-object was
created or is formed. It uses STL (AMF) data to separate the surfaces by use
of the threshold and builds on the assumption they can be unrolled.
There might be examples, where a practicable threshold can't be found for a
given design. But in most cases this can be solved by retrying with a
rendering with increased resolution.
What, if the assumption doesn't hold? Well, the result will be bad and the
generated 2D shape will be scattered somehow. In this case, I would advise
to review the original design, but one can also try to approximately unroll
an unrollable surface by applying some regression scheme.
Since Jon came up with this idea, I don't want to spoil his enjoyment and
dedication by presenting some code. So let's give him some time and wait for
his results.
--
View this message in context: http://forum.openscad.org/flattening-curved-surfaces-tp19727p19768.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
J
jon
Mon, Dec 26, 2016 10:17 PM
LOL! Spoil his enjoyment!
It is written, but not working yet. My approach is to find triangles
that share a side, and then compute the angle between normals for those
two triangles. If the angle is small (the normals are roughly the same)
then I assume those two triangles are on a surface together. Once the
surfaces are identified, then I have to flatten them out. Still a ways
to go, but it seems feasible, and (as Parkinbot wrote) using an STL will
allow others to design surfaces to be flattened.
Just a start at the moment. Rolling all of my vector routines was not
difficult, but then again, it's not working yet, so I'm sure there are
many bugs to be found
:)
On 12/26/2016 5:11 PM, Parkinbot wrote:
nophead,
without access to the vertex representation, but to the full set of
construction parameters this looks viable. Nevertheless, it undoutedly is a
lot of hard work, that you will have to do at least for each new object
class.
The sketched algorithm is completely unaware to how the 3D-object was
created or is formed. It uses STL (AMF) data to separate the surfaces by use
of the threshold and builds on the assumption they can be unrolled.
There might be examples, where a practicable threshold can't be found for a
given design. But in most cases this can be solved by retrying with a
rendering with increased resolution.
What, if the assumption doesn't hold? Well, the result will be bad and the
generated 2D shape will be scattered somehow. In this case, I would advise
to review the original design, but one can also try to approximately unroll
an unrollable surface by applying some regression scheme.
Since Jon came up with this idea, I don't want to spoil his enjoyment and
dedication by presenting some code. So let's give him some time and wait for
his results.
--
View this message in context: http://forum.openscad.org/flattening-curved-surfaces-tp19727p19768.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
No virus found in this message.
Checked by AVG - www.avg.com
Version: 2016.0.7924 / Virus Database: 4739/13653 - Release Date: 12/26/16
LOL! Spoil his enjoyment!
It is written, but not working yet. My approach is to find triangles
that share a side, and then compute the angle between normals for those
two triangles. If the angle is small (the normals are roughly the same)
then I assume those two triangles are on a surface together. Once the
surfaces are identified, then I have to flatten them out. Still a ways
to go, but it seems feasible, and (as Parkinbot wrote) using an STL will
allow others to design surfaces to be flattened.
Just a start at the moment. Rolling all of my vector routines was not
difficult, but then again, it's not working yet, so I'm sure there are
many bugs to be found
:)
On 12/26/2016 5:11 PM, Parkinbot wrote:
> nophead,
> without access to the vertex representation, but to the full set of
> construction parameters this looks viable. Nevertheless, it undoutedly is a
> lot of hard work, that you will have to do at least for each new object
> class.
>
> The sketched algorithm is completely unaware to how the 3D-object was
> created or is formed. It uses STL (AMF) data to separate the surfaces by use
> of the threshold and builds on the assumption they can be unrolled.
> There might be examples, where a practicable threshold can't be found for a
> given design. But in most cases this can be solved by retrying with a
> rendering with increased resolution.
>
> What, if the assumption doesn't hold? Well, the result will be bad and the
> generated 2D shape will be scattered somehow. In this case, I would advise
> to review the original design, but one can also try to approximately unroll
> an unrollable surface by applying some regression scheme.
>
> Since Jon came up with this idea, I don't want to spoil his enjoyment and
> dedication by presenting some code. So let's give him some time and wait for
> his results.
>
>
>
>
>
> --
> View this message in context: http://forum.openscad.org/flattening-curved-surfaces-tp19727p19768.html
> Sent from the OpenSCAD mailing list archive at Nabble.com.
>
> _______________________________________________
> OpenSCAD mailing list
> Discuss@lists.openscad.org
> http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
>
>
>
> -----
> No virus found in this message.
> Checked by AVG - www.avg.com
> Version: 2016.0.7924 / Virus Database: 4739/13653 - Release Date: 12/26/16
>
>
P
Parkinbot
Mon, Dec 26, 2016 11:39 PM
Hey, it is your project. So don't be modest. Great idea!
jon_bondy wrote
My approach is to find triangles that share a side, and then compute the
angle between normals for those
two triangles.
You don't need to calc the angle. The dot product of two normalized vectors
is 0 when orthogonal, 1 when parallel and -1 when antiparallel. You want
them almost parallel. So you can use a value a bit less then 1 as threshold.
Hint: for every final surface unroll you can easily calculate a bounding
box, and optimize the arrangement of the result for output.
--
View this message in context: http://forum.openscad.org/flattening-curved-surfaces-tp19727p19770.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
Hey, it is your project. So don't be modest. Great idea!
jon_bondy wrote
> My approach is to find triangles that share a side, and then compute the
> angle between normals for those
> two triangles.
You don't need to calc the angle. The dot product of two normalized vectors
is 0 when orthogonal, 1 when parallel and -1 when antiparallel. You want
them almost parallel. So you can use a value a bit less then 1 as threshold.
Hint: for every final surface unroll you can easily calculate a bounding
box, and optimize the arrangement of the result for output.
--
View this message in context: http://forum.openscad.org/flattening-curved-surfaces-tp19727p19770.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
MS
Mark Schafer
Tue, Dec 27, 2016 1:15 AM
great idea but consider making an edgelist and traversing that.
Two reasons:
- an edge will have a face on either side and so the angle between faces
can be easily calculated and associated with the edge.
- if you're going to preserve some edges (e.g. where you want a split to
occur), its handy to be able to group edges into lists
On 12/27/2016 11:17 AM, jon wrote:
LOL! Spoil his enjoyment!
It is written, but not working yet. My approach is to find triangles
that share a side, and then compute the angle between normals for
those two triangles. If the angle is small (the normals are roughly
the same) then I assume those two triangles are on a surface
together. Once the surfaces are identified, then I have to flatten
them out. Still a ways to go, but it seems feasible, and (as
Parkinbot wrote) using an STL will allow others to design surfaces to
be flattened.
Just a start at the moment. Rolling all of my vector routines was not
difficult, but then again, it's not working yet, so I'm sure there are
many bugs to be found
:)
On 12/26/2016 5:11 PM, Parkinbot wrote:
nophead,
without access to the vertex representation, but to the full set of
construction parameters this looks viable. Nevertheless, it
undoutedly is a
lot of hard work, that you will have to do at least for each new object
class.
The sketched algorithm is completely unaware to how the 3D-object was
created or is formed. It uses STL (AMF) data to separate the surfaces
by use
of the threshold and builds on the assumption they can be unrolled.
There might be examples, where a practicable threshold can't be found
for a
given design. But in most cases this can be solved by retrying with a
rendering with increased resolution.
What, if the assumption doesn't hold? Well, the result will be bad
and the
generated 2D shape will be scattered somehow. In this case, I would
advise
to review the original design, but one can also try to approximately
unroll
an unrollable surface by applying some regression scheme.
Since Jon came up with this idea, I don't want to spoil his enjoyment
and
dedication by presenting some code. So let's give him some time and
wait for
his results.
great idea but consider making an edgelist and traversing that.
Two reasons:
- an edge will have a face on either side and so the angle between faces
can be easily calculated and associated with the edge.
- if you're going to preserve some edges (e.g. where you want a split to
occur), its handy to be able to group edges into lists
On 12/27/2016 11:17 AM, jon wrote:
> LOL! Spoil his enjoyment!
>
> It is written, but not working yet. My approach is to find triangles
> that share a side, and then compute the angle between normals for
> those two triangles. If the angle is small (the normals are roughly
> the same) then I assume those two triangles are on a surface
> together. Once the surfaces are identified, then I have to flatten
> them out. Still a ways to go, but it seems feasible, and (as
> Parkinbot wrote) using an STL will allow others to design surfaces to
> be flattened.
>
> Just a start at the moment. Rolling all of my vector routines was not
> difficult, but then again, it's not working yet, so I'm sure there are
> many bugs to be found
>
> :)
>
>
> On 12/26/2016 5:11 PM, Parkinbot wrote:
>> nophead,
>> without access to the vertex representation, but to the full set of
>> construction parameters this looks viable. Nevertheless, it
>> undoutedly is a
>> lot of hard work, that you will have to do at least for each new object
>> class.
>>
>> The sketched algorithm is completely unaware to how the 3D-object was
>> created or is formed. It uses STL (AMF) data to separate the surfaces
>> by use
>> of the threshold and builds on the assumption they can be unrolled.
>> There might be examples, where a practicable threshold can't be found
>> for a
>> given design. But in most cases this can be solved by retrying with a
>> rendering with increased resolution.
>>
>> What, if the assumption doesn't hold? Well, the result will be bad
>> and the
>> generated 2D shape will be scattered somehow. In this case, I would
>> advise
>> to review the original design, but one can also try to approximately
>> unroll
>> an unrollable surface by applying some regression scheme.
>>
>> Since Jon came up with this idea, I don't want to spoil his enjoyment
>> and
>> dedication by presenting some code. So let's give him some time and
>> wait for
>> his results.
>>
>>
>>
J
jon
Tue, Dec 27, 2016 1:44 AM
I am not sure that I see the utility in knowing the edges if I'm trying
to create a surface. If I get in trouble with my current approach, I
will check back with y'all
On 12/26/2016 8:15 PM, Mark Schafer wrote:
great idea but consider making an edgelist and traversing that.
Two reasons:
- an edge will have a face on either side and so the angle between
faces can be easily calculated and associated with the edge.
- if you're going to preserve some edges (e.g. where you want a split
to occur), its handy to be able to group edges into lists
I am not sure that I see the utility in knowing the edges if I'm trying
to create a surface. If I get in trouble with my current approach, I
will check back with y'all
On 12/26/2016 8:15 PM, Mark Schafer wrote:
> great idea but consider making an edgelist and traversing that.
> Two reasons:
> - an edge will have a face on either side and so the angle between
> faces can be easily calculated and associated with the edge.
> - if you're going to preserve some edges (e.g. where you want a split
> to occur), its handy to be able to group edges into lists
>
R
runsun
Tue, Dec 27, 2016 5:30 PM
Certainly, the 3D points are known e.g. from the STL. But common-edge
triags share two points. ...
What I have in mind is that, if the points are known, we should be able to
calc the angles and relative position between points, then copy them onto a
flat surface. That is, no triagulation/hooking/unhooking is needed.
Certainly, this is under the circumstance that we know the shape and be able
to visualize neighboring points before proceeding. I guess you are looking
for a more general approach in which we just throw in points (w/o seeing the
shape) and let the program decides the neighboring points of each point.
$ Runsun Pan, PhD $ libs: doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), synwrite ( 2 ); $ tips: Bezier , hash ( 2 ), matrix ( 2 , 3 ), sweep ( 2 , 3 ), var ( 2 ), lerp , animation ( gif , prodVid , animlib ), precision ( 2 ), xl-control , type , rounded polygon , chfont , tailRecur ( 2 , 3 , 4 ), isosphere ( 2 ), area , vol/center , RGB , CurvedImg , tests ( 2 ), text , triang , unit ; $ Apps: rollApp , blockscad , openjscad , on AWS ( pdf ), support_tools
--
View this message in context: http://forum.openscad.org/flattening-curved-surfaces-tp19727p19779.html
Sent from the OpenSCAD mailing list archive at Nabble.com.
Parkinbot wrote
> Certainly, the 3D points are known e.g. from the STL. But *common-edge
> triags* share two points. ...
What I have in mind is that, if the points are known, we should be able to
calc the angles and relative position between points, then copy them onto a
flat surface. That is, no triagulation/hooking/unhooking is needed.
Certainly, this is under the circumstance that we know the shape and be able
to visualize neighboring points before proceeding. I guess you are looking
for a more general approach in which we just throw in points (w/o seeing the
shape) and let the program decides the neighboring points of each point.
-----
$ Runsun Pan, PhD $ libs: doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), synwrite ( 2 ); $ tips: Bezier , hash ( 2 ), matrix ( 2 , 3 ), sweep ( 2 , 3 ), var ( 2 ), lerp , animation ( gif , prodVid , animlib ), precision ( 2 ), xl-control , type , rounded polygon , chfont , tailRecur ( 2 , 3 , 4 ), isosphere ( 2 ), area , vol/center , RGB , CurvedImg , tests ( 2 ), text , triang , unit ; $ Apps: rollApp , blockscad , openjscad , on AWS ( pdf ), support_tools
--
View this message in context: http://forum.openscad.org/flattening-curved-surfaces-tp19727p19779.html
Sent from the OpenSCAD mailing list archive at Nabble.com.