Link to home
Start Free TrialLog in
Avatar of Claude050897
Claude050897

asked on

How to calculate BaryCentric?

Is there some formula to calculate the BaryCentric a,b & c values of a 3-D triangle?

I want to calculate this for a point P on the plane of the 3-D triangle. Is it then possible to calculate a point P' from a "warped" 3-D triangle so that P' is proportianally in the same place inside the "warped" triangle as P inside the original triangle?

Basically I want P' must "look" to be in the correct place as the triangle gets "warped" and I thought Barycentric coordinates would be the best, but the stuff on the internet is quite hairy to read through!
Avatar of cybermike3d
cybermike3d

Right, here goes ... In order to simplify the explanation I have written a little qbasic program that demonstrates the concept. Check it out and see if you have any questions. Basicaly what happens is your triangl has three points in space. Each, a 3D co ord consisting of an X,Y and Z offset  Then, you have a point on the plane of the triangle. This too has an X,Y and Z offset. Now, as you move your 'eye' along any of the viewing axis (Yaw, Pitch and Roll) so, the viweing angle to the triangle will change. So too, will the corresponding angle to the point on the face of the triangle. So, you simply translate the XYZ of the three points plus the XYZ of the reference point which you then project onto a 2d surface (Your computer screen) The little program that I wrote below, does this using floating point or integer math. The trade off is of course fast and coarse vs slow and accurate. ie, Hi speed games would use the integer based math and cad systems would use the floating point math.

This will do it for you either way. As the triangle is warped by a changing viewing angle, so too is the aspect of the reference point, but it still retains its position ratio wise to the other points of the triangle. Like I said, play with it a bit and feel free to ask me if you have any further questions.

regards

Cybermike3D

Cut and paste the following code onto your notepad then save as a .bas file. Check that is does in fact save properly. You may need to rename it on the disk. The use qbasic to load and run it. Have fun

'Triangle face orientation. www.cybermike3d.co.za

    CLS
    SCREEN 9, 1

      'set alf to 0 for hi resolution lo speed calculation mode
      'set alf to 1 to lo res hi speed integer calculation mode.

    alf = 0 '

    IF alf = 1 THEN
      'DEFINT B-Z
    END IF
      DIM sine(360)
      DIM cosine(360)
      DIM arctab(100, 100)
      DIM rootab(80, 80)
      PRINT "Building arctan table :"
       
      FOR yy = 0 TO 100
      FOR xx = 0 TO 100
      x = xx - 50: y = yy - 50
      IF y <> 0 THEN gan = ATN(x / y) * 57
      IF y = 0 AND x = 0 THEN gan = 0: gang = 0
      IF y = 0 AND x < 0 THEN gan = 270
      IF y = 0 AND x > 0 THEN gan = 90
      gang = gan
      IF y < 0 THEN gang = 180 + gan
      IF x < 0 AND y > 0 THEN gang = 360 + gan
      arctab(xx, yy) = gang
      NEXT
      NEXT
       
      PRINT "Building square root table"
       
      FOR yy = 0 TO 80
      FOR xx = 0 TO 80
      ra = SQR(xx ^ 2 + yy ^ 2)
      rootab(xx, yy) = ra
      NEXT
      NEXT

      PRINT "Building sine / cosine table"
      FOR l = 0 TO 360
      a = SIN(l / 57) * 100:
      sine(l) = INT(a)
      a = COS(l / 57) * 100:
      cosine(l) = INT(a)
      
      
      NEXT

      DIM rx(70), ry(70), rz(70), col(70), cmd(70)
      DIM nx(70), ny(70), nz(70)
      zf = 10
      GOSUB loadf
      GOSUB roll
      GOSUB roll
      WHILE g$ <> CHR$(27)
      g$ = ""
      g$ = INKEY$

      ' ---------------------------------- keyboard stuff
      IF g$ = "l" THEN CLS : GOSUB loadf
      IF g$ = "8" THEN ya = ya - 4
      IF g$ = "2" THEN ya = ya + 4
      IF g$ = "4" THEN xa = xa - 4
      IF g$ = "6" THEN xa = xa + 4
      IF g$ = "3" THEN za = za + 4
      IF g$ = "1" THEN za = za - 4
      IF g$ = "+" THEN zf = zf + 1
      IF g$ = "-" THEN zf = zf - 1
       
      IF g$ = "t" THEN tf = 1
      IF g$ = " " THEN tf = 0
      IF tf = 1 THEN ya = ya + ac: xa = xa + ac1: za = za + ac2
      IF g$ = "a" THEN ac = ac + 1
      IF g$ = "s" THEN ac = ac - 1
      IF g$ = "q" THEN ac1 = ac1 + 1
      IF g$ = "w" THEN ac1 = ac1 - 1
      IF g$ = "z" THEN ac2 = ac2 + 1
      IF g$ = "x" THEN ac2 = ac2 - 1

      IF g$ = "j" THEN nx(4) = nx(4) - 1
      IF g$ = "k" THEN nx(4) = nx(4) + 1
      IF g$ = "i" THEN ny(4) = ny(4) - 1
      IF g$ = "m" THEN ny(4) = ny(4) + 1

      IF g$ = "r" THEN GOSUB loadf

      IF ya > 360 THEN ya = ya - 360
      IF xa > 360 THEN xa = xa - 360
      IF za > 360 THEN za = za - 360
       
      IF ya < 0 THEN ya = ya + 360
      IF xa < 0 THEN xa = xa + 360
      IF za < 0 THEN za = za + 360
      'STOP
      IF g$ <> "" THEN GOSUB roll
      IF tf = 1 THEN GOSUB roll

      WEND
      END
roll:
      ws = ws - 1: ws = ABS(ws): os = ws - 1: os = ABS(os)
      SCREEN 9, 1, ws, os
      VIEW (0, 0)-(639, 349), 0
      LOCATE 1, 1
      PRINT "Press [I,J,K,M] to move point within triangle, [L] to load new traingle"
      PRINT "      [1,2,3,4,6,8] to rotate on x,y,z axis,  +- to zoom in/ out"
      PRINT
      PRINT "X-angle ="; xa
      PRINT "Y-angle ="; ya
      PRINT "Z-angle ="; za
      FOR l = 0 TO f
      rx(l) = nx(l)
      ry(l) = ny(l)
      rz(l) = nz(l)
      '----------------- translate in the three axis
rolx:   x = rx(l):
      y = ry(l):
      na = xa:
      GOSUB getcord
      rx(l) = xn:
      ry(l) = yn:
roly:   x = rz(l):
      y = ry(l):
      na = ya:
      GOSUB getcord
      rz(l) = xn:
      ry(l) = yn:
rolz:   x = rx(l):
      y = rz(l):
      na = za:
      GOSUB getcord
      rx(l) = xn:
      rz(l) = yn:
      '-------------------------- place polygon on screen
      xx = rx(l) * zf / 10 + 320:
      yy = ry(l) * zf / 10 + 268:
      '-------------------------- and correct aspect ratio
      yy = yy * 6 / 8
        '------------------------- draw thingys on screen
      IF cmd(l) = 4 THEN CIRCLE (xx, yy), 4, 8: PAINT (xx, yy), 8
      IF cmd(l) = 4 THEN CIRCLE (xx, yy), 4, col(l): PAINT (xx, yy), col(l): PSET (xx - 1, yy - 2), 15:   PSET (xx - 2, yy - 1), 15
      IF cmd(l) = 2 THEN CIRCLE (xx, yy), 3, 8: PAINT (xx, yy), 8
      IF cmd(l) = 2 THEN CIRCLE (xx, yy), 3, col(l): PAINT (xx, yy), col(l): PSET (xx - 1, yy - 2), 15:   PSET (xx - 2, yy - 1), 15
      IF cmd(l) = 2 THEN LINE (ox, oy)-(xx, yy), col(l)
      
      x4 = x3: x3 = x2: x2 = x1: x1 = x0: x0 = xx
      y4 = y3: y3 = y2: y2 = y1: y1 = y0: y0 = yy
      ox = xx: oy = yy

      PSET (320, 200)

      NEXT
      RETURN

getcord:

   IF alf = 0 THEN
   '---------- floating point calculation routine
       ixdif = x
       iydif = y
     itargetrange = SQR(ixdif ^ 2 + iydif ^ 2)
     ra = itargetrange
     IF iydif <> 0 THEN itgan = ATN(ixdif / iydif) * 57.2958
     IF iydif = 0 AND ixdif = 0 THEN itgan = 0: itgang = 0
     IF iydif = 0 AND ixdif < 0 THEN itgan = 270
     IF iydif = 0 AND ixdif > 0 THEN itgan = 90
     itgang = itgan
     IF iydif < 0 THEN itgang = 180 + itgan
     IF ixdif < 0 AND iydif > 0 THEN itgang = 360 + itgan
     itnang = na + itgang
     IF itnang > 180 THEN itnang = itnang - 360
     IF itnang < -180 THEN itnang = itnang + 360
     xn = SIN(itnang / 57.2958) * ra
     yn = COS(itnang / 57.2958) * ra
     RETURN
    END IF
   
    IF alf = 1 THEN
     
   ' ----------- integer based lookup table routine
      xx = ABS(x): yy = ABS(y)
      xx = xx / 2: yy = yy / 2
      ra = rootab(xx, yy)
      ra = ra * 2
      x = x / 3 + 50: y = y / 3 + 50
      nang = arctab(x, y) + na
      IF nang > 360 THEN nang = nang - 360
      IF nang < 0 THEN nang = nang + 360
      xn = sine(nang) * ra
      xn = xn / 100
      yn = cosine(nang) * ra
      yn = yn / 100
      RETURN
    END IF
      

loadf:
      ' --------------- load a random triangle
      f = 4
      FOR l = 0 TO 4
      nx(l) = RND(1) * 200 - 100: rx(l) = nx(l)
      ny(l) = RND(1) * 200 - 100: ry(l) = ny(l)
      nz(l) = 0: rz(l) = 0
      cmd(l) = 2
      col(l) = 7
      cmd(0) = 0

      NEXT

      nx(3) = nx(0): rx(3) = nx(3)
      ny(3) = ny(0): ry(3) = ny(3)
      cmd(4) = 4

      nx(4) = (nx(1) + nx(2) + nx(3)) / 3
      ny(4) = (ny(1) + ny(2) + ny(3)) / 3


      nx(5) = -100
      nx(6) = 100
      cmd(6) = 2
      col(6) = 2

      ny(7) = -100
      ny(8) = 100
      cmd(8) = 2
      col(8) = 1

      nz(9) = -100
      nz(10) = 100
      cmd(10) = 2
      col(10) = 4
      f = 10
      RETURN



ASKER CERTIFIED SOLUTION
Avatar of ChristerEricson
ChristerEricson

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
No response to Proposed Answer, assume it served the need and finalizing today.  In the event Asker returns with additional needs here, please response.

Moondancer
Community Support Moderator @ Experts Exchange