how to define a simple 2D-contour/polygon WITH ARCS that can be extruded ??

386 views
Skip to first unread message

Ottmar Petry

unread,
Feb 20, 2013, 3:07:47 AM2/20/13
to vpytho...@googlegroups.com
Hello.
I am just starting with VPython and work on a project to visualize a (wooden) board (like a board from a kitchen).
It has a 2d-geometry - most times based on a rectangle but maybe with arcs in the corner or also outer-contours
with some arcs. There is always an outer-contour that has to be extruded, e.g. 20mm to show a 20mm thick board.

Now my question:
what is the best way to define the outer-contour of such a board based on lines and arcs ?
This contour/ polyline? then needs to be extruded e.g. to a thickness of 20mm.

E.g. think about a contour like

startpoint: X0,Y0
line to: X900, Y0
arc to: X1000, Y100, RAD=100, centreX=900, centreY=100
line to: X1000, Y450
arc to: X950, Y500, RAD=50, centreX=950, centreY=450
line to: X0, Y500
line to: X0, Y0   <<< closed contour/polyline

this contour should be the outer-contour to be extruded.

How is the best way to define such 2 2D-contour with VPython ??
Are there objects to define an arc inside a contour-/polyline-definition ?
If so, where can I find a documentation of this detail ?

I hope that someone can help me.

Thanks in advance and best regards


Bruce Sherwood

unread,
Feb 20, 2013, 9:58:46 AM2/20/13
to vpytho...@googlegroups.com
There are two ways to construct the 2D shape to be extruded. You can specify the points yourself in a list given to the Polygon object, or you can use elements from the shapes library. The Help on extrusion has a link to the shapes library, which includes an arc shape.

Moreover, in the shapes library you'll see that for the rectangle shape you can specify rounded or inverted rounded corners, which may satisfy your need.

In the example programs "extrusion_examples.py" by Kadir Haldenbilen illustrates a wide variety of uses of the extrusion object. My example program "extrusion_overview.py" may also be informative.

Ottmar Petry

unread,
Feb 21, 2013, 5:42:29 AM2/21/13
to vpytho...@googlegroups.com
Hello Bruce or someone else who can help me.

Thanks for your answer.
I tried a lot but could not find out a way how a closed contour using lines AND arcs can be 
defined so that this contour then can be extruded.
Attached you find my trials as file myShape.PY together with some drawings defining which
quite simple contour I want do define: some arcs and some lines - but the arcs are not
roundings of a rectangle.

some other questions :

where can I find some kind of header-files describing which parameters are possible
e.g. to define an arc and the way how an arc is constructed:
e.g. from angle1 to angle2 counterclockwise, or ??
because using centerpoint, radius and angle1 and angle2 there are 2 different arcs 
possible. 

I think that I can continue if someone sends me a proposal how such a closed contour
of lines and arcs can be defined and extruded.

Thanks in advance and best regards
Ottmar
myShape.zip

Ottmar Petry

unread,
Feb 21, 2013, 5:43:13 AM2/21/13
to vpytho...@googlegroups.com

Bruce Sherwood

unread,
Feb 21, 2013, 11:47:00 AM2/21/13
to vpytho...@googlegroups.com
Here is a program that creates the extrusion you want. The basic idea is to add and subtract rectangles and disks. 

Another possible approach would be to make a Python list of positions along the straight parts of the contour and then extend the list with the pos attribute of paths.arc. That is, if p is a list of the points along the straight parts of the path, p.extend(a.pos) to add arc points to the path, where a = paths.arc(....). Note that paths are in the xz plane; see the example program extrusion_overview.py for a visualization of this issue.

from __future__ import print_function, division
from visual import *

#-----------------------------------------------------------------------------------
# define a "board" using arcs and lines as a closed contour
# this board should be extruded e.g. with a thickness od 20 mm (see var. straight)
#-----------------------------------------------------------------------------------
        
scene.title = "mySHAPE"
scene.height = 1000
scene.width = 1500
scene.range = 600

scene.center = (500, 250, 10)

# workpiece must have thickness of 20 mm
straight = [(0,0,0),(0,0,-20)] # extrude in -z direction

# Create four sections. The first is the left half of the board.
s1 = shapes.rectangle(pos=(250,250), width=500, height=500)

# The second from the left is a rectangle from which we subtract a circle (a disk)
r2 = shapes.rectangle(pos=(600,150), width=200, height=300)
c2 = shapes.circle(pos=(600,300), radius=100)
s2 = r2-c2

# The third from the left is a rectangle to which we add a circle, then
# subtract the right half of the material.
r3 = shapes.rectangle(pos=(900,150), width=400, height=300)
c3 = shapes.circle(pos=(900,300), radius=200)
r3b = shapes.rectangle(pos=(1000,250), width=200, height=500)
s3 = r3+c3-r3b

# The fourth from the left is like the third.
r4 = shapes.rectangle(pos=(900,200), width=200, height=400)
c4 = shapes.circle(pos=(900,400), radius=100)
r4b = shapes.rectangle(pos=(850,250), width=100, height=500)
s4 = r4+c4-r4b

C = s1+s2+s3+s4 # Set C = s1 or s2 or s3 or s4 to see the individual contributions

# why is Polygon always closed ??  can I define an unclosed Polygon ??
# The Polygon module, not written by those developing VPython, only handles closed contours.

# From the Help on extrusion:
# Instead of giving Polygon closed contours of shapes, alternatively you can specify
# the 2D shape as a simple list of 2D points that need not constitute a closed contour,
# as in the upper object shown at the right. Here is the program:
##s = [(-3,5), (0,0), (-3,-5)]
##p = [(-7,0,5), (5,0,-5)]
##extrusion(pos=p, shape=s,
##          color=color.orange, 
##          material=materials.wood)

# It should be possible to use the paths library to create a list of positions.

myExt_Arc = extrusion(pos=straight, shape=C, color=color.yellow)


Ottmar Petry

unread,
Feb 21, 2013, 12:34:00 PM2/21/13
to vpytho...@googlegroups.com
Thanks very much for this approach.

But this is not a possible solution for me because I get the outer contour as a polyline with
lines and arcs and then it is not possible to split this contour into rectangles and disks 
which then have to be added or subtracted to build the desired outer-contour.

I need an approach where I can convert each element from my input-polylines-data 
(i.e. consecutive lines and arcs) to a VPython element that can be extruded.
But I don´t understand your description how to handle the arcs  ... "p.extend(a.pos)" ...

I think that my task is a quite general task: you have a (closed) contour with lines and arcs
and want this contour to be extruded.
So I think that an example showing how this can be defined and handled would be of interest
also for other people.

So, if possible please use my data to define the contour in the alternative way.
I did not find an existing example where arcs and lines were used together to built an extrudable
consecutive contour.

Thanks in advance and best regards
Ottmar



Bruce Sherwood

unread,
Feb 21, 2013, 2:59:52 PM2/21/13
to vpytho...@googlegroups.com
Here is a way to use the paths library (which creates paths in the xz plane), plus a simple list of coordinates in the xz plane for the straight lines, to create a Polygon to be extruded.

I'll add that the reason a Polygon must be closed is because this is a very special object that enables "2D constructive geometry", in which Polygon objects can be added, subtracted, exclusive or-ed, and intersected. None of these operations are possible with a simple list of points, nor could these operations be carried out with a non-closed perimeter.

from __future__ import print_function, division
from visual import *

#-----------------------------------------------------------------------------------
# define a "board" using arcs and lines as a closed contour
# this board should be extruded e.g. with a thickness od 20 mm (see var. straight)
#-----------------------------------------------------------------------------------
        
scene.title = "mySHAPE"
scene.height = 1000
scene.width = 1500
scene.range = 600

scene.center = (500, 250, 10)

# workpiece must have thickness of 20 mm
straight = [(0,0,0),(0,0,-20)] # extrude in -z direction

# In the xz plane, create the straight lines:
p = [(500,0,250), (500,0,500), (0,0,500),
     (0,0,0), (1000,0,0), (1000,0,400)]

# In the xz plane, create the arcs:
a1 = paths.arc(pos=(900,0,400), radius=100, angle1=0, angle2=-pi/2)
a2 = paths.arc(pos=(900,0,300), radius=200, angle1=-pi/2, angle2=-pi)
a3 = paths.arc(pos=(600,0,250), radius=100, angle1=0, angle2=pi)
p.extend(a1.pos)
p.extend(a2.pos)
p.extend(a3.pos)

# Convert to a list of (x,y) positions:
s = []
for q in p:
    s.append((q[0],q[2]))

# Create a Polygon object:
poly = Polygon(s)

myExt_Arc = extrusion(pos=straight, shape=poly, color=color.yellow)

Ottmar Petry

unread,
Feb 21, 2013, 5:13:32 PM2/21/13
to vpytho...@googlegroups.com
Hi.

Thanks again for your help and the last proposal.
Its very difficult to understand this way of programming when you are used to programm
in languages like BASIC, SIMULA, PASCAL, C(++).

Your code is quite compact but for me to understand I have the following questions:

1) why do I have to define a polyline in XZ, if at the end I want to use it in XY ?

2) what does the definition mean if I start with   p = [(500,0,250),...
    Does it define a point at that position or a line TO this position (from where starting ?) ?
    what type does this set of 3D-coordinates have ?  How can I know what the type is if I only write  p = [...] ?

3) OK, then after p = [(500,0,250),...] I have defined some lines 

4) then I define some individual arcs, like   a1 = paths.arc(pos=(900,0,400), radius=100, angle1=0, angle2=-pi/2)
    but why also in XZ ?

5) now I have some lines and some arcs

6) what type has object  p  ?  Lines I think ??!!
    and then I  "extend" some arcs  with    p.extend(a1.pos)
    But why do I use   a1.pos  and not  only a1 ??    
    What is the difference between  p.extend(a1)  and   p.extend(a1.pos)  ?
    How could I come to the idea to  extend  a1.pos and not a1 ?  (I want to add the arc !)

7) you here first defined all lines and then all arcs
    Can I also define the objects in the order in which I get these objects from my input ?
    That is a consecutive order maybe  line, line, arc, arc, line, arc, line, line 
    
8) then I convert my XZ-data to XY - OK, I can understand how this is done - but why was XZ necessary ?

9) is there no alternative way straight defining my lines and arc as they appear in the input-order as
    extrudable contour and in XY ?

    e.g. something like

    p = [(500,0,250)]
    a1 = paths.arc(pos=(900,0,400), radius=100, angle1=0, angle2=-pi/2)
    p.extend(a1.pos)
    p.extend(<<<another line-definition - but how >>>)
    a2 = paths.arc(pos=(xxx,0,zzz), radius=100, angle1=0, angle2=-pi/2)
    p.extend(a2.pos)
    p.extend(<<<another line-definition - but how >>>)
    p.extend(<<<another line-definition - but how >>>)
    p.extend(<<<another line-definition - but how >>>)
    a3 = paths.arc(pos=(xxx,0,zzz), radius=100, angle1=0, angle2=-pi/2)
    p.extend(a3.pos)
    ...

   if such a definition leads to a closed XZ-contour that could be converted to XY and then extruded
   then it would be a possible solution ... ?


For me as a beginner in (V)Python its difficult to understand the philosophie in the background that results in
the need to define the contour in XZ seperated by lines and arcs and then by converting it to XY
as base for the possible extrusion.   This is quite strange to understand and accept.
I get dynamic data of outer-contour-elements (arcs and lines) as input and I have to handle 
these objects in that order that means if the next object is a line I want to do something with
that line, if its an arc I want to handle that arc at that time and so on.

Maybe its easier for me to define a XY-contour based on lines and internally convert the arcs to
a set of lines. Then I only have lines as elements for the outer-contour and then I think there
exist a possibility to define these lines (closed contour) to be extrudable.

Thanks very much for your help.

I hope that I can understand more from the background and then find a way to implement my idea with (V)Python.

Best regards
Ottmar

Bruce Sherwood

unread,
Feb 21, 2013, 6:03:13 PM2/21/13
to vpytho...@googlegroups.com
1) why do I have to define a polyline in XZ, if at the end I want to use it in XY ?
>>> Because the paths library generates lists of 3D points in the xz plane, for its typical use as a path for an extrusion, just as the shapes library generates a list of 2D points in the xy plane, ready to extrude along a path in the xz plane. (Of course you can orient an extrusion in a different way, but you have been using a path in the -z direction, and shapes in the xy plane.) It's a bit unusual to use the 3D paths library to generate a 2D shape, but the paths library provides primitives such as arc that are apparently appropriate for your input data.

2) what does the definition mean if I start with   p = [(500,0,250),...
    Does it define a point at that position or a line TO this position (from where starting ?) ?
    what type does this set of 3D-coordinates have ?  How can I know what the type is if I only write  p = [...] ?
>>> I've used p to collect a list of 3D points in the xz plane, some of them written explicitly, such as (500,0,250), some of them created by paths.arc. After completing the list of 3D points in the xz plane, I do a tiny bit of processing (in the for loop) to create a list of 2D points in the xy plane, consistent with representing a 2D shape to be extruded along a line perpendicular to that shape, namely your "straight" that goes in the -z direction. As for what "type" (500,0,250) is, it is a Python "tuple", a set of values that are "immutable" in the sense that you can read individual elements of a tuple but you can't change an individual element. This is different from a "list" such as [500,0,250] in which the elements are read/write. The extrusion object will accept tuples, lists, or VPython vector objects; you can use any of these.

>>> The 2D points such as (500,250) are relative to the pos attribute of your extrusion, which in your case is at (0,0).

3) OK, then after p = [(500,0,250),...] I have defined some lines 

4) then I define some individual arcs, like   a1 = paths.arc(pos=(900,0,400), radius=100, angle1=0, angle2=-pi/2)
    but why also in XZ ?
>>> Because that's what the paths library gives you. As discussed in the rectangle section of the paths library, print(a1.pos) gives you not (900,0,400) but a list of 3D vectors.

5) now I have some lines and some arcs

6) what type has object  p  ?  Lines I think ??!!
    and then I  "extend" some arcs  with    p.extend(a1.pos)
    But why do I use   a1.pos  and not  only a1 ??    
    What is the difference between  p.extend(a1)  and   p.extend(a1.pos)  ?
    How could I come to the idea to  extend  a1.pos and not a1 ?  (I want to add the arc !)
>>> p is a Python list of 3D points, and s is a list of 2D points. a1 is a paths.arc object; a1.pos is a list of 3D vectors, and a1.radius, a1.angle1, and a1.angle2 are all numbers. a1.pos is just one attribute of the paths.arc object, and it is the attribute we want for creating a contour.

7) you here first defined all lines and then all arcs
    Can I also define the objects in the order in which I get these objects from my input ?
    That is a consecutive order maybe  line, line, arc, arc, line, arc, line, line 
>>> You have to order your input in such a way that you accumulate into the p list points that follow each other around the contour. So no, you can't just start the list of points with a line along the left edge of the board, then add points along the right edge, then add an arc in the central region. Try changing the order of adding points to p and you'll see that you get nonsense. You need to create a 2D "contour" as an ordered list of 2D points going around the outer edge of the object.

>>> On the other hand, if your contour consists in order of line, line, arc, arc, line, arc, line, line, that's not a problem. In your particular example the three arcs follow each other, so their points are added to p one after the other. 
    
8) then I convert my XZ-data to XY - OK, I can understand how this is done - but why was XZ necessary ?
>>> Again, because what the paths library gives you is a set of points in the xz plane, more suitable for 3D paths than for 2D shapes.

9) is there no alternative way straight defining my lines and arc as they appear in the input-order as extrudable contour and in XY ?

    e.g. something like

    p = [(500,0,250)]
    a1 = paths.arc(pos=(900,0,400), radius=100, angle1=0, angle2=-pi/2)
    p.extend(a1.pos)
    p.extend(<<<another line-definition - but how >>>)
    a2 = paths.arc(pos=(xxx,0,zzz), radius=100, angle1=0, angle2=-pi/2)
    p.extend(a2.pos)
    p.extend(<<<another line-definition - but how >>>)
    p.extend(<<<another line-definition - but how >>>)
    p.extend(<<<another line-definition - but how >>>)
    a3 = paths.arc(pos=(xxx,0,zzz), radius=100, angle1=0, angle2=-pi/2)
    p.extend(a3.pos)
    ...

   if such a definition leads to a closed XZ-contour that could be converted to XY and then extruded
   then it would be a possible solution ... ?
>>> After extending p with an arc, you can certainly extend p with a line:
p.extend([(x1,0,z1), (x2,0,z2)])

For me as a beginner in (V)Python its difficult to understand the philosophie in the background that results in the need to define the contour in XZ seperated by lines and arcs and then by converting it to XY as base for the possible extrusion.   This is quite strange to understand and accept. I get dynamic data of outer-contour-elements (arcs and lines) as input and I have to handle these objects in that order that means if the next object is a line I want to do something with that line, if its an arc I want to handle that arc at that time and so on.

Maybe its easier for me to define a XY-contour based on lines and internally convert the arcs to
a set of lines. Then I only have lines as elements for the outer-contour and then I think there
exist a possibility to define these lines (closed contour) to be extrudable.

>>> I hope I've explained that the 2D/3D issue is simply because the paths library is for making paths, which are 3D things (could be a helical path, for example, with some 2D shape as the cross section). It's not anything particular to Python or VPython. Rather it's particular to what the paths library provides.

Bruce Sherwood

unread,
Feb 21, 2013, 6:10:47 PM2/21/13
to vpytho...@googlegroups.com
Minor correction. I said "After extending p with an arc, you can certainly extend p with a line: p.extend([(x1,0,z1), (x2,0,z2)])".

In fact it's simpler than that. The arc will have ended at the point (x1,0,z1) where the line starts, so there's no need to duplicate that point. Just say p.extend( [(x2,0,z2)] ).

The following simpler statement will also work: p.append( (x2,0,z2) ).

Ottmar Petry

unread,
Feb 22, 2013, 2:09:29 AM2/22/13
to vpytho...@googlegroups.com
Hello Bruce.

I am very thankful for your help. Thanks very much.
Now I understand the background and the differences of paths and shapes as they are now, how they
can be used in my case.

1) Is there any literature where those things like paths/shapes their functions, possibilities to convert from paths to shapes ..
is documented

2) it would be easier if the shapes library would directly allow to define an arc then doing something that I want to do
would be much more straight forward. Would i make sense to extend the shapes library with an arc-function ?
Who developed this shapes library - who could extend it (if it would make sense ?)  ?

3) at the moment I have to ask a lot because at the moment I do not have enough documentation that I can use.
E.g. concerning your last lines offering 3 possibilities:

a) p.extend([(x1,0,z1), (x2,0,z2)])
b) p.extend( [(x2,0,z2)] )
c) p.append( (x2,0,z2) )

my questions: what is the difference between extend and append - append I think is always at the end but extend
is an extension, but where - at what position (insert at a certain position ? where ?)  ?

E.g. concerning this question: where can I find material around these things:
- which functions exist that I can use e.g. concerning a paths variable  p ?
- what does these functions do ?

Maybe I did not yet find these documentation.
For me its also OK to read some header-files if they contain these information.

Again thank you very much.

Have a nice weekend and best regards
Ottmar




Ottmar Petry

unread,
Feb 22, 2013, 10:59:59 AM2/22/13
to vpytho...@googlegroups.com
Another question: is it possible to define that an extrusion has no "filling" color
that means that it is transparent, maybe only showing the outer-border, so that
e.g. if I place a tube inside that such a tube is visible

something like 

color = color.transparent  or
color = color.FrameOnly

??

Thanks
Ottmar


On Wednesday, February 20, 2013 9:07:47 AM UTC+1, Ottmar Petry wrote:

Bruce Sherwood

unread,
Feb 22, 2013, 4:52:10 PM2/22/13
to vpytho...@googlegroups.com
1) All of the documentation is present in the Help, and that's the only documentation there is. As a C++ programmer you expect to find it useful to read header files to learn what attributes and methods are available for classes. The equivalent information is in the Help descriptions of the extrusion, paths, and shapes objects. See point 3 below.

2) There already is a shapes.arc, but it's just an outline, not a filled in object. The appropriate way to improve the shapes library would be to be able to specify angle1 and angle2 for the circle and ellipse objects. The shapes.py and paths.py libraries were built mainly by Kadir Haldenbilen, but this is open source, and anyone can contribute changes they've made. However, this would be of no use to you, because as you've explained your input data are in the form of paths, not shapes, and having a shape that is "pie-shaped" wouldn't help you. 

It would be possible to make it a little easier to use the paths library to create a Polygon, but it wouldn't be much easier than the scheme I already showed you (and which I will document in the extrusion documentation), namely to use the paths library to create a list of 3D xyz points, then convert to 2D xy points (requiring 3 simple statements), then give this list of 2D points to the Polygon object (1 simple statement). We may be able to eliminate these 4 statements, but we won't be able to eliminate your need to choose paths and combine them using the Python list methods extend and/or append.

3) The problem with understanding extend and append is that these are not VPython functions. They are methods of Python list objects. As a newcomer to Python and VPython, but a newcomer who is trying to use by far the most complex of all the VPython objects, extrusions, you've been caught by the problem of how you would know whether "extend" is some VPython object that isn't documented in the VPython Help or whether it is some piece of Python syntax. See any Python documentation for the meaning of append (add one more object to the end of an existing list) and of extend (add a list of objects to the end of an existing list).

Many years ago at the start of VPython (in 2000), we decided to use lower-case names for simplicity, and with "from visual import *" to make it very easy for novice programmers (which you are not) to have everything they need to get started. In fact, numerically by far most users of VPython are first-year university students who have never written a program before, in any language, and they are using VPython to model physical systems. They use a very tiny subset of Python's very rich capabilities.

You on the other hand, as an experienced programmer, might wish to study the section on the first page of the VPython Help, the section titled "For experienced programmers". If your program started with "import vis" and instead of "extrusion" you said "vis.extrusion" it would be more clear to you that "extend" is a Python function, not a VPython entity.

4) From the documentation on extrusion: "Currently it is not possible to specify the opacity of an extrusion object." More generally, from the Help on color/opacity, "Currently curve, convex, faces, points, and helix objects do not allow transparency." Currently VPython does most of the OpenGL 3D rendering in the CPU, but in my work on GlowScript (glowscript.org) I do the rendering in GPUs. I hope to import GPU rendering to VPython, which would among other things make it possible to do true transparency at the pixel level, as I do in GlowScript. The transparency machinery in VPython, is necessarily at the object level, not the pixel level, which means among other things that intersecting transparent objects are not rendered correctly. To see an example of pixel-level transparency being handled correctly, see this (you need a modern graphics card with GPUs and a WebGL-enabled browser such as Chrome):


However, maybe all you're looking for is to render the outer perimeter of the object, in which case it's easy to do. The program I posted that uses paths ends with these two statements:

poly = Polygon(s)
myExt_Arc = extrusion(pos=straight, shape=poly, color=color.yellow)

If in the second statement you say "shape=s", thereby giving just a list of points rather than a Polygon object, you'll see that the extrusion is completely hollow.

Bruce Sherwood

unread,
Feb 22, 2013, 10:09:56 PM2/22/13
to vpytho...@googlegroups.com
A colleague points to me that list addition can be used instead of the essentially equivalent list method "extend".

a = [1, 2, 3]
b = [10, 20, 30]
print(a+b)
print(a.extend(b))

Both of these print statements produce [1, 2, 3, 10, 20, 30]. "a+b" creates a new list, whereas "a.extend(b)" extends list "a".

The portion of my posted program that generates the list of points along the contour can be written like this:

# In the xz plane, create the straight lines:
p = [(500,0,250), (500,0,500), (0,0,500),
     (0,0,0), (1000,0,0), (1000,0,400)]

# In the xz plane, create the arcs:
a1 = paths.arc(pos=(900,0,400), radius=100, angle1=0, angle2=-pi/2)
a2 = paths.arc(pos=(900,0,300), radius=200, angle1=-pi/2, angle2=-pi)
a3 = paths.arc(pos=(600,0,250), radius=100, angle1=0, angle2=pi)
p += a1.pos # add the a1 points to p
p += a2.pos # add the a2 points to p
p += a3.pos # add the a3 points to p

Bruce Sherwood

unread,
Feb 23, 2013, 6:05:10 PM2/23/13
to vpytho...@googlegroups.com
Here is a more principled version of the program that uses the paths library to create the Polygon object. The key point is that in the paths library an arc starts out (in the xz plane) headed in the -z direction. Looking down from above the xz plane (along the +y axis), an arc goes counterclockwise, starting from the +x axis. So in this version of the program the 3D xyz path is laid out in the -z portion of the xz plane, and these 3D points are then (in the "for" loop) converted to 2D points with x -> x and -z -> y.

I'll mention that for the next release of VPython 6 I've added this scheme for using the paths library to the documentation of the extrusion object, and I've revised shapes.circle and shapes.ellipse to accept angle1 and angle2 arguments in order to specify partial circles and ellipses as shape objects.

from __future__ import print_function, division
from visual import *

#-----------------------------------------------------------------------------------
# define a "board" using arcs and lines as a closed contour
# this board should be extruded e.g. with a thickness of 20 mm (see var. straight)
#-----------------------------------------------------------------------------------
        
scene.title = "mySHAPE"
scene.height = 1000
scene.width = 1500
scene.range = 600

scene.center = (500, 250, 10)

# workpiece must have thickness of 20 mm
straight = [(0,0,0),(0,0,-20)] # extrude in -z direction

# In the xz plane, create the straight lines.
# To be consistent with the paths library, whose
# paths start in the -z direction, lay out the
# contour in such a way that -z will be converted
# later to +y:
p = [(500,0,-250), (500,0,-500), (0,0,-500),
     (0,0,0), (1000,0,0), (1000,0,-400)]

# In the xz plane, create the arcs:
a1 = paths.arc(pos=(900,0,-400), radius=100, angle1=0, angle2=pi/2)
a2 = paths.arc(pos=(900,0,-300), radius=200, angle1=pi/2, angle2=pi)
a3 = paths.arc(pos=(600,0,-250), radius=100, angle1=0, angle2=-pi)
p += a1.pos
p += a2.pos
p += a3.pos

# Convert to a list of (x,y) positions, where -z -> y:
s = []
for q in p:
    s.append((q[0],-q[2]))

# Create a Polygon object:

Ottmar Petry

unread,
Mar 13, 2013, 12:08:39 PM3/13/13
to vpytho...@googlegroups.com


On Wednesday, February 20, 2013 9:07:47 AM UTC+1, Ottmar Petry wrote:

Ottmar Petry

unread,
Mar 13, 2013, 12:17:44 PM3/13/13
to vpytho...@googlegroups.com
Hello.

I am looking for a rule how arc can be defined.
When I want to use the following notation then I don´t know I can distinguish
between arcs running counter-clockwise (CCW) and those clockwise (CW).
How does the arc-function detect that it is CW or CCW ?

If I define a continuous path using a sequence of those  paths.arc-commands
then I suppose that the last end-point always is the next start-point
but then there are several possibilities for arcs if I only define

- the centre-point using  pos=(...) 
- radius
- start-angle angle1 and
- end-angle angle2

I generate sequences like

a1 = paths.arc(pos=(987.00,0,457.70), radius=13.09, angle1=-4.11, angle2=-3.14)
p.extend(a1.pos)
a1 = paths.arc(pos=(987.00,0,457.70), radius=13.10, angle1=-3.14, angle2=-1.57)
p.extend(a1.pos)
...

but I cannot find a rule how to handle the angle-values (sign ??) how to reach that
arcs go CCW or CW ?

Can someone help me ?
Is there any description on how to use the parameters of arc(...) ?

Thanks in advance
Ottmar



On Wednesday, February 20, 2013 9:07:47 AM UTC+1, Ottmar Petry wrote:

Bruce Sherwood

unread,
Mar 13, 2013, 1:29:32 PM3/13/13
to vpytho...@googlegroups.com
The paths.arc function calls the shapes.arc function in visual_common/shapes.py. Here is the key part of that function:

        cp = []  # outer arc
        cpi = [] # inner arc
        seg = 2.0*pi/np
        nseg = int(abs((angle2-angle1))/seg)+1
        seg = (angle2-angle1)/nseg
        for i in range(nseg+1):
            x = cos(angle1+i*seg)
            y = sin(angle1+i*seg)
            cp.append( (radius*x+pos[0],radius*y+pos[1]) )
            cpi.append( ((radius-thickness)*x+pos[0],(radius-thickness)*y+pos[1]) )

Starting at angle1, calculate a position. For each iteration in the for loop, add a small angle (seg) which is (angle2-angle1)/(the number of segments in the arc). If seg is positive, this generates a CCW arc starting at angle1, as viewed from above the xz plane. If seg is negative, this generates a CW arc.

One way to keep things straight is to always make (angle2-angle1) be a positive quantity, in which case the arc will go CCW starting from angle1.


--
You received this message because you are subscribed to the Google Groups "VPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vpython-user...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Reply all
Reply to author
Forward
0 new messages