Author Topic: 3D Graph Plotter  (Read 7733 times)

0 Members and 1 Guest are viewing this topic.

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: 3D Graph Plotter
« Reply #15 on: January 31, 2021, 08:24:16 pm »
Holy cow I forgot all about that. Beautiful!
You're not done when it works, you're done when it's right.

Offline _vince

  • Seasoned Forum Regular
  • Posts: 422
    • View Profile
Re: 3D Graph Plotter
« Reply #16 on: February 01, 2021, 07:49:49 pm »
Thx, I really enjoy playing with it.  I've been improving the colour scheme over time as well, trying to go for 'textbook quality'

I really wanted to write some kind of PDF reviewing basic complex analysis topics from the visual perspective, ie zeros, poles, filters, integrals, Cauchy's etc because it's so rarely done and stunningly beautiful but don't have the willpower for it
cd2.png
* cd2.png (Filesize: 146.49 KB, Dimensions: 800x600, Views: 308)
cd3.png
* cd3.png (Filesize: 795.56 KB, Dimensions: 800x600, Views: 334)
cd1.png
* cd1.png (Filesize: 162.32 KB, Dimensions: 800x600, Views: 329)

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: 3D Graph Plotter
« Reply #17 on: February 01, 2021, 08:10:28 pm »
That looks textbook quality already vince for sure. As for the writeup, yikes. That's a lot of explaining to do. For anyone interested, this isn't your Kansas math anymore. This speaks of residue calculus:

 
ss.png
You're not done when it works, you're done when it's right.

Offline _vince

  • Seasoned Forum Regular
  • Posts: 422
    • View Profile
Re: 3D Graph Plotter
« Reply #18 on: February 01, 2021, 08:33:05 pm »
Seeing cauchy's integral formula evaluated numerically converge to the function was amazing to discover, but yes, too much writing and notation.  There's so much neat stuff out there that's probably never been plotted before (afaik), I think it is a worthwhile artistic pursuit
cd5.png
* cd5.png (Filesize: 431.7 KB, Dimensions: 800x600, Views: 284)
cd4.png
* cd4.png (Filesize: 428.44 KB, Dimensions: 800x600, Views: 292)
cd6.png
* cd6.png (Filesize: 376.38 KB, Dimensions: 800x600, Views: 278)

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: 3D Graph Plotter
« Reply #19 on: February 05, 2021, 11:53:55 am »
Alrighty, had to keep going with this one more step. This version of the 3d plotter replaces z=f(x,y) with parametric equations instead. This lets you make all kinds of exotic shapes. The full project, including all test curves, is at:

https://github.com/wfbarnes/3D-Grapher

A bare-bones way to test it yourself is of course included below.

 
trefoil.png

 
mobius.png

 
ellipse.png

 
trig.png

* sxmath.bi (Filesize: 1.72 KB, Downloads: 205)
* sxmath.bm (Filesize: 25.21 KB, Downloads: 223)
* sxript.bi (Filesize: 7.99 KB, Downloads: 211)
* sxript.bm (Filesize: 99 KB, Downloads: 219)
* 3D Grapher - Parametric.bas (Filesize: 27.64 KB, Downloads: 212)
You're not done when it works, you're done when it's right.

Offline _vince

  • Seasoned Forum Regular
  • Posts: 422
    • View Profile
Re: 3D Graph Plotter
« Reply #20 on: February 05, 2021, 06:23:50 pm »
nice work, I wanted to suggest that z = f(x, y) is just a special case of parametric surface but you're ahead.  Adding a time dimension t for animation is also neat too.

The other cool thing worth plotting is vector fields and perhaps the option of randomly spawned particles
vf.png
* vf.png (Filesize: 156.21 KB, Dimensions: 688x666, Views: 310)

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
    • View Profile
Re: 3D Graph Plotter
« Reply #21 on: February 05, 2021, 06:29:51 pm »
Hey, I like the idea of vector fields and time animation. Maybe I'll do that next time 3D season comes up for me. I did enough yesterday to last half an eon.

In the meantime, this 2D demo does exactly that, sorta:

Code: QB64: [Select]
  1.  
  2. _TITLE "Vector Field"
  3.  
  4. ' Meta
  5.  
  6. CONST Aquamarine = _RGB32(127, 255, 212)
  7. CONST Lime = _RGB32(0, 255, 0)
  8.  
  9. DIM SHARED XSize
  10. DIM SHARED YSize
  11. DIM SHARED XCells
  12. DIM SHARED YCells
  13. XSize = 30
  14. YSize = 30
  15. XCells = 30
  16. YCells = 30
  17. NPC = .1 * SQR(XCells * YCells)
  18. SCREEN _NEWIMAGE(XSize * XCells, YSize * YCells, 32)
  19.  
  20.  
  21. TYPE Vector
  22.     x AS DOUBLE
  23.     y AS DOUBLE
  24.  
  25. TYPE FieldLine
  26.     Center AS Vector
  27.     Tangent AS Vector
  28.  
  29. TYPE Particle
  30.     Displacement AS Vector
  31.     Velocity AS Vector
  32.     Shade AS _UNSIGNED LONG
  33.  
  34. TYPE Charge
  35.     Center AS Vector
  36.     Radial AS Vector
  37.     Angular AS Vector
  38.  
  39. DIM SHARED VectorField(XCells, YCells) AS FieldLine
  40. DIM SHARED Particles(XCells, YCells, NPC) AS Particle
  41. DIM SHARED Charges(100) AS Charge
  42. DIM SHARED ChargeCount
  43.  
  44. ChargeCount = 1
  45. Charges(ChargeCount).Center.x = 0
  46. Charges(ChargeCount).Center.y = 0
  47. Charges(ChargeCount).Radial.x = .05
  48. Charges(ChargeCount).Radial.y = .05
  49. Charges(ChargeCount).Angular.x = 0
  50. Charges(ChargeCount).Angular.y = 0
  51.  
  52.  
  53. FOR i = 1 TO XCells
  54.     FOR j = 1 TO YCells
  55.         VectorField(i, j).Center.x = (1 / 2) * XSize * (2 * i - XCells) - XSize / 2
  56.         VectorField(i, j).Center.y = (1 / 2) * YSize * (2 * j - YCells) - YSize / 2
  57.         FOR k = 1 TO NPC
  58.             Particles(i, j, k).Shade = Lime
  59.             Particles(i, j, k).Displacement.x = XSize * (RND - .5)
  60.             Particles(i, j, k).Displacement.y = YSize * (RND - .5)
  61.         NEXT
  62.     NEXT
  63.  
  64. CALL CalculateField
  65.  
  66.  
  67.         x = _MOUSEX
  68.         y = _MOUSEY
  69.         IF ((x > 0) AND (x < _WIDTH) AND (y > 0) AND (y < _HEIGHT)) THEN
  70.             Charges(ChargeCount).Center.x = (x - _WIDTH / 2)
  71.             Charges(ChargeCount).Center.y = (-y + _HEIGHT / 2)
  72.             CALL CalculateField
  73.         END IF
  74.     LOOP
  75.  
  76.     k = _KEYHIT
  77.     SELECT CASE k
  78.         CASE 49
  79.             Charges(ChargeCount).Radial.x = .05
  80.             Charges(ChargeCount).Radial.y = .05
  81.             Charges(ChargeCount).Angular.x = 0
  82.             Charges(ChargeCount).Angular.y = 0
  83.         CASE 50
  84.             Charges(ChargeCount).Radial.x = -.05
  85.             Charges(ChargeCount).Radial.y = -.05
  86.             Charges(ChargeCount).Angular.x = 0
  87.             Charges(ChargeCount).Angular.y = 0
  88.         CASE 51
  89.             Charges(ChargeCount).Radial.x = .05
  90.             Charges(ChargeCount).Radial.y = -.05
  91.             Charges(ChargeCount).Angular.x = 0
  92.             Charges(ChargeCount).Angular.y = 0
  93.         CASE 52
  94.             Charges(ChargeCount).Radial.x = -.05
  95.             Charges(ChargeCount).Radial.y = .05
  96.             Charges(ChargeCount).Angular.x = 0
  97.             Charges(ChargeCount).Angular.y = 0
  98.         CASE 53
  99.             Charges(ChargeCount).Radial.x = 0
  100.             Charges(ChargeCount).Radial.y = 0
  101.             Charges(ChargeCount).Angular.x = .05
  102.             Charges(ChargeCount).Angular.y = -.05
  103.         CASE 54
  104.             Charges(ChargeCount).Radial.x = 0
  105.             Charges(ChargeCount).Radial.y = 0
  106.             Charges(ChargeCount).Angular.x = -.05
  107.             Charges(ChargeCount).Angular.y = .05
  108.         CASE 48
  109.             ChargeCount = 1
  110.         CASE 32
  111.             ChargeCount = ChargeCount + 1
  112.             Charges(ChargeCount).Center.x = Charges(ChargeCount - 1).Center.x
  113.             Charges(ChargeCount).Center.y = Charges(ChargeCount - 1).Center.y
  114.             Charges(ChargeCount).Radial.x = Charges(ChargeCount - 1).Radial.x
  115.             Charges(ChargeCount).Radial.y = Charges(ChargeCount - 1).Radial.y
  116.             Charges(ChargeCount).Angular.x = Charges(ChargeCount - 1).Angular.x
  117.             Charges(ChargeCount).Angular.y = Charges(ChargeCount - 1).Angular.y
  118.     END SELECT
  119.     IF (k <> 0) THEN
  120.         CALL CalculateField
  121.     END IF
  122.     _KEYCLEAR
  123.  
  124.     LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA(0, 0, 0, 20), BF
  125.  
  126.     DIM xc AS DOUBLE
  127.     DIM yc AS DOUBLE
  128.     DIM xd AS DOUBLE
  129.     DIM yd AS DOUBLE
  130.     DIM xx AS DOUBLE
  131.     DIM yy AS DOUBLE
  132.  
  133.     LOCATE 1, 1: PRINT "Press 1-6 to change charge type. Press space to fix charge, 0 to clear."
  134.     FOR i = 1 TO XCells
  135.         FOR j = 1 TO YCells
  136.             xc = VectorField(i, j).Center.x
  137.             yc = VectorField(i, j).Center.y
  138.             FOR k = 1 TO NPC
  139.                 xd = 0
  140.                 yd = 0
  141.                 xx = Particles(i, j, k).Displacement.x + .1 * Particles(i, j, k).Velocity.x
  142.                 yy = Particles(i, j, k).Displacement.y + .1 * Particles(i, j, k).Velocity.y
  143.                 IF (xx < -XSize / 2) THEN
  144.                     xd = -xx + XSize / 2
  145.                 END IF
  146.                 IF (xx > XSize / 2) THEN
  147.                     xd = -xx - XSize / 2
  148.                 END IF
  149.                 IF (yy < -YSize / 2) THEN
  150.                     yd = -yy + YSize / 2
  151.                 END IF
  152.                 IF (yy > YSize / 2) THEN
  153.                     yd = -yy + -YSize / 2
  154.                 END IF
  155.                 Particles(i, j, k).Displacement.x = xx + xd
  156.                 Particles(i, j, k).Displacement.y = yy + yd
  157.                 CALL cpset(xc + Particles(i, j, k).Displacement.x, yc + Particles(i, j, k).Displacement.y, Particles(i, j, k).Shade)
  158.             NEXT
  159.         NEXT
  160.     NEXT
  161.     _LIMIT 60
  162.     _DISPLAY
  163.  
  164.  
  165. SUB CalculateField
  166.     DIM i AS INTEGER
  167.     DIM j AS INTEGER
  168.     DIM k AS INTEGER
  169.     DIM dx AS DOUBLE
  170.     DIM dy AS DOUBLE
  171.     DIM d2 AS DOUBLE
  172.     DIM xx AS DOUBLE
  173.     DIM yy AS DOUBLE
  174.     FOR i = 1 TO XCells
  175.         FOR j = 1 TO YCells
  176.             xx = 0
  177.             yy = 0
  178.             FOR k = 1 TO ChargeCount
  179.                 dx = VectorField(i, j).Center.x - Charges(k).Center.x
  180.                 dy = VectorField(i, j).Center.y - Charges(k).Center.y
  181.                 d2 = 5000 / (dx * dx + dy * dy)
  182.                 xx = xx + (Charges(k).Radial.x * dx * d2) + (Charges(k).Angular.x * dy * d2)
  183.                 yy = yy + (Charges(k).Radial.y * dy * d2) + (Charges(k).Angular.y * dx * d2)
  184.             NEXT
  185.             VectorField(i, j).Tangent.x = xx
  186.             VectorField(i, j).Tangent.y = yy
  187.             FOR k = 1 TO NPC
  188.                 Particles(i, j, k).Velocity.x = VectorField(i, j).Tangent.x
  189.                 Particles(i, j, k).Velocity.y = VectorField(i, j).Tangent.y
  190.             NEXT
  191.         NEXT
  192.     NEXT
  193.  
  194. SUB cpset (x1, y1, col AS _UNSIGNED LONG)
  195.     PSET (_WIDTH / 2 + x1, -y1 + _HEIGHT / 2), col
  196.  
  197.  

 
ss.png

You're not done when it works, you're done when it's right.