w00t for [language] drop down box! TY IanM! (and whoever coded it in. I think IanM but it might be someone else xD)
[edit] THANKS PAUL JOHNSTON! [/edit]
Anyways, uhh this is a simple transformation to comprehend, but I don't think I can explain it, without describing math more complicated than what I'm actually doing. Basically, take this image:
Say you have two points, P1 and P2. These are the endpoints of the red line in (1). You want a transformation that will transform the unit segment (0,0) to (0,1), into our line P1 to P2. This transformation does that. In addition, it transforms segments off the line, by scaling and rotating them, as one would think it should*.
*meaning it preserves ratios of lengths between any two sets of points, and angles between any two points - it is not a reflection.
(2) is a more complicated example, but as you can see, it's not all that complicated. You just stretch the white line segment!
This transformation can be given by the following matrix equation, where (x,y) is a point on the white curve, and A and B are the endpoints of the red line (we're talking column vectors here). P' is the transformed point.
in code (all multiplied out, no matrices)
ret.x=pt.x*(b.x-a.x)-pt.y*(b.y-a.y)+a.x
ret.y=pt.y*(b.x-a.x)+pt.x*(b.y-a.y)+a.y
That odd x,-y matrix comes from a CCW rotation matrix of 90 degrees, which is [[0,-1][1,0]]. I'm adding X units up the parametric line from P1 to P2, and Y units up the parametric line from P1 to P2 rotated 90 degrees. The weird term (why x and y are all mashed up in there) is there because I factored stuff out, so I had (x*I+y*R), where I is an identity matrix, and R is the aforementioned rotation matrix.
Without further adieu, I give you an implementation of this transformation, with the squiggle seen in image (2). Vanilla DBPro, no plugins needed.
`%Project Title%
`%Source File Name%
`======================
type vec2
x as float
y as float
endtype
global centerX `graph center, in pixels
global centerY
global scWidth `screen dimensions, in pixels
global scHeight
global PPU `pixels per unit
scWidth=screen width()
scHeight=screen height()
centerX=scWidth/2
centerY=scHeight/2
PPU=100
global ret as vec2
dim mySequence(9) as vec2
mySequence(0).x=0
mySequence(9).x=1
for n=1 to 4
mySequence(n*2).x=n/5.0
mySequence(n*2-1).x=n/5.0
next n
for n=0 to 4
v#=sin(n*90)*.2
mySequence(n*2).y=v#
mySequence(n*2+1).y=v#
next n
`makes a "mySequence" that looks like:
` _
`_| |_ _
` |_|
`coded so weirdly because I didn't want to have 20 lines of BLAH =some lame boring value
P1 as vec2
P2 as vec2
lastP as vec2
temp as vec2
P1.x=-.5
P1.y=.5
P2.x=1
P2.y=2
do
cls
if mouseclick()=1
pix_to_units(mousex(),mousey())
P1=ret
else
if mouseclick()=2
pix_to_units(mousex(),mousey())
P2=ret
endif
endif
temp.x=0
temp.y=0
ret.x=1
ret.y=0
`draw untransformed "mySequence"
lastP=mySequence(0)
for n=1 to array count(mySequence())
temp=mySequence(n)
drawLine(lastP,temp,rgb(255,255,255))
lastP=temp
next n
`draw transformed "mySequence"
temp=mySequence(0)
transformPointToSegment(temp,P1,P2)
lastP=ret
for n=1 to array count(mySequence())
temp=mySequence(n)
transformPointToSegment(temp,P1,P2)
temp=ret
drawLine(lastP,temp,rgb(255,0,0))
lastP=temp
next n
`remend
sync
loop
function drawLine(A as vec2, B as vec2, color as dword)
units_to_pix(A.x,A.y)
x1=ret.x
y1=ret.y
units_to_pix(B.x,B.y)
x2=ret.x
y2=ret.y
ink color,color
line x1,y1,x2,y2
endfunction
function pix_to_units(x,y)
ret.x=(x-centerX)*1.0/PPU
ret.y=-(y-centerY)*1.0/PPU
endfunction
function units_to_pix(x as float, y as float)
ret.x=x*PPU+centerX
ret.y=-y*PPU+centerY
endfunction
function transformPointToSegment(pt as vec2, a as vec2, b as vec2)
`where R is a rotation matrix giving a rotation 90 degrees CCW, and A, B, and P are column vectors
`P'=(B-A)*P.x+R*(B-A)*p.y+A
`this transformation scales (P-B) and (P-A) by a factor of ||B-A||, and rotates P by atan2(B-A)
`easier expressed in matrix form by:
` [P.x -P.y]
`P=[P.y P.x]*(B-A) + A
ret.x=pt.x*(b.x-a.x)-pt.y*(b.y-a.y)+a.x
ret.y=pt.y*(b.x-a.x)+pt.x*(b.y-a.y)+a.y
endfunction
Tell me if there's a broken link to images in a thread I post, and I'll fix 'em.