QB64.org Forum

Active Forums => QB64 Discussion => Topic started by: STxAxTIC on June 17, 2020, 01:13:09 pm

Title: Harder-than-it-looks math problem
Post by: STxAxTIC on June 17, 2020, 01:13:09 pm
This sounds easy, but the devil is in the details. I wanna see people stab at this problem and I know some of you can't resist...

Suppose I hand you the three XY coordinates of three points that make a triangle. If I give you a fourth XY point, is that point located inside the triangle or outside?

Answer in code.
Title: Re: Harder-than-it-looks math problem
Post by: Ashish on June 17, 2020, 01:20:30 pm
I think I dealed with this stuff when I posted space filling with polygons in program section https://www.qb64.org/forum/index.php?topic=2515
Title: Re: Harder-than-it-looks math problem
Post by: Qwerkey on June 17, 2020, 01:41:11 pm
No matter that Ashish (along with others?) has already solved this.  This looks an irresistible problem for a non-mathematician.  I think that you have defined my activity for tomorrow.
Title: Re: Harder-than-it-looks math problem
Post by: MasterGy on June 17, 2020, 01:44:24 pm
That's a good question. That's exactly what I dealt with recently. (Philipines and the Resistors # 2)
I researched for a long time before I succeeded.


3d-Triangle : a,b,c   
3d-platoon  : p,q
(indexs : 1-x , 2-y , 3-z)

D1 = b(2) * c(3) - b(3) * c(2) - a(2) * c(3) + a(3) * c(2) + a(2) * b(3) - a(3) * b(2)
D2 = b(1) * c(3) - b(3) * c(1) - a(1) * c(3) + a(3) * c(1) + a(1) * b(3) - a(3) * b(1)
D3 = b(1) * c(2) - b(2) * c(1) - a(1) * c(2) + a(2) * c(1) + a(1) * b(2) - a(2) * b(1)

D = a(1) * (b(2) * c(3) - b(3) * c(2)) - a(2) * (b(1) * c(3) - b(3) * c(1)) + a(3) * (b(1) * c(2) - b(2) * c(1))

A = -(p(1) * D1 + p(2) * D2 + p(3) * D3 - D)
B = (q(1) - p(1)) * D1 + (q(2) - p(2)) * D2 + (q(3) - p(3)) * D3




if B = 0, then the triangle and the plane of the section are parallel to each other


intersection point: A / B
proportionally between points p and q


so: if A / B> = 0 and A / B <= 1, then the triangle ABC contains the section PQ


the thing works, do it, if someone is making a 3d game, this code might come in handy
Title: Re: Harder-than-it-looks math problem
Post by: STxAxTIC on June 17, 2020, 04:46:40 pm
I figured this would have been hit already. Nice work boys.

The question came up in discord lately and this is what I decided on:

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(800, 600, 32)
  2.  
  3. TYPE Vector
  4.     x AS DOUBLE
  5.     y AS DOUBLE
  6.  
  7. TYPE Triangle
  8.     p1 AS Vector ' corner coordinates
  9.     p2 AS Vector
  10.     p3 AS Vector
  11.  
  12. DIM TestTriangle AS Triangle
  13. DIM TestParticle AS Vector
  14.  
  15. TestTriangle.p1.x = 150
  16. TestTriangle.p1.y = 0
  17. TestTriangle.p2.x = 0
  18. TestTriangle.p2.y = 100
  19. TestTriangle.p3.x = -150
  20. TestTriangle.p3.y = -100
  21.  
  22.  
  23.         x0 = _MOUSEX
  24.         y0 = _MOUSEY
  25.         x0 = (x0 - _WIDTH / 2)
  26.         y0 = (-y0 + _HEIGHT / 2)
  27.         TestParticle.x = x0
  28.         TestParticle.y = y0
  29.     LOOP
  30.  
  31.     CALL DrawTriangle(TestTriangle)
  32.     CALL cpset(TestParticle.x, TestParticle.y, _RGBA(255, 255, 255, 255))
  33.     CALL PointInsideTriangle(TestTriangle, TestParticle)
  34.  
  35.     _DISPLAY
  36.     _LIMIT 30
  37.  
  38.  
  39. SUB PointInsideTriangle (tr AS Triangle, p AS Vector)
  40.     DIM s12inside AS INTEGER
  41.     DIM s23inside AS INTEGER
  42.     DIM s31inside AS INTEGER
  43.     DIM dz AS Vector
  44.     DIM ta AS Vector
  45.     ' side 12
  46.     dz.x = p.x - tr.p1.x
  47.     dz.y = p.y - tr.p1.y
  48.     ta.x = tr.p2.x - tr.p1.x
  49.     ta.y = tr.p2.y - tr.p1.y
  50.     IF CrossProduct(ta, dz) > 0 THEN s12inside = 1 ELSE s12inside = 0
  51.     ' side 23
  52.     dz.x = p.x - tr.p2.x
  53.     dz.y = p.y - tr.p2.y
  54.     ta.x = tr.p3.x - tr.p2.x
  55.     ta.y = tr.p3.y - tr.p2.y
  56.     IF CrossProduct(ta, dz) > 0 THEN s23inside = 1 ELSE s23inside = 0
  57.     ' side 31
  58.     dz.x = p.x - tr.p3.x
  59.     dz.y = p.y - tr.p3.y
  60.     ta.x = tr.p1.x - tr.p3.x
  61.     ta.y = tr.p1.y - tr.p3.y
  62.     IF CrossProduct(ta, dz) > 0 THEN s31inside = 1 ELSE s31inside = 0
  63.     IF s12inside = 1 AND s23inside = 1 AND s31inside = 1 THEN
  64.         LOCATE 1, 1: PRINT "inside"
  65.     ELSE
  66.         LOCATE 1, 1: PRINT "      "
  67.     END IF
  68.  
  69. FUNCTION CrossProduct (a AS Vector, b AS Vector)
  70.     CrossProduct = a.x * b.y - b.x * a.y
  71.  
  72. SUB DrawTriangle (t AS Triangle)
  73.     CALL cline(t.p1.x, t.p1.y, t.p2.x, t.p2.y, _RGBA(255, 255, 255, 255))
  74.     CALL cline(t.p2.x, t.p2.y, t.p3.x, t.p3.y, _RGBA(255, 255, 255, 255))
  75.     CALL cline(t.p3.x, t.p3.y, t.p1.x, t.p1.y, _RGBA(255, 255, 255, 255))
  76.  
  77. SUB cline (x1 AS DOUBLE, y1 AS DOUBLE, x2 AS DOUBLE, y2 AS DOUBLE, col AS _UNSIGNED LONG)
  78.     LINE (_WIDTH / 2 + x1, -y1 + _HEIGHT / 2)-(_WIDTH / 2 + x2, -y2 + _HEIGHT / 2), col
  79.  
  80. SUB cpset (x1 AS DOUBLE, y1 AS DOUBLE, col AS _UNSIGNED LONG)
  81.     PSET (_WIDTH / 2 + x1, -y1 + _HEIGHT / 2), col
  82.  
Title: Re: Harder-than-it-looks math problem
Post by: Qwerkey on June 18, 2020, 04:14:00 am
So, this will be my approach:  In triangle ABC, with angles alpha, beta and gamma, if the point is inside the triangle it forms triangles with angles alpha', beta' and gamma'.  Here the condition alpha' + beta' + gamma' = 2pi is met.  Outside, alpha' + beta' + gamma' < 2pi.  So I will code for this condition.  When I've completed, I'll check with the existing solutions and this will make an interesting InForm project (I may be some time).
  [ This attachment cannot be displayed inline in 'Print Page' view ]  

Later edit:  Tested my condition and it seems to work.  So will now slog on with the coding.
In the meantime, you might like to try my bit of trial code. Vertices%(3, 0) and Vertices%(3, 1) are the x- & y- of the test position.  You can manually change the values to put it inside or outside and see the difference in the printed result: when this is negative (over and above calculation errors), the point is outside.  The final code will give explanations of what the calculations are.
Code: QB64: [Select]
  1. 'Is a point inside or outside a triangle? (problem set by STxAxTIC)
  2.  
  3. CONST SmallErr# = 1E-11
  4.  
  5. DIM Vertices%(3, 1)
  6.  
  7. Vertices%(0, 0) = 10
  8. Vertices%(0, 1) = 420
  9. Vertices%(1, 0) = 600
  10. Vertices%(1, 1) = 150
  11. Vertices%(2, 0) = 690
  12. Vertices%(2, 1) = 440
  13. Vertices%(3, 0) = 520
  14. Vertices%(3, 1) = 165
  15.  
  16. SCREEN _NEWIMAGE(700, 500, 32)
  17.  
  18. LINE (Vertices%(0, 0), Vertices%(0, 1))-(Vertices%(1, 0), Vertices%(1, 1))
  19. LINE (Vertices%(1, 0), Vertices%(1, 1))-(Vertices%(2, 0), Vertices%(2, 1))
  20. LINE (Vertices%(2, 0), Vertices%(2, 1))-(Vertices%(0, 0), Vertices%(0, 1))
  21.  
  22. LINE (Vertices%(3, 0), Vertices%(3, 1))-(Vertices%(0, 0), Vertices%(0, 1)), _RGB32(255, 0, 0)
  23. LINE (Vertices%(3, 0), Vertices%(3, 1))-(Vertices%(1, 0), Vertices%(1, 1)), _RGB32(255, 0, 0)
  24. LINE (Vertices%(3, 0), Vertices%(3, 1))-(Vertices%(2, 0), Vertices%(2, 1)), _RGB32(255, 0, 0)
  25.  
  26. A# = SideLength#(Vertices%(0, 0), Vertices%(0, 1), Vertices%(2, 0), Vertices%(2, 1))
  27. B# = SideLength#(Vertices%(1, 0), Vertices%(1, 1), Vertices%(0, 0), Vertices%(0, 1))
  28. C# = SideLength#(Vertices%(2, 0), Vertices%(2, 1), Vertices%(1, 0), Vertices%(1, 1))
  29.  
  30. D# = SideLength#(Vertices%(3, 0), Vertices%(3, 1), Vertices%(1, 0), Vertices%(1, 1))
  31. E# = SideLength#(Vertices%(3, 0), Vertices%(3, 1), Vertices%(2, 0), Vertices%(2, 1))
  32. F# = SideLength#(Vertices%(3, 0), Vertices%(3, 1), Vertices%(0, 0), Vertices%(0, 1))
  33.  
  34. Alpha# = Angle#(A#, B#, C#)
  35. Beta# = Angle#(B#, C#, A#)
  36. Gamma# = Angle#(C#, A#, B#)
  37.  
  38. AlphaDash# = Angle#(A#, E#, F#)
  39. BetaDash# = Angle#(B#, D#, F#)
  40. GammaDash# = Angle#(C#, D#, E#)
  41.  
  42. PRINT AlphaDash# + BetaDash# + GammaDash# - _PI(2)
  43.  
  44.     _LIMIT 30
  45.  
  46. FUNCTION SideLength# (X1#, Y1#, X2#, Y2#)
  47.     SideLength# = SQR((X1# - X2#) * (X1# - X2#) + (Y1# - Y2#) * (Y1# - Y2#))
  48.  
  49. FUNCTION Angle# (L1#, L2#, L3#)
  50.     Angle# = _ACOS(((L2# * L2#) + (L3# * L3#) - (L1# * L1#)) / (2 * L2# * L3#))
  51.  
Title: Re: Harder-than-it-looks math problem
Post by: STxAxTIC on June 18, 2020, 08:57:56 am
Hmmmmm I like that approach. To keep the primed variables from measuring the wrong angle you can force them to be less than pi. Pretty cool, keep us posted if you see it all the way through.
Title: Re: Harder-than-it-looks math problem
Post by: Qwerkey on June 18, 2020, 10:24:43 am
I have done my bit of InForm coding - seems to work nicely:
https://www.qb64.org/forum/index.php?topic=2716.0 (https://www.qb64.org/forum/index.php?topic=2716.0)
Let me know if you find any fatal flaws.
Title: Re: Harder-than-it-looks math problem
Post by: SMcNeill on June 18, 2020, 12:21:45 pm
And here's a solution without doing any fancy-pancy vector math and such:

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(640, 480, 32)
  2.  
  3. CONST DRAWIT = -1
  4.  
  5. PRINT CheckTriangle(100, 100, 200, 100, 300, 300, 160, 150)
  6. PRINT CheckTriangle(100, 100, 200, 100, 300, 300, 150, 50)
  7.  
  8. FUNCTION CheckTriangle (tx1, ty1, tx2, ty2, tx3, ty3, px, py)
  9.     d = _DEST: s = _SOURCE
  10.     temp = _NEWIMAGE(_WIDTH, _HEIGHT, 32)
  11.     _DEST temp: _SOURCE temp
  12.     COLOR _RGBA32(255, 255, 255, 100)
  13.     LINE (tx1, ty1)-(tx2, ty2)
  14.     LINE (tx2, ty2)-(tx3, ty3)
  15.     LINE (tx3, ty3)-(tx1, ty1)
  16.     txc = (tx1 + tx2 + tx3) / 3 'triangle x center
  17.     tyc = (ty1 + ty2 + ty3) / 3 'triangle y center
  18.     PAINT (txc, tyc)
  19.     _BLEND
  20.     PSET (px, py), _RGBA(255, 0, 0, 200)
  21.     p = POINT(px, py)
  22.     IF p = _RGBA32(255, 55, 55, 222) THEN CheckTriangle = -1
  23.     _DEST d: _SOURCE s
  24.     IF DRAWIT THEN
  25.         CLS
  26.         CIRCLE (px, py), 5, _RGBA(255, 0, 0, 200)
  27.         _PUTIMAGE (0, 0), temp, d
  28.     END IF
  29.     _FREEIMAGE temp

We're basically just doing some simple blending to see if our point appears in the triangle, or not.

Often, if we're already drawing the objects to the screen, a simple method like this is faster and more efficient than doing a string of math calculations for us.  It's also inherently more intuitive for new programmers and children to understand -- to them it's as complex as saying, "Cut a triangle out of a sheet of paper, and toss a drop of ink at it.  Is the ink inside (or on) the triangle, or not?"   It turns the problem into a simple, visual solution, with very little reliance on math at all.
Title: Re: Harder-than-it-looks math problem
Post by: Qwerkey on June 18, 2020, 12:37:30 pm
... a solution without doing any fancy-pancy vector math and such:

Qwerkey: the renowed fancy-pancy mathematician of this site - not!!
Title: Re: Harder-than-it-looks math problem
Post by: bplus on June 18, 2020, 12:42:50 pm
And here's a solution without doing any fancy-pancy vector math and such:

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(640, 480, 32)
  2.  
  3. CONST DRAWIT = -1
  4.  
  5. PRINT CheckTriangle(100, 100, 200, 100, 300, 300, 160, 150)
  6. PRINT CheckTriangle(100, 100, 200, 100, 300, 300, 150, 50)
  7.  
  8. FUNCTION CheckTriangle (tx1, ty1, tx2, ty2, tx3, ty3, px, py)
  9.     d = _DEST: s = _SOURCE
  10.     temp = _NEWIMAGE(_WIDTH, _HEIGHT, 32)
  11.     _DEST temp: _SOURCE temp
  12.     COLOR _RGBA32(255, 255, 255, 100)
  13.     LINE (tx1, ty1)-(tx2, ty2)
  14.     LINE (tx2, ty2)-(tx3, ty3)
  15.     LINE (tx3, ty3)-(tx1, ty1)
  16.     txc = (tx1 + tx2 + tx3) / 3 'triangle x center
  17.     tyc = (ty1 + ty2 + ty3) / 3 'triangle y center
  18.     PAINT (txc, tyc)
  19.     _BLEND
  20.     PSET (px, py), _RGBA(255, 0, 0, 200)
  21.     p = POINT(px, py)
  22.     IF p = _RGBA32(255, 55, 55, 222) THEN CheckTriangle = -1
  23.     _DEST d: _SOURCE s
  24.     IF DRAWIT THEN
  25.         CLS
  26.         CIRCLE (px, py), 5, _RGBA(255, 0, 0, 200)
  27.         _PUTIMAGE (0, 0), temp, d
  28.     END IF
  29.     _FREEIMAGE temp

We're basically just doing some simple blending to see if our point appears in the triangle, or not.

Often, if we're already drawing the objects to the screen, a simple method like this is faster and more efficient than doing a string of math calculations for us.  It's also inherently more intuitive for new programmers and children to understand -- to them it's as complex as saying, "Cut a triangle out of a sheet of paper, and toss a drop of ink at it.  Is the ink inside (or on) the triangle, or not?"   It turns the problem into a simple, visual solution, with very little reliance on math at all.

Ha! I knew this was coming from Steve :) what took so long?

@SMcNeill  how did you figure the point value for intersecting triangle? here:
Code: QB64: [Select]
  1. IF p = _RGBA32(255, 55, 55, 222) THEN CheckTriangle = -1

I suspect that takes some fansy-pansy tech knowledge too ;-))
or maybe you tested a known point and took a reading of the value and translated that back into _RGBA32 arguments.

I do think math would be faster than PAINTing large triangles and drawing things on the side. Maybe you could setup a timed test. It IS easier to understand no doubt in my mind.
Title: Re: Harder-than-it-looks math problem
Post by: SMcNeill on June 18, 2020, 03:38:18 pm
Quote
I suspect that takes some fansy-pansy tech knowledge too ;-))
or maybe you tested a known point and took a reading of the value and translated that back into _RGBA32 arguments.

That's the exact trick.  Just plot a normal point for the triangle, then PSET any point in it.  Read that value and now you have your_RGBA values to compare it against.  ;D
Title: Re: Harder-than-it-looks math problem
Post by: STxAxTIC on June 18, 2020, 05:10:46 pm
Emphasis on "math problem"... Yes, the preskool solution is there for those who... Nevermind... Nice analysis steve
Title: Re: Harder-than-it-looks math problem
Post by: Pete on June 18, 2020, 05:38:33 pm
The answer is 4.
Title: Re: Harder-than-it-looks math problem
Post by: Qwerkey on June 19, 2020, 04:18:54 am
I hope that I have now corrected the error in mine, quod vide.
Title: Re: Harder-than-it-looks math problem
Post by: luke on June 19, 2020, 07:03:43 am
@SMcNeill why do you the PSET at all? Wouldn't it just be easier to check the POINT directly:
Code: [Select]
FUNCTION CheckTriangle (tx1, ty1, tx2, ty2, tx3, ty3, px, py)
    DIM p AS _UNSIGNED LONG, r AS _UNSIGNED LONG
    d = _DEST: s = _SOURCE
    temp = _NEWIMAGE(_WIDTH, _HEIGHT, 32)
    _DEST temp: _SOURCE temp
    COLOR _RGB(255, 255, 255)
    _DONTBLEND
    LINE (tx1, ty1)-(tx2, ty2)
    LINE (tx2, ty2)-(tx3, ty3)
    LINE (tx3, ty3)-(tx1, ty1)
    txc = (tx1 + tx2 + tx3) / 3 'triangle x center
    tyc = (ty1 + ty2 + ty3) / 3 'triangle y center
    PAINT (txc, tyc)
    CheckTriangle = POINT(px, py) > 0

    _DEST d: _SOURCE s
    IF DRAWIT THEN
        CLS
        CIRCLE (px, py), 5, _RGB(255, 0, 0)
        _PUTIMAGE (0, 0), temp, d
    END IF
    _FREEIMAGE temp
END FUNCTION
Or am I missing something?
Title: Re: Harder-than-it-looks math problem
Post by: Qwerkey on June 19, 2020, 07:16:22 am
Thanks, QB64, for _ACOS() additional to the restrictive ATN() of QuickBasic.  My method uses The Law of Cosines to find angles from triangle side lengths.

To keep the primed variables from measuring the wrong angle you can force them to be less than pi.

The beauty of _ACOS() is that it always returns the angle in the range 0 - pi, and so needs no code adjusters.
Next time, I'll have a slightly harder trig puzzle!
Title: Re: Harder-than-it-looks math problem
Post by: bplus on June 19, 2020, 01:42:35 pm
Nice one @luke  I suspected there was easier way to Steve's method but blundered, my mind probably too cluttered with worries about my gambling problem with Blackjack ;-))

Here is key to the simplest solution (so far), well @MasterGy has fewest Lines of Code (I think, don't see working demo) but why does that work? assuming it does, knowing MasterGy I think I am safe ;-))
I am also assuming Luke's also works because..., well you know!
BTW I am also assuming STx's works for same reason. :)
I only tried @SMcNeill 's and know it works as far as it went, but why I ask the PAINT question at the end of this post.

Key to simple math solution:
Code: QB64: [Select]
  1. FUNCTION PtInteriorOfAngleTF (ox1, oy1, ax1, ay1, ax2, ay2, ptx, pty)
  2.     a1 = atan360(_ATAN2(ay1 - oy1, ax1 - ox1)) ' angle of one arm from origin of angle
  3.     a2 = atan360(_ATAN2(ay2 - oy1, ax2 - ox1)) ' angle of the other arm from origin of angle
  4.     ap = atan360(_ATAN2(pty - oy1, ptx - ox1)) ' angle of point from same origin
  5.     IF a2 < a1 THEN SWAP a2, a1 'make a1 the samller of the two angles for test fit of point
  6.     IF ap >= a1 AND ap <= a2 THEN PtInteriorOfAngleTF = -1 ' if point angle is inside or on the 2 arm angles then point is in or on.
  7.  
  8.     'PRINT a1, a2, ap, PtInteriorOfAngleTF 'debug
  9.     'I can't believe all the blunders I've made putting this so simple an idea together!!!
  10.  
  11. FUNCTION atan360 (ra) 'convert radian angle from _ATAN2()  to guaranteed positive angle
  12.     atan360 = _R2D(ra + _PI(2))
  13.  

Here it is in action to the triangle problem:
Code: QB64: [Select]
  1. _TITLE "Interior of an Angle" ' B+ 2020-06-09  Math Geometry
  2. ' Interesting problem posed by STx 2020-06-17
  3. ' https://www.qb64.org/forum/index.php?topic=2714.0
  4.  
  5. 'got me thinking how I might solve it here is what I came uo with
  6. ' to save time using Steve's code to problem setup, so I check same as his for starters
  7.  
  8. SCREEN _NEWIMAGE(640, 480, 32)
  9. px = 160: py = 150
  10. PRINT "Test Interior"
  11. tf = PtInteriorOfTriangleTF(100, 100, 200, 100, 300, 300, px, py)
  12. IF tf THEN PRINT "Pt ("; px; ","; py; ") is in or on." ELSE PRINT "Pt ("; px; ","; py; ") is Out."
  13. px = 150: py = 50
  14. PRINT "Test Exterior"
  15. tf = PtInteriorOfTriangleTF(100, 100, 200, 100, 300, 300, px, py)
  16. IF tf THEN PRINT "Pt ("; px; ","; py; ") is in or on." ELSE PRINT "Pt ("; px; ","; py; ") is Out."
  17.  
  18. 'try some more borderline cases
  19. ' pt is corner of tringle
  20. PRINT "Test triangle point"
  21. px = 100: py = 100
  22. tf = PtInteriorOfTriangleTF(100, 100, 200, 100, 300, 300, px, py)
  23. IF tf THEN PRINT "Pt ("; px; ","; py; ") is in or on." ELSE PRINT "Pt ("; px; ","; py; ") is Out."
  24. 'point is on line between 2 points
  25. px = 150: py = 100
  26. PRINT "Test Border line"
  27. tf = PtInteriorOfTriangleTF(100, 100, 200, 100, 300, 300, px, py)
  28. IF tf THEN PRINT "Pt ("; px; ","; py; ") is in or on." ELSE PRINT "Pt ("; px; ","; py; ") is Out."
  29.  
  30. 'oh let's just test everywhere!
  31. _TITLE "Testing random points on screen, press escape to quit any other for another test..."
  32. WHILE _KEYDOWN(27) = 0
  33.     CLS
  34.     px = RND * 640: py = RND * 480
  35.     tf = PtInteriorOfTriangleTF(100, 100, 200, 100, 300, 300, px, py)
  36.     IF tf THEN PRINT "Pt ("; px; ","; py; ") is in or on." ELSE PRINT "Pt ("; px; ","; py; ") is Out."
  37.     SLEEP
  38.  
  39.  
  40. SUB drawSituation (tx1, ty1, tx2, ty2, tx3, ty3, px, py) '3 points of triangle and test pt yellow
  41.     LINE (tx1, ty1)-(tx2, ty2)
  42.     LINE (tx2, ty2)-(tx3, ty3)
  43.     LINE (tx3, ty3)-(tx1, ty1)
  44.     CIRCLE (px, py), 3, &HFFFFFF00
  45.  
  46. FUNCTION PtInteriorOfTriangleTF (tx1, ty1, tx2, ty2, tx3, ty3, px, py)
  47.     drawSituation tx1, ty1, tx2, ty2, tx3, ty3, px, py
  48.     IF PtInteriorOfAngleTF(tx1, ty1, tx2, ty2, tx3, ty3, px, py) THEN
  49.         IF PtInteriorOfAngleTF(tx2, ty2, tx1, ty1, tx3, ty3, px, py) THEN
  50.             IF PtInteriorOfAngleTF(tx3, ty3, tx1, ty1, tx2, ty2, px, py) THEN
  51.                 PtInteriorOfTriangleTF = -1
  52.             END IF
  53.         END IF
  54.     END IF
  55.  
  56. FUNCTION PtInteriorOfAngleTF (ox1, oy1, ax1, ay1, ax2, ay2, ptx, pty)
  57.     a1 = atan360(_ATAN2(ay1 - oy1, ax1 - ox1))
  58.     a2 = atan360(_ATAN2(ay2 - oy1, ax2 - ox1))
  59.     ap = atan360(_ATAN2(pty - oy1, ptx - ox1))
  60.     IF a2 < a1 THEN SWAP a2, a1
  61.     IF ap >= a1 AND ap <= a2 THEN PtInteriorOfAngleTF = -1
  62.  
  63.     'PRINT a1, a2, ap, PtInteriorOfAngleTF 'debug
  64.     'I can't believe all the blunders I've made putting this so simple an idea together!!!
  65.  
  66. FUNCTION atan360 (ra) 'convert radian angle from _ATAN2()  to guaranteed positive angle
  67.     atan360 = _R2D(ra + _PI(2))
  68.  
  69. 'FUNCTION CheckTriangle (tx1, ty1, tx2, ty2, tx3, ty3, px, py)
  70.  
  71. 'thanks SMcNeill for this simple to understand method
  72. ' BUT I think I have simpler! ;-))
  73.  
  74.  
  75. '    DIM p AS _UNSIGNED LONG, r AS _UNSIGNED LONG
  76. '    d = _DEST: s = _SOURCE
  77. '    temp = _NEWIMAGE(_WIDTH, _HEIGHT, 32)
  78. '    _DEST temp: _SOURCE temp
  79. '    COLOR _RGBA32(255, 255, 255, 100)
  80. '    _DONTBLEND
  81. '    LINE (tx1, ty1)-(tx2, ty2)
  82. '    LINE (tx2, ty2)-(tx3, ty3)
  83. '    LINE (tx3, ty3)-(tx1, ty1)
  84. '    txc = (tx1 + tx2 + tx3) / 3 'triangle x center
  85. '    tyc = (ty1 + ty2 + ty3) / 3 'triangle y center
  86. '    PAINT (txc, tyc)
  87. '    _BLEND
  88. '    PSET (px, py), _RGBA(255, 0, 0, 200)
  89. '    p = POINT(px, py)
  90. '    IF p = _RGBA32(255, 55, 55, 222) THEN CheckTriangle = -1
  91. '    _DEST d: _SOURCE s
  92. '    IF DRAWIT THEN
  93. '        CLS
  94. '        CIRCLE (px, py), 5, _RGBA(255, 0, 0, 200)
  95. '        _PUTIMAGE (0, 0), temp, d
  96. '    END IF
  97. '    _FREEIMAGE temp
  98. 'END FUNCTION
  99.  

It is both simple to understand AND mathematical the Intersect of 2 Heavenly Realms.

In English, it just says that a Point Interior to a Triangle has to be Interior to each of it's 3 Interior Angles.

Does PAINT consider a Point On the Triangle in it? Anyway this code considers On or In as opposed to Exterior only.

EDIT: add more comments for key function
Title: Re: Harder-than-it-looks math problem
Post by: STxAxTIC on June 19, 2020, 03:18:54 pm
Problem with non vector methods is you're stuck on screen. Let's tilt the x and y axes both by say, whatever 31 degrees. How does your solution change?

All my solution does is require that the triangle be drawn with with the right hand rule, and the criteria for being inside is whether or not the stray point occurs to the left of the vector, that's all it does. No explicit coordinate system means this works for any orientation of both the coordinates and the triangle.
Title: Re: Harder-than-it-looks math problem
Post by: STxAxTIC on June 19, 2020, 03:59:20 pm
Wow sorry if I marked that as best answer for a while, don't forum and drive, kids.
Title: Re: Harder-than-it-looks math problem
Post by: bplus on June 19, 2020, 04:02:37 pm
Problem with non vector methods is you're stuck on screen. Let's tilt the x and y axes both by say, whatever 31 degrees. How does your solution change?

All my solution does is require that the triangle be drawn with with the right hand rule, and the criteria for being inside is whether or not the stray point occurs to the left of the vector, that's all it does. No explicit coordinate system means this works for any orientation of both the coordinates and the triangle.

Here we go again with the stupid right hand rule! a 3D property when discussing 2D triangles or shall we talk about triangles on spheres?

A point interior of an angle is not dependent on axis orientation you know that, all the way down to Topology, so I can talk surface of sphere.

Quote
In English, it just says that a Point Interior to a Triangle has to be Interior to each of it's 3 Interior Angles.

My solution depends solely on angles between points.
Title: Re: Harder-than-it-looks math problem
Post by: STxAxTIC on June 19, 2020, 04:58:12 pm
There are few instances here when someone so blatantly can't see the point. Don't be at the center of it man, it's not usually you.
Title: Re: Harder-than-it-looks math problem
Post by: Pete on June 19, 2020, 05:51:00 pm
Of course he can't "see" the point. A point is zero-dimensional space. You really need to take my Physic 101 Sems, Bill. :D

Pete
Title: Re: Harder-than-it-looks math problem
Post by: SMcNeill on June 19, 2020, 08:00:41 pm
@SMcNeill why do you the PSET at all? Wouldn't it just be easier to check the POINT directly

It would be.  I just added the PSET as a physical representation of the problem.  The code to draw the visible circle to highlight the point came later, as my poor eyes just couldn't pick up on that single pixel very easily.


Quote
Does PAINT consider a Point On the Triangle in it? Anyway this code considers On or In as opposed to Exterior only.

My example counts a point ON the triangle as being IN it.  If that's not desirable for your needs, just redraw the triangles edge a separate color after the fill has did its job.

Quote
Problem with non vector methods is you're stuck on screen. Let's tilt the x and y axes both by say, whatever 31 degrees. How does your solution change?

If you're dealing with 3 dimensional triangles and points, use the GL commands to draw it and check the color value.  The solution really doesn't need to change at all.  People have displayed 3d graphics on 2d screens for ages now.  Didn't you know that??
Title: Re: Harder-than-it-looks math problem
Post by: STxAxTIC on June 19, 2020, 08:50:18 pm
Nope, I have a lot to learn from you about math apparently. Can I start pitching my questions right to you?
Title: Re: Harder-than-it-looks math problem
Post by: STxAxTIC on June 19, 2020, 08:56:56 pm
Actually don't answer, I will pose the same question in 3d next chance I get, that will at least give a chance for bplus to become aminus. I don't know what yer gonna do Steve...
Title: Re: Harder-than-it-looks math problem
Post by: bplus on June 19, 2020, 11:43:57 pm
Dang this is harder than I thought, didn't test enough cases (only one, blah).

Made one fix that repaired test reports for most triangles but still am getting false negatives. I know the theory is right just not executed well enough yet.
Title: Re: Harder-than-it-looks math problem
Post by: Ashish on June 20, 2020, 12:04:25 am
Ok.. Here's my approach. It is based on areas.

EDIT : Code Updated. Now press SpaceBar to generate new triangle
Code: QB64: [Select]
  1. TYPE vec2
  2.     x AS INTEGER
  3.     y AS INTEGER
  4. _TITLE "Move mouse into triangle, it will become red"
  5. SCREEN _NEWIMAGE(600, 600, 32)
  6.  
  7. DIM p(2) AS vec2, m AS vec2
  8. p(0).x = INT(RND * 600): p(0).y = INT(RND * 600)
  9. p(1).x = INT(RND * 600): p(1).y = INT(RND * 600)
  10. p(2).x = INT(RND * 600): p(2).y = INT(RND * 600)
  11. red~& = _RGB(255, 0, 0)
  12. white~& = _RGB32(255)
  13.     k$ = INKEY$
  14.     CLS
  15.     IF k$ = " " THEN
  16.         p(0).x = INT(RND * 600): p(0).y = INT(RND * 600)
  17.         p(1).x = INT(RND * 600): p(1).y = INT(RND * 600)
  18.         p(2).x = INT(RND * 600): p(2).y = INT(RND * 600)
  19.     END IF
  20.     m.x = _MOUSEX: m.y = _MOUSEY
  21.     IF insideTriangle(p(0), p(1), p(2), m) THEN COLOR red~& ELSE COLOR white~&
  22.     FOR i = 0 TO 2 'draw triangle
  23.         LINE (p(i).x, p(i).y)-(p((i + 1) MOD 3).x, p((i + 1) MOD 3).y)
  24.     NEXT
  25.     _DISPLAY
  26.     _LIMIT 60
  27.  
  28. 'p1,p2,p3 -> coordinates of triangle
  29. 'N is the test point.
  30. 'returns true if N is inside the triangle
  31. FUNCTION insideTriangle (p1 AS vec2, p2 AS vec2, p3 AS vec2, N AS vec2)
  32.     p_area& = triangleArea(p1, p2, N) + triangleArea(p1, N, p3) + triangleArea(N, p2, p3)
  33.     insideTriangle = (ABS(triangleArea(p1, p2, p3) - p_area&) <= 3)
  34. FUNCTION triangleArea& (p1 AS vec2, p2 AS vec2, p3 AS vec2)
  35.     triangleArea& = 0.5 * ABS(p1.x * (p2.y - p3.y) + p2.x * (p3.y - p1.y) + p3.x * (p1.y - p2.y))
  36.  
Title: Re: Harder-than-it-looks math problem
Post by: STxAxTIC on June 20, 2020, 12:08:14 am
Ashish, you have made my day!!!

For those above who are terrified of vectors, this perfect solution contains the same calculation mine does, right down to the cross product of vectors --- except what Ashish just blessed us with is just so damn efficient and tight! A lovely lovely job. I think we'll all be answering to you as the QB64 president in a few short years.


Title: Re: Harder-than-it-looks math problem
Post by: bplus on June 20, 2020, 12:26:56 am
Yeah well, looks like he only tested one triangle.

Oh that's clever though, the area of 3 little triangles with the point as a vertex has to equal the given triangle area.

To me that's just plain Geometry and no right hand rule in sight, LOL.
Title: Re: Harder-than-it-looks math problem
Post by: Ashish on June 20, 2020, 12:49:37 am
ouch! I updated the code @bplus
Title: Re: Harder-than-it-looks math problem
Post by: bplus on June 20, 2020, 12:56:48 am
ouch! I updated the code @bplus

LOL thanks, I did say it was clever ;-))

I got mine working now with or without a WINDOW statement that completely flips the axis, the only code I have to change is the mouse with PMAP so you can check any point you want, the triangles change rather quickly.

Code: QB64: [Select]
  1. SCREEN _NEWIMAGE(800, 600, 32)
  2.  
  3. WINDOW (0, 600)-(800, 0) 'lets screw the hell up with the coodinate system
  4.  
  5. ' works with or without flopping the coordinate system with WINDOW statement above
  6.  
  7. 1 x1 = RND * 800: y1 = RND * 600: x2 = RND * 800: y2 = RND * 600: x3 = RND * 800: y3 = RND * 600
  8. WHILE _KEYDOWN(27) = 0
  9.     CLS: lc = lc + 1
  10.     IF lc >= 100 THEN lc = 1: GOTO 1 'new triangle
  11.  
  12.  
  13.     'use this with WINDOW command
  14.     WHILE _MOUSEINPUT: WEND: px = PMAP(_MOUSEX, 0): py = PMAP(_MOUSEY, 1)
  15.  
  16.     'use this without Window
  17.     'WHILE _MOUSEINPUT: WEND: px = _MOUSEX: py = _MOUSEY
  18.  
  19.  
  20.     tf = PtInteriorOfTriangleTF(x1, y1, x2, y2, x3, y3, px, py)
  21.     IF tf THEN PRINT "Pt ("; px; ","; py; ") in or on." ELSE PRINT "Pt ("; px; ","; py; ") is Out."
  22.     IF INKEY$ = " " THEN
  23.         SLEEP
  24.     END IF
  25.     _DISPLAY: _LIMIT 30
  26.  
  27. SUB drawSituation (tx1, ty1, tx2, ty2, tx3, ty3, px, py) '3 points of triangle and test pt yellow
  28.     LINE (tx1, ty1)-(tx2, ty2)
  29.     LINE (tx2, ty2)-(tx3, ty3)
  30.     LINE (tx3, ty3)-(tx1, ty1)
  31.     CIRCLE (px, py), 3, &HFFFFFF00
  32.     CIRCLE (tx1, ty1), 3, &HFFFF0000
  33.     CIRCLE (tx2, ty2), 3, &HFF00AA00
  34.     CIRCLE (tx3, ty3), 3, &HFF0000FF
  35.  
  36. FUNCTION PtInteriorOfTriangleTF (tx1, ty1, tx2, ty2, tx3, ty3, px, py)
  37.     drawSituation tx1, ty1, tx2, ty2, tx3, ty3, px, py
  38.     IF PtInteriorOfAngleTF(tx1, ty1, tx2, ty2, tx3, ty3, px, py) THEN
  39.         IF PtInteriorOfAngleTF(tx2, ty2, tx1, ty1, tx3, ty3, px, py) THEN
  40.             IF PtInteriorOfAngleTF(tx3, ty3, tx1, ty1, tx2, ty2, px, py) THEN
  41.                 PtInteriorOfTriangleTF = -1
  42.             END IF
  43.         END IF
  44.     END IF
  45.  
  46. FUNCTION PtInteriorOfAngleTF (ox1, oy1, ax1, ay1, ax2, ay2, ptx, pty)
  47.     a1 = atan360(_ATAN2(ay1 - oy1, ax1 - ox1)) ' angle of one arm from origin of angle
  48.     a2 = atan360(_ATAN2(ay2 - oy1, ax2 - ox1)) ' angle of the other arm from origin of angle
  49.     ap = atan360(_ATAN2(pty - oy1, ptx - ox1)) ' angle of point from same origin
  50.     IF a2 < a1 THEN SWAP a2, a1 'make a1 the samller of the two angles for test fit of point
  51.     IF ABS(a2 - a1) > 180 THEN 'can't be so we are crossing the point where angles go from 360 to 0
  52.         a1Fix = a1 + 360 'fix  a1Fix is now the greater angle
  53.         IF ap < a1 THEN apFix = ap + 360 ELSE apFix = ap 'a1Fix is now the greater angle
  54.         IF apFix <= a1Fix AND apFix >= a2 THEN PtInteriorOfAngleTF = -1
  55.     ELSE
  56.         IF ap >= a1 AND ap <= a2 THEN PtInteriorOfAngleTF = -1
  57.     END IF
  58.  
  59.     IF ap >= a1 AND ap <= a2 THEN PtInteriorOfAngleTF = -1 ' is inside or on the 2 arm angles
  60.     PRINT a1, a2, ap, PtInteriorOfAngleTF
  61.  
  62. FUNCTION atan360 (ra) 'convert radian angle from _ATAN2()  to guaranteed positive angle
  63.     atan360 = _R2D(ra + _PI(2)): IF atan360 > 359.9999 THEN atan360 = atan360 - 360
  64.  
  65.  

 
Title: Re: Harder-than-it-looks math problem
Post by: bplus on June 20, 2020, 01:02:47 am
Yep! Ashish has a winner!

Here is a tighter translation:
Code: QB64: [Select]
  1. _TITLE "Translate Ashish Interior Triangle to less code"
  2. SCREEN _NEWIMAGE(600, 600, 32)
  3. red~& = _RGB(255, 0, 0): white~& = _RGB32(255)
  4. 1 x1 = INT(RND * 600): y1 = INT(RND * 600): x2 = INT(RND * 600): y2 = INT(RND * 600): x3 = INT(RND * 600): y3 = INT(RND * 600)
  5.     k$ = INKEY$
  6.     CLS
  7.     IF k$ = " " THEN GOTO 1
  8.     mx = _MOUSEX: my = _MOUSEY
  9.     IF insideTriangle(x1, y1, x2, y2, x3, y3, mx, my) THEN COLOR red~& ELSE COLOR white~&
  10.     LINE (x1, y1)-(x2, y2): LINE (x2, y2)-(x3, y3): LINE (x3, y3)-(x1, y1)
  11.     _DISPLAY
  12.     _LIMIT 60
  13. FUNCTION insideTriangle (x1, y1, x2, y2, x3, y3, px, py)
  14.     area& = triangleArea(x1, y1, x2, y2, px, py) + triangleArea(x1, y1, px, py, x3, y3) + triangleArea(px, py, x2, y2, x3, y3)
  15.     insideTriangle = (ABS(triangleArea(x1, y1, x2, y2, x3, y3) - area&) <= 3)
  16. FUNCTION triangleArea& (x1, y1, x2, y2, x3, y3)
  17.     triangleArea& = 0.5 * ABS(x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2))
  18.  
Title: Re: Harder-than-it-looks math problem
Post by: Ashish on June 20, 2020, 02:24:19 am
@bplus you can reduce the lines even more! ;)
Title: Re: Harder-than-it-looks math problem
Post by: luke on June 20, 2020, 06:43:25 am
It looks like you can cut out those pesky constants, too:
Code: [Select]
FUNCTION insideTriangle (x1, y1, x2, y2, x3, y3, px, py)
    area& = triangleArea2(x1, y1, x2, y2, px, py) + triangleArea2(x1, y1, px, py, x3, y3) + triangleArea2(px, py, x2, y2, x3, y3)
    insideTriangle = area& <= triangleArea2(x1, y1, x2, y2, x3, y3)
END FUNCTION
FUNCTION triangleArea2& (x1, y1, x2, y2, x3, y3)
    triangleArea2& = ABS(x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2))
END FUNCTION
Title: Re: Harder-than-it-looks math problem
Post by: STxAxTIC on June 20, 2020, 07:15:16 am
To me that's just plain Geometry and no right hand rule in sight, LOL.

Still nope.

EDIT

Yeah blah blah blah the third vector is perpendicular to the originals and doesn't count anymore. That's not true. The right hand rule manifests in the 2D plane as a NEGATIVE SIGN. Right? Because if A and B are vectors, you should remember that:

A x B = - B x A

in any coordinates. The fact that the sign changes when you swap the arguments IS the right hand rule in two dimensions. Yes, you don't have to deal with the entire third dimension, but you're constant trying not to step in its shadow with those negative signs.

I see what you want to mean in all this, but the important thing is you see what I mean, lol.
Title: Re: Harder-than-it-looks math problem
Post by: bplus on June 20, 2020, 11:15:36 am
Still nope.

EDIT

Yeah blah blah blah the third vector is perpendicular to the originals and doesn't count anymore. That's not true. The right hand rule manifests in the 2D plane as a NEGATIVE SIGN. Right? Because if A and B are vectors, you should remember that:

A x B = - B x A

in any coordinates. The fact that the sign changes when you swap the arguments IS the right hand rule in two dimensions. Yes, you don't have to deal with the entire third dimension, but you're constant trying not to step in its shadow with those negative signs.

I see what you want to mean in all this, but the important thing is you see what I mean, lol.

I know you know vector math way better than I, thanks for showing it in simple enough form that even I could understand in 2D. :) 

Not using vector math, I never noticed having to swap signs. I do know if I use WINDOW and make y increase going up, all the trig calculations are fine without change and as the angle increases the direction reverses visually from clockwise to counter-clockwise, again with no change in math.

So you prefer to work with coordinate systems completely independent of the screen, your own world so to speak.
Man, I confess I couldn't easily come up with WINDOW coordinates that would just tilt a 2D plane with WINDOW statement.
Title: Re: Harder-than-it-looks math problem
Post by: STxAxTIC on June 20, 2020, 11:22:21 am
Yyyyyyikes, I hate the way I come off pretty much all the time. Thanks for hanging in there.

I thought you were just being extremely cheeky for its own sake, it didn't occur to me to make the argument as such until the end.
Title: Re: Harder-than-it-looks math problem
Post by: bplus on June 20, 2020, 11:46:18 am
Area of a Triangle says Luke:
Code: QB64: [Select]
  1. FUNCTION triangleArea2& (x1, y1, x2, y2, x3, y3)
  2.     triangleArea2& = ABS(x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2))
  3.  


Area of Triangle says Ashish:
Code: QB64: [Select]
  1. FUNCTION triangleArea& (x1, y1, x2, y2, x3, y3)
  2.     triangleArea& = 0.5 * ABS(x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2))
  3.  

I know with Ashish code above, it doesn't matter if area = .5 * (....   or 1000 * (... or _PI * (...
because you are using same calc to compare two areas but

I saved Ashish Area Triangle so I might use in other apps for real area in pixels and it might screw things up if I have wrong formula. So I guess I better test it. :) I think I have always used Hero's formula but you have to calc the 3 distances between points, so that will be judge.
Title: Re: Harder-than-it-looks math problem
Post by: bplus on June 20, 2020, 11:50:49 am
Yyyyyyikes, I hate the way I come off pretty much all the time. Thanks for hanging in there.

I thought you were just being extremely cheeky for its own sake, it didn't occur to me to make the argument as such until the end.

You are a working stiff still chasing after a paycheck, I am surprised you have time for any of this. I didn't when I was working. I tried and burned the candle at both ends and got crabby as hell and started interpreting people's intentions poorly, still not the greatest at that.

cheeky def: impudent or irreverent, typically in an endearing or amusing way.
Yeah OK, maybe some of that too :)
Title: Re: Harder-than-it-looks math problem
Post by: Qwerkey on June 20, 2020, 12:51:57 pm
cheeky def: impudent or irreverent, typically in an endearing or amusing way.
Every member here is tremendously endearing.
Title: Re: Harder-than-it-looks math problem
Post by: bplus on June 20, 2020, 01:36:03 pm
And Ashish formula for Area of Triangle was accurate even with triangles crossing over the axii:

Code: QB64: [Select]
  1. _TITLE "Area of a triangle : spacebar for next triangle, q to quit" 'b+ 2020-06-20
  2.  
  3. 'compare the functions and you might guess why I might prefer AshishArea for Area of a triangle given 3 points.
  4. ' But does it work in all cases of triangle coordinates? Yes!
  5.  
  6. ' I will use WINDOW to test cross axis triangles to see if negative and positive coordinates effect accuracy or break function.
  7.  
  8. SCREEN _NEWIMAGE(601, 601, 32)
  9. WINDOW (-100, 100)-(100, -100) 'cheeky, sarcastic, fun loving > our beloved mathematically correct graph
  10.  
  11. 1 x1 = RND * 200 - 100: y1 = RND * 200 - 100: x2 = RND * 200 - 100
  12. y2 = RND * 200 - 100: x3 = RND * 200 - 100: y3 = RND * 200 - 100
  13.     CLS
  14.     plus100
  15.     PRINT "("; x1 \ 1; ","; y1 \ 1; "), ("; x2 \ 1; ","; y2 \ 1; "), ("; x3 \ 1; ","; y3 \ 1; ")"
  16.     PRINT HeroArea(x1, y1, x2, y2, x3, y3), AshishArea(x1, y1, x2, y2, x3, y3)
  17.     LINE (x1, y1)-(x2, y2): LINE (x2, y2)-(x3, y3): LINE (x3, y3)-(x1, y1)
  18.     _DISPLAY
  19.     _LIMIT 30
  20.     k$ = INKEY$
  21.     IF k$ = "q" THEN SYSTEM
  22.     IF k$ = " " THEN GOTO 1
  23.  
  24. FUNCTION HeroArea (x1, y1, x2, y2, x3, y3)
  25.     a = _HYPOT(x1 - x2, y1 - y2)
  26.     b = _HYPOT(x2 - x3, y2 - y3)
  27.     c = _HYPOT(x3 - x1, y3 - y1)
  28.     s = (a + b + c) / 2
  29.     HeroArea = SQR(s * (s - a) * (s - b) * (s - c))
  30.  
  31. FUNCTION AshishArea (x1, y1, x2, y2, x3, y3)
  32.     'this is a keeper thanks Ashish
  33.     'FUNCTION triangleArea& (x1, y1, x2, y2, x3, y3)
  34.     AshishArea = 0.5 * ABS(x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2))
  35.  
  36. SUB plus100 'for bplus new standard math graph
  37.     FOR i = -100 TO 100: PSET (0, i): PSET (i, 0): NEXT
  38.  

and can we see enough WINDOW graphs and get enough practice with it? (dang cheeky again)

SCREEN _NEWIMAGE(601, 601, 32)  601??? maybe 600 x 600 will be OK

I had a hard time staying in bounds for this:
1 x1 = RND * 200 - 100: y1 = RND * 200 - 100: x2 = RND * 200 - 100
y2 = RND * 200 - 100: x3 = RND * 200 - 100: y3 = RND * 200 - 100

I was messing around with 201's because that is pixels across but dump INT() of x, y's and no fiddle with 1 less when mult by RND so 200 is fine. (Just some notes about using WINDOW, maybe only to myself.)

Maybe after getting use to origin in the middle, I will be ready to take on drawing vectors.