Ugh. Is my math (and logic) right?
#1
Such a long time since I've done this kind of stuff, I don't have much confidence in my struggled result.

Is this the right way to draw a line with PSET ???

Code: (Select All)
SCREEN _NEWIMAGE(641, 201, 32)

SUB MyLine(x1%, y1%, x2%, y2%)
' y% = m# * x% + c#
    xd% = x2% - x1%
    yd% = y2% - y1%
    m# = yd%/xd%
    c# = y2% - x2% * m#
    IF xd% >= yd% THEN FOR i = x1% to x2%: PSET(i, m# * i + c#) : NEXT i
    IF xd% < yd%  THEN  FOR i = y1% to y2%: PSET((i - c#)/m#, i) : NEXT i
END SUB

FOR X = 0 TO 640 step 10
    MyLine(0,0,X,200)
NEXT X
FOR Y = 0 TO 200 step 5
    LINE (0,0)-(640, Y), _RGB(255,255,0)
NEXT X
Reply
#2
Why not just draw a line with LINE?
Reply
#3
(08-29-2023, 12:59 AM)SMcNeill Wrote: Why not just draw a line with LINE?

Because I'm working on something that doesn't work with LINE.  (Or with DRAW.)

That wee bit of code is just the first bit.
Reply
#4
Works for me after I make it right with QB64:
Code: (Select All)
Screen _NewImage(641, 201, 32)


For X = 0 To 640 Step 10
    MyLine 0, 0, X, 200
Next X
For Y = 0 To 200 Step 5
    Line (0, 0)-(640, Y), _RGB(255, 255, 0)
Next Y
Sub MyLine (x1%, y1%, x2%, y2%)
    ' y% = m# * x% + c#
    xd% = x2% - x1%
    yd% = y2% - y1%
    m# = yd% / xd%
    c# = y2% - x2% * m#
    If xd% >= yd% Then For i = x1% To x2%: PSet (i, m# * i + c#): Next i
    If xd% < yd% Then For i = y1% To y2%: PSet ((i - c#) / m#, i): Next i
End Sub

And faster than my method! Nice if it works for all x, y
b = b + ...
Reply
#5
Probably needs division by zero logic for horizontal and vertical lines.
Reply
#6
(08-29-2023, 01:12 AM)bplus Wrote: Works for me after I make it right with QB64:
Code: (Select All)
Screen _NewImage(641, 201, 32)


For X = 0 To 640 Step 10
    MyLine 0, 0, X, 200
Next X
For Y = 0 To 200 Step 5
    Line (0, 0)-(640, Y), _RGB(255, 255, 0)
Next Y
Sub MyLine (x1%, y1%, x2%, y2%)
    ' y% = m# * x% + c#
    xd% = x2% - x1%
    yd% = y2% - y1%
    m# = yd% / xd%
    c# = y2% - x2% * m#
    If xd% >= yd% Then For i = x1% To x2%: PSet (i, m# * i + c#): Next i
    If xd% < yd% Then For i = y1% To y2%: PSet ((i - c#) / m#, i): Next i
End Sub

And faster than my method! Nice if it works for all x, y

Ok, math seems to makes sens.  I was really unsure.

Now to tackle vertical and horizontal lines.
Reply
#7
Oh I hadn't setup my method correctly it's fast too comparing bLine to MyLine
Code: (Select All)
Screen _NewImage(800, 600, 32)
bLine 300, 30, 300, 500
bLine 300, 30, 500, 30
For X = 0 To 640 Step 10
    Color &HFFFF0000
    MyLine 0, 0, X, 200
Next X
For Y = 0 To 200 Step 5
    Color &HFF0000FF
    bLine 0, 0, 640, Y
Next Y

Sub bLine (x1, y1, x2, y2)
    dx = x2 - x1
    dy = y2 - y1
    dist = Sqr(dx * dx + dy * dy)
    dx = dx / dist
    dy = dy / dist
    For i = 0 To dist
        PSet (x1 + dx * i, y1 + dy * i)
    Next
End Sub
Sub MyLine (x1%, y1%, x2%, y2%)
    ' y% = m# * x% + c#
    xd% = x2% - x1%
    yd% = y2% - y1%
    m# = yd% / xd%
    c# = y2% - x2% * m#
    If xd% >= yd% Then For i = x1% To x2%: PSet (i, m# * i + c#): Next i
    If xd% < yd% Then For i = y1% To y2%: PSet ((i - c#) / m#, i): Next i
End Sub
b = b + ...
Reply
#8
(08-29-2023, 02:00 AM)bplus Wrote: Oh I hadn't setup my method correctly it's fast too comparing bLine to MyLine
Code: (Select All)
Screen _NewImage(800, 600, 32)
bLine 300, 30, 300, 500
bLine 300, 30, 500, 30
For X = 0 To 640 Step 10
    Color &HFFFF0000
    MyLine 0, 0, X, 200
Next X
For Y = 0 To 200 Step 5
    Color &HFF0000FF
    bLine 0, 0, 640, Y
Next Y

Sub bLine (x1, y1, x2, y2)
    dx = x2 - x1
    dy = y2 - y1
    dist = Sqr(dx * dx + dy * dy)
    dx = dx / dist
    dy = dy / dist
    For i = 0 To dist
        PSet (x1 + dx * i, y1 + dy * i)
    Next
End Sub
Sub MyLine (x1%, y1%, x2%, y2%)
    ' y% = m# * x% + c#
    xd% = x2% - x1%
    yd% = y2% - y1%
    m# = yd% / xd%
    c# = y2% - x2% * m#
    If xd% >= yd% Then For i = x1% To x2%: PSet (i, m# * i + c#): Next i
    If xd% < yd% Then For i = y1% To y2%: PSet ((i - c#) / m#, i): Next i
End Sub

I had started with something more like bline, but I was really not sure of myself, and went the other way.

I much prefer bline.  I will steal that.
Reply
#9
@bplus

Now I remember part of my concern with my first approach: distance of the line between two points yielding decimal values that cause loss of a pixel at the end of a line.

Here's what I'm getting (white lines being MyLine(), yellow lines being bline:

   
Reply
#10
And the instant I posted that last one, wait a minute ...

Problem solved with a little security (last two lines added to bLine):

Code: (Select All)
Sub bLine (x1, y1, x2, y2)
    dx = x2 - x1
    dy = y2 - y1
    dist = Sqr(dx * dx + dy * dy)
    dx = dx / dist
    dy = dy / dist
    For i = 0 To dist
        PSet (x1 + dx * i, y1 + dy * i)
    Next
    Pset (x1,y1)
    Pset (x2,y2)
End Sub
Reply




Users browsing this thread: 2 Guest(s)