## stick man manniquin

User projects written in or related to FreeBASIC.
BasicCoder2
Posts: 3598
Joined: Jan 01, 2009 7:03
Location: Australia

### stick man manniquin

This is my stick man rigging demo.
You can select a joint by clicking on it with the mouse.
Unfortunately some joints exist at the same x,y location and the mouse can only pick one.
To compensate for this problem you can tap the space bar to move through the joints.
You can then use the left/right cursor keys to rotate the joints.

Code: Select all

`'some useful definesConst Pi = 4 * Atn(1)Dim Shared As Double TwoPi = 8 * Atn(1)Dim Shared As Double RtoD = 180 / Pi   ' radians * RtoD = degreesDim Shared As Double DtoR = Pi / 180   ' degrees * DtoR = radiansscreenres 640,480,32'color rgb(0,0,0),rgb(255,255,255):clsdim shared as integer selected   'selected bone numbertype BONE    as integer r       'reset start angle    as integer p       'pointer to previous bone    as integer x1      'absolute start    as integer y1    as integer x2      'end  point    as integer y2    as single  a       'angle of joint    as single  aMin    'limits of joint movement    as single  aMax    as single  s       'size    as ulong   c       'colorend typedim shared as BONE bones(0 to 13)'=================== LEG 1 ================bones(0).x2 = 320   'start pointbones(0).y2 = 240bones(1).r = 1bones(1).a = 81bones(2).a = 53bones(3).a = 239bones(1).s = 100bones(2).s = 100bones(3).s = 30bones(1).c = rgb(255,0,0)bones(2).c = rgb(255,0,0)bones(3).c = rgb(255,0,0)bones(1).p = 0bones(2).p = 1bones(3).p = 2'==================== LEG 2 =====================bones(4).r = 1bones(4).a = 59bones(5).a = 53bones(6).a = 239bones(4).s = 100bones(5).s = 100bones(6).s = 30bones(4).c = rgb(0,255,0)bones(5).c = rgb(0,255,0)bones(6).c = rgb(0,255,0)bones(4).p = 0bones(5).p = 4bones(6).p = 5'===================== TORSO ========================bones(7).r = 1bones(7).a = 270bones(7).s = 100bones(7).c = rgb(0,0,255)bones(7).p = 0'===================== ARM 1 =========================bones(8).r = 1bones(8).a = 81bones(9).a = 294bones(10).a = 315bones(8).s = 80bones(9).s = 70bones(10).s = 30bones(8).c = rgb(0,255,255)bones(9).c = rgb(0,255,255)bones(10).c = rgb(0,255,255)bones(8).p = 7bones(9).p = 8bones(10).p = 9'===================== ARM 2 =========================bones(11).r = 1bones(11).a = 114bones(12).a = 343bones(13).a = 239bones(11).s = 80bones(12).s = 70bones(13).s = 30bones(11).c = rgb(155,155,0)bones(12).c = rgb(155,155,0)bones(13).c = rgb(155,155,0)bones(11).p = 7bones(12).p = 11bones(13).p = 12dim shared as single anglesub drawBones()    screenlock    cls    angle = 0    locate 2,1    for i as integer = 1 to 13        color bones(i).c        if bones(i).r = 1 then angle = 0:print        if bones(i).a < 0   then bones(i).a = bones(i).a + 360        if bones(i).a > 359 then bones(i).a = bones(i).a - 360        angle = angle + bones(i).a        if angle < 0   then angle = angle + 360        if angle > 359 then angle = angle - 360        bones(i).x1 = bones( bones(i).p ).x2        bones(i).y1 = bones( bones(i).p ).y2        bones(i).x2 = bones(i).x1 + cos(angle*DtoR) * bones(i).s        bones(i).y2 = bones(i).y1 + sin(angle*DtoR) * bones(i).s          line (bones(i).x1,bones(i).y1)-(bones(i).x2,bones(i).y2),bones(i).c        circle (bones(i).x1,bones(i).y1),3,rgb(200,200,200)        if selected = i then            circle (bones(i).x1,bones(i).y1),5            draw string (bones(i).x1+8,bones(i).y1), str(selected)        end if        print i;" ";bones(i).a,angle    next i    screenunlockend subdim as string keydim as integer mx,my,mbdrawBones()dim as single dd,dx,dydo        getmouse mx,my,,mb        if mb = 1 then            for i as integer = 0 to 13                dx = mx-bones(i).x1                dy = my-bones(i).y1                dd = sqr(dx^2+dy^2)                if dd < 5 then                    selected = i                end if            next i        end if                key = inkey        If key=Chr(255) +"K" Then bones(selected).a = bones(selected).a - 1        If key=Chr(255) +"M" Then bones(selected).a = bones(selected).a + 1        if key = " " then selected = selected + 1        if selected = 14 then selected = 1        drawBones()        sleep 2loop until  multikey(&H01) sleep`

If the joints could be positioned in a 3D volume instead of being restricted to 2D surface with the ability to rotate them around the center of the figure you could probably use the mouse to select all the joints.

It might look something like this.

Code: Select all

`'some useful definesConst Pi = 4 * Atn(1)Dim Shared As Double TwoPi = 8 * Atn(1)Dim Shared As Double RtoD = 180 / Pi   ' radians * RtoD = degreesDim Shared As Double DtoR = Pi / 180   ' degrees * DtoR = radiansscreenres 940,480,32sub setXYZ(x as double,y as double,z as double)    circle (x+z\2,y-z\2),3,rgb(0,255,0)    'draw string (x+z\2,y-z\2),str(int(x+.5))+","+str(int(y+.5))+","+str(int(z+.5))end subsub lineXYZ(x1 as double,y1 as double,z1 as double,x2 as double,y2 as double,z2 as double)    line (x1+z1\2,y1-z1\2)-(x2+z2\2,y2-z2\2),rgb(255,0,0)    setXYZ(x1,y1,z1)    setXYZ(x2,y2,z2)end subtype ALINE    as integer x1    as integer y1    as integer z1    as integer x2    as integer y2    as integer z2end typedim shared as ALINE lines(1 to 15)dim shared as integer x1,y1,z1,x2,y2,z2for i as integer = 1 to 15   'draw 15 lines    read lines(i).x1,lines(i).y1,lines(i).z1,lines(i).x2,lines(i).y2,lines(i).z2    lineXYZ(x1,y1,z1,x2,y2,z2)next isub drawLines()    screenlock    cls    for i as integer = 1 to 15   'draw 15 lines        lineXYZ(lines(i).x1,lines(i).y1,lines(i).z1,lines(i).x2,lines(i).y2,lines(i).z2)    next i    screenunlockend subsub rotatePointsY()    dim as double px1,py1,pz1,px2,py2,pz2,rx1,ry1,rz1,rx2,ry2,rz2    for angle as double = 0 to 360        cls        for i as integer = 1 to 15  '15 lines            pz1 = lines(i).z1 - 50            px1 = lines(i).x1 - 350            py1 = lines(i).y1 - 350             rz1 = (Cos(angle*DtoR) * pz1 - Sin(angle*DtoR) * px1)+50            rx1 = (Sin(angle*DtoR) * pz1 + Cos(angle*DtoR) * px1)+350            ry1 = py1+340            pz2 = lines(i).z2 - 50            px2 = lines(i).x2 - 350            py2 = lines(i).y2 - 350             rz2 = (Cos(angle*DtoR) * pz2 - Sin(angle*DtoR) * px2)+50            rx2 = (Sin(angle*DtoR) * pz2 + Cos(angle*DtoR) * px2)+350            ry2 = py2+340            LINEXYZ(rx1,ry1,rz1,rx2,ry2,rz2)        next i        sleep 50    next angleend subrotatePointsY()'drawLines()sleepdata 321,140,-20,321,140,+20  'shoulderdata 321,140,-20,288,213,-20  'left arm topdata 288,213,-20,280,280,-20  'lowerdata 280,280,-20,306,270,-20  'wristdata 321,140,+20, 334,218,+20 'right armdata 334,218,+20, 402,237,+20data 402,237,+20, 428,222,+20data 322,239,-20, 322,239,+20 'hipdata 322,239,-20, 338,338,-20  'left legdata 338,338,-20, 268,411,-20data 268,411,-20, 297,419,-20data 322,239,+20, 373,326,+20data 373,326,+20, 337,419,+20data 337,419,+20, 367,414,+20data 321,140,0, 322,239,0    'torso`
leopardpm
Posts: 1795
Joined: Feb 28, 2009 20:58

### Re: stick man manniquin

LOL! luv it... nice little demo
Pitto
Posts: 119
Joined: Nov 19, 2012 19:58

### Re: stick man manniquin

Hi BasicCoder2,

well done demo. I like it.

I think that, adding the possibility to record each node position along a timeline, an interesting animation could be created.
Looks like a technique used a long time ago to render graphics in a videogame of the early 90's called "another World": https://www.anotherworld.fr/anotherworld_uk/page_realisation.htm
It would be nice to be able to manage some connected polygons with each other in a hierarchical way.
Maybe I went a bit 'off topic :)
BasicCoder2
Posts: 3598
Joined: Jan 01, 2009 7:03
Location: Australia

### Re: stick man manniquin

Pitto wrote:Hi BasicCoder2,
well done demo. I like it.

Thanks for the feedback.

May I say that I admired your programming of a soccer game something I wasn't able to complete.

I think that, adding the possibility to record each node position along a timeline, an interesting animation could be created.

That was the idea. You move the bones and save the the positions. Later you can play back the positions and have an animation as they do in the 3D Blender software. Elsewhere I have covered the bones with a polygon so for example the torso would be one line (the backbone) but it would orientate a square polygon (or any shape polygon for that matter). I did this somewhere in a robot arm demo. It all takes time to write and debug this stuff and for that you need motivation. It is really only reinventing what professionals have already done better. My weakness is not having a grasp of 3D math.

It would be nice to be able to manage some connected polygons with each other in a hierarchical way.
Maybe I went a bit 'off topic :)

The only reason for keeping on topic is when searching for a subject. There is some good stuff in the squares thread but unless you happen to hit on the right key words in the search facility you will not find them. None of this stuff is going anywhere in a commercial sense. It is all just playing about with code as someone might play around with a puzzle game.

It is easy enough to make many polygons and they will stay together over rotation and magnification. I have messed with that somewhere but it all 2D stuff.

Here is the logic used in the polygon drawing mode in one of my vector paint programs.

You draw a polygon with the mouse. Move the mouse while holding down the left button and a line will be drawn between the start point and the current point. Repeat and the lines will all join. End it by ending a line at the start point. A dotted rectangle will then enclose the polygon. By holding the button down within that rectangle you can move the polygon where ever you like. Click outside the rectangle to end it. The polygons are saved in an array and in other code examples you could step through the polygons to delete or edit them later.

Code: Select all

`const wCanvas = 640const hCanvas = 480const SCRW = 840const SCRH = 552const POSX = 180const POSY = 60screenres SCRW,SCRH,32color rgb(1,1,1),rgb(254,254,254)  'black ink, white papercls 'executes color statement settingsdim shared as integer mx,my,mb,ox,oy,sx,sy,x1,y1,x2,y2,dx,dydim shared as any ptr canvas3,canvas2,canvas1canvas3 = imagecreate(wCanvas,hCanvas,rgb(255,  0,255)) 'current shape drawn herecanvas2 = imagecreate(wCanvas,hCanvas,rgb(255,254,255)) 'save current picturecanvas1 = imageCreate(wCanvas,hCanvas,rgb(255,254,255)) 'current screen to displaytype SHAPE    as integer  x(100)  'absolute coordinates of points on screen    as integer  y(100)    as integer  size    'number of coordinates    as uinteger c1      'boundary color    as uinteger c2      'fill colorend typedim shared as SHAPE shapes(100)  'up to 100 shapesdim shared as integer sCount     'actual number of shapes'==============================================='DRAWS CURRENT LINES FOR SHAPE USED BY getShape()'===============================================sub drawShape(s as SHAPE)    line canvas3,(0,0)-(wCanvas-1,hCanvas-1),rgb(255,0,255),bf  'clear drawing buffer    if s.size<>0 then        for i as integer = 0 to s.size-2            line canvas3,(s.x(i),s.y(i))-(s.x(i+1),s.y(i+1)),rgb(0,0,0)        next i    end ifend subsub update()    screenlock()    cls    'draw shapes    'copy to display    put (POSX,POSY),canvas1,pset    'draw screen box    line (POSX-2,POSY-2)-(POSX+wCanvas+2,POSY+hCanvas+2),rgb(1,1,1),b    line (POSX-4,POSY-4)-(POSX+wCanvas+4,POSY+hCanvas+4),rgb(1,1,1),b    locate 1,1    print "NUMBER OF SHAPES: ";sCount    screenunlock()end sub'=================================================='ALLOWS USER TO DRAW A SHAPE OUT OF CONNECTED LINES'EXITS SHAPE DRAWING WHEN START OF FIRST LINE IS'CONNECTED BY END OF LAST LINE. IT THEN ALLOW THE'USER TO MOVE AND RESIZE THE SHAPE.'==================================================function getShape() as SHAPE    dim s as SHAPE    s.c1 = rgb(0,0,0)    s.c2 = rgb(200,200,200)        s.size = 0  'clear list        'get first coordinate        'save current screen    get (POSX,POSY)-(POSX+wCanvas-1,POSY+hCanvas-1),canvas2    'clear canvas3 with magenta    line canvas3,(0,0)-(wCanvas-1,hCanvas-1),rgb(255,0,255),bf    sx = mx    sy = my    s.x(s.size)=mx-POSX  'save first coordinate    s.y(s.size)=my-POSY    s.size = s.size + 1    'get next coordinate    do        'wait for button down        getmouse mx,my,,mb        while mb<>1            getmouse mx,my,,mb        wend        ox = mx        oy = my        line canvas3,(sx-POSX,sy-POSY)-(mx-POSX,my-POSY),s.c1 'draw current line being drawn        'erase current screen drawing with previous saved screen        put canvas1,(0,0),canvas2,pset        'copy latest drawing stage onto display canvas        put canvas1,(0,0),canvas3,trans        update()        do            getmouse mx,my,,mb            if mx<>ox or my<>oy then 'it has moved                drawShape(s)                line canvas3,(sx-POSX,sy-POSY)-(mx-POSX,my-POSY),s.c1 'draw current line being drawn                'erase current screen drawing with previous saved screen                put canvas1,(0,0),canvas2,pset                'copy latest drawing stage onto screen                put canvas1,(0,0),canvas3,trans                update()                ox = mx                oy = my            end if            sleep 1        loop until mb<>1                'save next coordinate        s.x(s.size)=mx-POSX        s.y(s.size)=my-POSY        s.size = s.size + 1        sx = mx  'start of next line        sy = my                'loop until close to start    loop until sx-POSX>s.x(0)-3 and sx-POSX<s.x(0)+3 and sy-POSY>s.y(0)-3 and sy-POSY<s.y(0)+3    s.x(s.size-1)=s.x(0)  'make last coordinate start coordinate    s.y(s.size-1)=s.y(0)    'find dimensions of box around shape    dim as integer x1,x2,y1,y2     x1 = 1000    y1 = 1000    x2 = 0    y2 = 0    'get dimensions of box around shape    for i as integer = 0 to s.size-1        if s.x(i)<x1 then x1 = s.x(i)        if s.x(i)>x2 then x2 = s.x(i)        if s.y(i)<y1 then y1 = s.y(i)        if s.y(i)>y2 then y2 = s.y(i)    next i    drawShape(s)    'draw dotted box around shape    line canvas3,(x1,y1)-(x2,y2),rgb(1,1,1),b,&b1111000011110000    'draw resize tag on bottom/right corner of box    line canvas3,(x2,y2)-(x2+5,y2+5),rgb(1,1,1),b    'erase current screen drawing with previous saved screen    put canvas1,(0,0),canvas2,pset    'copy latest drawing stage onto screen    put canvas1,(0,0),canvas3,trans    update()'================================================================='  MOVES OR RESIZES SHAPE UNTIL BUTTON DOWN ELSEWHERE'=================================================================    dim as integer dx,dy    do        getmouse mx,my,,mb            ox = mx            oy = my                'MOVE SHAPE WHILE BUTTON DOWN INSIDE BOX        if mb=1 and mx>x1+POSX and mx<x2+POSX and my>y1+POSY and my<y2+POSY then  'inside box            while mb=1  'while button held down                getmouse mx,my,,mb                if mx<>ox or my<>oy then 'mouse has moved                    dx = mx-ox                    dy = my-oy   'amount it has moved                                    'update coordinates positions                    for i as integer = 0 to s.size-1                        s.x(i)=s.x(i)+dx                        s.y(i)=s.y(i)+dy                    next i                                        x1 = x1 + dx                    x2 = x2 + dx                    y1 = y1 + dy                    y2 = y2 + dy                                    drawShape(s)                    line canvas3,(x1,y1)-(x2,y2),rgb(1,1,1),b,&b1111000011110000                    line canvas3,(x2,y2)-(x2+6,y2+6),rgb(1,1,1),b                    'erase current screen drawing with previous saved screen                    put canvas1,(0,0),canvas2,pset                    'copy latest drawing stage onto screen                    put canvas1,(0,0),canvas3,trans                    update()                    'line canvas3,(x1,y1)-(x2,y2),rgb(1,1,1),b,&b1111000011110000                    'line canvas3,(x2,y2)-(x2+5,y2+5),rgb(1,1,1),b                      ox = mx                    oy = my                end if            wend        end if        'RESIZE SHAPE WHILE BUTTON DOWN WITHIN TAG AREA        dim as double LX,LY,r1,r2        if mb=1 and mx>x2+POSX and my>y2+POSY and mx<x2+6+POSX and my<y2+6+POSY then        'if mb=1 and mx>x2-5 and my>y2-5 and mx<x2+5 and my<y2+5 then            while mb=1                getmouse mx,my,,mb                if mx<>ox or my<>oy then  'mouse has moved                    dx = mx-ox                    dy = my-oy   'amount it has moved                    LX = (x2 + dx)-x1  'new width and height of box                    LY = (y2 + dy)-y1                    for i as integer = 0 to s.size-1                        r1 = (s.x(i)-x1)/(x2-x1)                        r2 = (s.y(i)-y1)/(y2-y1)                        s.x(i)=LX*r1+x1                        s.y(i)=LY*r2+y1                    next i                    x2 = x2 + dx                    y2 = y2 + dy                                    drawShape(s)                    line canvas3,(x1,y1)-(x2,y2),rgb(1,1,1),b,&b1111000011110000                    line canvas3,(x2,y2)-(x2+6,y2+6),rgb(1,1,1),b                    'erase current screen drawing with previous saved screen                    put canvas1,(0,0),canvas2,pset                    'copy latest drawing stage onto screen                    put canvas1,(0,0),canvas3,trans                    update()                    'line canvas3,(x1,y1)-(x2,y2),rgb(1,1,1),b,&b1111000011110000                    'line canvas3,(x2,y2)-(x2+5,y2+5),rgb(1,1,1),b                    ox = mx                    oy = my                end if            wend        end if        loop until mb=1 and (mx<x1 or mx>x2 or my<y1 or my>y2)    '========================================================='           FILLS IN SHAPE WITH COLOR2'=========================================================    'fill in shape    drawShape(s)  'clears canvas3 and draws shape s    'fill outside of shape with white    paint canvas3,(0,0),rgb(254,254,254),s.c1    'fill any magenta area which will be inside shape with color2    for j as integer = 0 to hCanvas-1        for i as integer = 0 to wCanvas-1            if point(i,j,canvas3)=rgb(255,0,255) then                pset canvas3,(i,j),s.c2            end if        next i    next j        'refill outside of shape with magenta    paint canvas3,(0,0),rgb(255,0,255),s.c1    'erase current screen drawing with previous saved screen    put canvas1,(0,0),canvas2,pset    'copy latest drawing stage onto screen    put canvas1,(0,0),canvas3,trans    update()  'copy shape onto screen    while mb=1        getmouse mx,my,,mb    wend    return send function' ====  MAIN PROGRAM ====update()do    getmouse mx,my,,mb    'is it over drawing area??    if mb = 1 and mx > POSX and mx < POSX+wCanvas and my>POSY and my<POSY+hCanvas then        shapes(sCount) = getShape()        sCount = sCount + 1    end if        update()    sleep 1loop until multikey(&H01)'draw shapesclsif sCount<>0 then    for i as integer = 0 to sCount-1    if shapes(i).size<>0 then        for j as integer = 0 to shapes(i).size-2            line (shapes(i).x(j),shapes(i).y(j))-(shapes(i).x(j+1),shapes(i).y(j+1)),rgb(0,0,0)        next j    end if    next iend ifdim as string keykey = inkeywhile key<>"x"    key = inkeywendimageDestroy(canvas1)imageDestroy(canvas2)imageDestroy(canvas3)`
Last edited by BasicCoder2 on Sep 16, 2017 23:10, edited 1 time in total.
Pitto
Posts: 119
Joined: Nov 19, 2012 19:58

### Re: stick man manniquin

Hi BasicCoder2,

for me too programming is a fun passtime, but often I notice that some things I've learned programming may be applied to other fields.

Coming back to topic, would be cool having the ability to set up key-frames and the program could interpolate frames in between. First time I've seen this many years ago in a commercial vector software I was left speechless.

Reinventing what professionals have already done is a fun process too. And if anyone releases his source, others may have inspiration for inventing something new. For example, I've examined the code snipped above (nice it too), I'd use the fill routine that you used in mine FBB project - thanks for sharing.

P.S. Jasc Soccer is in stand-by at moment, but I would like to continue to develop it.
BasicCoder2
Posts: 3598
Joined: Jan 01, 2009 7:03
Location: Australia

### Re: stick man manniquin

Pitto wrote:Coming back to topic, would be cool having the ability to set up key-frames and the program could interpolate frames in between. First time I've seen this many years ago in a commercial vector software I was left speechless..

Between each frame each joint would have change by some amount so to insert intermediate frames perhaps just divide the changes of each joint by the number of frames to be inserted plus one to get the incremental values to add to the first set of joint positions?

Thus if a joint changed from 60 to 70 then the change was +10. So lets say one intermediate frame was to be inserted then the joint position for that frame would be 60 + 5.

The other change not implemented above would be the movement of the reference point which in the example is at the hip. This reference point could also be moved automatically if say the feet are not touching the ground (or are below ground).

The same logic could also be applied to intermediate rotations and magnifications.

Now if three frames are considered and you want intermediate values it might be like using the Bezier curve to generate the intermediate positions.

Or just learn to use the software that already does all this including software that deals with 3D objects and their physics :)
.
leopardpm
Posts: 1795
Joined: Feb 28, 2009 20:58

### Re: stick man manniquin

your keyframe interpolation is spot on, and the addition of bezier curves upon which to interpolate is good too.

I do hate (and love) reinventing the wheel - it does provide satisfaction. Remember we do this to improve our own knowledge, not exactly to make the world a better place... to do that you need to improve upon it or come up with a completely different approach or result. And to do that, it helps to understand the initial algorithm thoroughly, which is what we are doing... so, in the end, its all positives any way you cut it!
BasicCoder2
Posts: 3598
Joined: Jan 01, 2009 7:03
Location: Australia

### Re: stick man manniquin

This is just to see if it piques anyone's interest. It seemed to me that you could write a rigging editor with FreeBasic and then flesh it out with the pixel cloud as seen in dodicat's demos. I dabbled with a simple stick figure and then thought about giving it an isometric display as shown above.

The example below is supposed to be a walking bear (headless at this stage). It was edited by a simple rigging editor I have been trying to develop. The output of the editor is in the data statements. The editor can change the angle of a pivot point and/or the length of a bone being rotated.

Be it a bear or a man the bones are the same, they just vary in length. I changed the angle and length of a stickman bone set to make a bear bone set. Different actions are simply sequences of angles over units of time. It is no different to controlling a robot man or bear (or dog) except it is virtual not an actual physical entity.

For reasons I don't understand such sequences and bone lengths are not shared or available for those making 3d animations using rendering software. Such sequences would best be extracted from the actions of real animals rather than the silly manual positioning of bones for each frame as appears to be the case in the current batch of 3d rendering software.

In the simple case of the isometric 3d stick man above I just shifted the shoulder and hip positions for opposing limbs. In the example below I simply shifted the frames by 180 degrees for the other set of legs.

Code: Select all

`'some useful definesConst Pi = 4 * Atn(1)Dim Shared As Double TwoPi = 8 * Atn(1)Dim Shared As Double RtoD = 180 / Pi   ' radians * RtoD = degreesDim Shared As Double DtoR = Pi / 180   ' degrees * DtoR = radiansscreenres 800,480,32Sub drawLine(x1 as integer,y1 as integer,x2 as integer, y2 as integer,size as integer,c as uinteger)    Dim As Integer ax, ay, d, dxx, dyy, x, y    circle (x1,y1),size,c,,,,f    If x1 = x2 And y1 = y2 Then Exit Sub      If x1 = x2 Then        x = x1        if y2>y1 then            For y as integer  = y1 To y2                if size = 0 then                    pset (x,y),c                else                    circle (x,y),size,c,,,,f                end if            Next y        else            for y as integer = y2 to y1                if size = 0 then                    pset (x,y),c                else                    circle (x,y),size,c,,,,f                end if            next y        end if          Elseif y1 = y2 Then        y = y1        if x2>x1 then            For x as integer = x1 To x2                if size = 0 then                    pset (x,y),c                else                    circle (x,y),size,c,,,,f                end if            next x        else            for x as integer = x2 to x1                if size = 0 then                    pset (x,y),c                else                    circle (x,y),size,c,,,,f                end if            next x        end if    Else        dxx = x2 - x1        dyy = y2 - y1        ax = 1        ay = 1            If dxx < 0 Then            dxx = -dxx            ax = -1        End If            If dyy < 0 Then            dyy = -dyy            ay = -1        End If            x = x1        y = y1            dim as integer ii            If dxx >= dyy Then            ii = dxx + 1            dyy Shl= 1            d = dyy - dxx            dxx Shl= 1                  While ii > 0                ii -= 1                if size = 0 then                    pset (x,y),c                else                    circle (x,y),size,c,,,,f                end if                        If d >= 0 Then                    y += ay                    d -= dxx                 End If                         d += dyy                 x += ax              Wend          Else              ii = dyy + 1              dxx Shl= 1              d = dxx - dyy              dyy Shl= 1              While ii > 0                  ii -= 1                if size = 0 then                    pset (x,y),c                else                    circle (x,y),size,c,,,,f                end if                          If d >= 0 Then                      x += ax                      d -= dyy                  End If                          d += dxx                  y += ay              Wend          End If    End IfEnd Subtype PIVOT    as integer r       'reset start angle    as integer p       'pointer to previous bone    as integer x1      'absolute start    as integer y1    as integer x2      'end  point    as integer y2    as single  a       'angle of joint    as single  aMin    'limits of joint movement    as single  aMax    as single  s       'size    as ulong   c       'colorend typedim shared as single angle'dim shared as integer selected   'selected bone numberdim shared as integer selFrame   'currently selected frameselFrame = 1dim shared as integer selFrame2   'selFrame2 = 5   '180 degrees out of phasedim shared as integer TBONESTBONES = 8dim shared as integer TFRAMESTFRAMES = 8dim shared as PIVOT pivots(1 to TFRAMES,0 to TBONES)'set starting positionsfor i as integer = 1 to TFRAMES    pivots(i,0).x2 = 101   'start point    pivots(i,0).y2 = 102    pivots(i,1).r = 1    pivots(i,1).p = 0    pivots(i,2).p = 1    pivots(i,3).p = 2    pivots(i,4).p = 3'=======================================    pivots(i,5).r = 1        pivots(i,5).p = 0    pivots(i,6).p = 5    pivots(i,7).p = 6    pivots(i,8).p = 7next ifor i as integer = 1 to TFRAMES    for j as integer = 0 to TBONES        read pivots(i,j).r,pivots(i,j).a,pivots(i,j).s,pivots(i,j).p    next jnext isub drawBones()    screenlock    cls    angle = 0    for i as integer = 0 to TBONES        color pivots(selFrame,i).c        if pivots(selFrame,i).r = 1 then angle = pivots(selFrame,0).a        if pivots(selFrame,i).a < 0   then pivots(selFrame,i).a = pivots(selFrame,i).a + 360        if pivots(selFrame,i).a > 359 then pivots(selFrame,i).a = pivots(selFrame,i).a - 360        angle = angle + pivots(selFrame,i).a        if angle < 0   then angle = angle + 360        if angle > 359 then angle = angle - 360        pivots(selFrame,i).x1 = pivots(selFrame, pivots(selFrame,i).p ).x2        pivots(selFrame,i).y1 = pivots(selFrame, pivots(selFrame,i).p ).y2        pivots(selFrame,i).x2 = pivots(selFrame,i).x1 + cos(angle*DtoR) * pivots(selFrame,i).s        pivots(selFrame,i).y2 = pivots(selFrame,i).y1 + sin(angle*DtoR) * pivots(selFrame,i).s         drawLine ( pivots(selFrame,i).x1, pivots(selFrame,i).y1, pivots(selFrame,i).x2, pivots(selFrame,i).y2, 3 ,rgb(255,255,0))        if i = 1 or i = 5 then            drawLine ( pivots(selFrame,i).x1, pivots(selFrame,i).y1, pivots(selFrame,i).x2, pivots(selFrame,i).y2, 9 ,rgb(100,100,255))        end if        circle (pivots(selFrame,i).x1,pivots(selFrame,i).y1),3,rgb(200,200,200)        circle (pivots(selFrame,i).x2,pivots(selFrame,i).y2),3,rgb(200,100,0)    next i    '=================================================================================    for i as integer = 0 to TBONES        color pivots(selFrame2,i).c        if pivots(selFrame2,i).r = 1 then angle = pivots(selFrame2,0).a        if pivots(selFrame2,i).a < 0   then pivots(selFrame2,i).a = pivots(selFrame2,i).a + 360        if pivots(selFrame2,i).a > 359 then pivots(selFrame2,i).a = pivots(selFrame2,i).a - 360        angle = angle + pivots(selFrame2,i).a        if angle < 0   then angle = angle + 360        if angle > 359 then angle = angle - 360        pivots(selFrame2,i).x1 = pivots(selFrame2, pivots(selFrame2,i).p ).x2        pivots(selFrame2,i).y1 = pivots(selFrame2, pivots(selFrame2,i).p ).y2        pivots(selFrame2,i).x2 = pivots(selFrame2,i).x1 + cos(angle*DtoR) * pivots(selFrame2,i).s        pivots(selFrame2,i).y2 = pivots(selFrame2,i).y1 + sin(angle*DtoR) * pivots(selFrame2,i).s         drawLine ( pivots(selFrame2,i).x1, pivots(selFrame2,i).y1, pivots(selFrame2,i).x2, pivots(selFrame2,i).y2, 3 ,rgb(255,0,0))        if i = 1 or i = 5 then            drawLine ( pivots(selFrame,i).x1, pivots(selFrame,i).y1, pivots(selFrame,i).x2, pivots(selFrame,i).y2, 9 ,rgb(100,100,255))        end if        circle (pivots(selFrame2,i).x1,pivots(selFrame2,i).y1),3,rgb(200,200,200)        circle (pivots(selFrame2,i).x2,pivots(selFrame2,i).y2),3,rgb(200,100,0)    next i'==================================================================================    line (0,182)-(799,182),rgb(200,100,0)    screenunlockend subdim as string keydim as integer mx,my,mbdrawBones()dim as single dd,dx,dydo    selFrame = selFrame + 1    if selFrame > 8 then selFrame = 1    selFrame2 = selFrame2 + 1    if selFrame2 > 8 then selFrame2 = 1    drawBones()    sleep 200loop until  multikey(&H01)DATA  0,0,0,0,1,356,48,0,0,94,44,1,0,329,40,2,0,302,18,3,1,180,48,0,0,266,40,5,0,0,36,6,0,275,22,7DATA  0,0,0,0,1,356,48,0,0,110,44,1,0,314,40,2,0,304,18,3,1,180,48,0,0,263,40,5,0,20,36,6,0,262,22,7DATA  0,0,0,0,1,0,48,0,0,118,44,1,0,314,40,2,0,289,18,3,1,180,48,0,0,265,40,5,0,27,36,6,0,259,22,7DATA  0,0,0,0,1,0,48,0,0,126,44,1,0,317,40,2,0,278,18,3,1,180,48,0,0,287,40,5,0,22,36,6,0,261,22,7DATA  0,0,0,0,1,8,48,0,0,130,44,1,0,299,40,2,0,284,22,3,1,180,48,0,0,262,40,5,0,51,36,6,0,243,22,7DATA  0,0,0,0,1,0,48,0,0,143,44,1,0,275,40,2,0,80,18,3,1,180,48,0,0,252,40,5,0,0,36,6,0,281,22,7DATA  0,0,0,0,1,0,48,0,0,114,44,1,0,270,40,2,0,80,18,3,1,177,48,0,0,250,40,5,0,3,36,6,0,289,22,7DATA  0,0,0,0,1,0,48,0,0,94,44,1,0,304,40,2,0,346,18,3,1,180,48,0,0,258,40,5,0,0,36,6,0,283,22,7`
leopardpm
Posts: 1795
Joined: Feb 28, 2009 20:58

### Re: stick man manniquin

thats really cool, BC!
BasicCoder2
Posts: 3598
Joined: Jan 01, 2009 7:03
Location: Australia

### Re: stick man manniquin

Now the pivot points have to be given a 3d coordinate and drawn on a isometric display.
This program rotates the animated rigging around the starting point on the "backbone".
The opposite side in the same frame are again drawn 180 degrees out of phase to the other side.
Each side is shifted in opposite directions on the z axis.
Keep in mind the z axis moves into the screen not vertically.

The reason I did not use the thick lines this time is because as the rigging rotates the order in which the parts are to be drawn changes.
To overcome this I have to replace the lines with a cloud of pixel values which can be sorted using the painter's algorithm.
.

Code: Select all

`'some useful definesConst Pi = 4 * Atn(1)Dim Shared As Double TwoPi = 8 * Atn(1)Dim Shared As Double RtoD = 180 / Pi   ' radians * RtoD = degreesDim Shared As Double DtoR = Pi / 180   ' degrees * DtoR = radiansscreenres 640,480,32type PIVOT    as integer r       'reset start angle    as integer p       'pointer to previous bone    as single x1      'absolute start    as single y1    as single z1    as single x2      'end  point    as single y2    as single z2    as single  a       'angle of joint in xy axis    as single  aMin    'limits of joint movement    as single  aMax    as single  s       'size    as ulong   c       'colorend typesub setXYZ(x as single,y as single,z as single)    circle (x+z\2,y-z\2),3,rgb(0,255,0)end subsub lineXYZ(x1 as single,y1 as single,z1 as single,x2 as single,y2 as single,z2 as single)    line (x1+z1\2,y1-z1\2)-(x2+z2\2,y2-z2\2),rgb(255,0,0)    setXYZ(x1,y1,z1)    setXYZ(x2,y2,z2)end subdim shared as single angle,angle2'dim shared as integer selected   'selected bone numberdim shared as integer selFrame   'currently selected frameselFrame = 1dim shared as integer selFrame2   'selFrame2 = 5   '180 degrees out of phasedim shared as integer TBONESTBONES = 8dim shared as integer TFRAMESTFRAMES = 8dim shared as PIVOT pivots(1 to TFRAMES,0 to TBONES)'set starting positionsfor i as integer = 1 to TFRAMES    pivots(i,0).x2 = 0  'start point at 0,0,0    pivots(i,0).y2 = 0    pivots(i,0).z2 = 0    pivots(i,1).r = 1    pivots(i,1).p = 0    pivots(i,2).p = 1    pivots(i,3).p = 2    pivots(i,4).p = 3'=======================================    pivots(i,5).r = 1        pivots(i,5).p = 0    pivots(i,6).p = 5    pivots(i,7).p = 6    pivots(i,8).p = 7next ifor i as integer = 1 to TFRAMES    for j as integer = 0 to TBONES        read pivots(i,j).r,pivots(i,j).a,pivots(i,j).s,pivots(i,j).p    next jnext isub drawBones()    dim as single px1,py1,pz1,px2,py2,pz2,rx1,ry1,rz1,rx2,ry2,rz2    angle2 = angle2 - 5    screenlock    cls    line (320,0)-(320,479),rgb(200,200,255)    line (0,240)-(639,240),rgb(200,200,255)    for i as integer = 0 to TBONES        color pivots(selFrame,i).c        if pivots(selFrame,i).r = 1 then angle = pivots(selFrame,0).a        if pivots(selFrame,i).a < 0   then pivots(selFrame,i).a = pivots(selFrame,i).a + 360        if pivots(selFrame,i).a > 359 then pivots(selFrame,i).a = pivots(selFrame,i).a - 360        angle = angle + pivots(selFrame,i).a        if angle < 0   then angle = angle + 360        if angle > 359 then angle = angle - 360        pivots(selFrame,i).x1 = pivots(selFrame, pivots(selFrame,i).p ).x2        pivots(selFrame,i).y1 = pivots(selFrame, pivots(selFrame,i).p ).y2        pivots(selFrame,i).x2 = pivots(selFrame,i).x1 + cos(angle*DtoR) * pivots(selFrame,i).s        pivots(selFrame,i).y2 = pivots(selFrame,i).y1 + sin(angle*DtoR) * pivots(selFrame,i).s                   'draw isometric view                    pz1 = pivots(selFrame,i).z1-20            px1 = pivots(selFrame,i).x1            py1 = pivots(selFrame,i).y1                rz1 = (Cos(angle2*DtoR) * pz1 - Sin(angle2*DtoR) * px1)            rx1 = (Sin(angle2*DtoR) * pz1 + Cos(angle2*DtoR) * px1)                        ry1 = py1                        pz2 = pivots(selFrame,i).z2-20            px2 = pivots(selFrame,i).x2            py2 = pivots(selFrame,i).y2                        rz2 = (Cos(angle2*DtoR) * pz2 - Sin(angle2*DtoR) * px2)            rx2 = (Sin(angle2*DtoR) * pz2 + Cos(angle2*DtoR) * px2)            ry2 = py2                        LINEXYZ(rx1+320,ry1+240,rz1,rx2+320,ry2+240,rz2)    next i'==================================================================================    for i as integer = 0 to TBONES        color pivots(selFrame2,i).c        if pivots(selFrame2,i).r = 1 then angle = pivots(selFrame2,0).a        if pivots(selFrame2,i).a < 0   then pivots(selFrame2,i).a = pivots(selFrame2,i).a + 360        if pivots(selFrame2,i).a > 359 then pivots(selFrame2,i).a = pivots(selFrame2,i).a - 360        angle = angle + pivots(selFrame2,i).a        if angle < 0   then angle = angle + 360        if angle > 359 then angle = angle - 360        pivots(selFrame2,i).x1 = pivots(selFrame2, pivots(selFrame2,i).p ).x2        pivots(selFrame2,i).y1 = pivots(selFrame2, pivots(selFrame2,i).p ).y2        pivots(selFrame2,i).x2 = pivots(selFrame2,i).x1 + cos(angle*DtoR) * pivots(selFrame2,i).s        pivots(selFrame2,i).y2 = pivots(selFrame2,i).y1 + sin(angle*DtoR) * pivots(selFrame2,i).s                    'draw isometric view            pz1 = pivots(selFrame2,i).z1+20            px1 = pivots(selFrame2,i).x1            py1 = pivots(selFrame2,i).y1                rz1 = (Cos(angle2*DtoR) * pz1 - Sin(angle2*DtoR) * px1)            rx1 = (Sin(angle2*DtoR) * pz1 + Cos(angle2*DtoR) * px1)                        ry1 = py1                        pz2 = pivots(selFrame2,i).z2+20            px2 = pivots(selFrame2,i).x2            py2 = pivots(selFrame2,i).y2                        rz2 = (Cos(angle2*DtoR) * pz2 - Sin(angle2*DtoR) * px2)            rx2 = (Sin(angle2*DtoR) * pz2 + Cos(angle2*DtoR) * px2)            ry2 = py2                        LINEXYZ(rx1+320,ry1+240,rz1,rx2+320,ry2+240,rz2)            '=================================================================================================    next i    screenunlockend subdim as string keydim as integer mx,my,mbdrawBones()dim as single dd,dx,dydo    selFrame = selFrame + 1    if selFrame > 8 then selFrame = 1    selFrame2 = selFrame2 + 1    if selFrame2 > 8 then selFrame2 = 1    drawBones()    sleep 200loop until  multikey(&H01)DATA  0,0,0,0,1,356,48,0,0,94,44,1,0,329,40,2,0,302,18,3,1,180,48,0,0,266,40,5,0,0,36,6,0,275,22,7DATA  0,0,0,0,1,356,48,0,0,110,44,1,0,314,40,2,0,304,18,3,1,180,48,0,0,263,40,5,0,20,36,6,0,262,22,7DATA  0,0,0,0,1,0,48,0,0,118,44,1,0,314,40,2,0,289,18,3,1,180,48,0,0,265,40,5,0,27,36,6,0,259,22,7DATA  0,0,0,0,1,0,48,0,0,126,44,1,0,317,40,2,0,278,18,3,1,180,48,0,0,287,40,5,0,22,36,6,0,261,22,7DATA  0,0,0,0,1,8,48,0,0,130,44,1,0,299,40,2,0,284,22,3,1,180,48,0,0,262,40,5,0,51,36,6,0,243,22,7DATA  0,0,0,0,1,0,48,0,0,143,44,1,0,275,40,2,0,80,18,3,1,180,48,0,0,252,40,5,0,0,36,6,0,281,22,7DATA  0,0,0,0,1,0,48,0,0,114,44,1,0,270,40,2,0,80,18,3,1,177,48,0,0,250,40,5,0,3,36,6,0,289,22,7DATA  0,0,0,0,1,0,48,0,0,94,44,1,0,304,40,2,0,346,18,3,1,180,48,0,0,258,40,5,0,0,36,6,0,283,22,7`