Might as well ask first... :)
BlitzPlus Forums/BlitzPlus Programming/Might as well ask first... :)
| ||
Does anyone have code that'll map an image onto a (2D) quad with arbitrarily positioned corner points?1, 2, 3, 4 -- corners 1-------------------2 | | | | | Original | | | | | 3-------------------4 1 2 Remapped 4 3 ... so in the remapped version it'll have the image appropriately stretched/scaled, etc, between the points? I'm going to attempt it, but I think it's actually a lot harder than it looks (for me, anyway), so it'd obviously be handy if someone's already done it :) |
| ||
Have you tried tformimage |
| ||
James, I think I have some code to do this from long ago. If I find it I'll put it in the code archive. (starfox - tformimage isn't going to do any good) |
| ||
I think that old 3d engine by PRJ might be worth a look. |
| ||
This will make you appreciate 3d hardware. Of course, your rectangle and quad can each be considered as two triangles. So the real problem is mapping triangle to triangle. Theoretically, this would be easy. There is just one linear transformation ( 3x3 matrix ) which maps the corresponding vertices. So you apply this to the entire source triangle and you are done! But in the approximate world of limited number of pixels it gets a lot tougher. You have to estimate values with bilinear filtering or something similar. |
| ||
In case you want to go with 3D my SpriteControl uses quads like so:v0---v1 | /| | / | | / | |/ | v2---v3 Quick example: ; Sprite Control - Quad manipulation Include "Sprite Control.bb" Graphics3D 640,480 SetBuffer BackBuffer() ClearTextureFilters cam=CreateCamera() Spritecamera cam testsprite=LoadImage3D("checker.jpg") copy=LoadImage3D("checker.jpg") ; move corners s=GetSurface(testsprite,1) VertexCoords s,0,VertexX(s,0)+0.2,VertexY(s,0)+0.4,VertexZ(s,0) VertexCoords s,1,VertexX(s,1)-0.7,VertexY(s,1)-0.2,VertexZ(s,1) VertexCoords s,2,VertexX(s,2)-0.3,VertexY(s,2)-0.1,VertexZ(s,2) VertexCoords s,3,VertexX(s,3)-0.1,VertexY(s,3)+0.1,VertexZ(s,3) DrawImage3D copy,150,220 DrawImage3D testsprite,462,220 RenderWorld Flip WaitKey() End Result (BEFORE / AFTER) ![]() |
| ||
Thanks Syntax, but I definitely want 2D here! DJ: Good point -- I'll take a look (though I'm guessing it will be too complex for me!). Floyd: ">> There is just one linear transformation ( 3x3 matrix )" -- stop right there! Ouch... though I guess this is related to Starfox's suggestion (never quite grasped TFormImage, though the example I have seems to just show resize/scale operations)...? Master: if you do have that code, please pass it over... :) |
| ||
James, I wrote that off the top of my head. On second thought it gets even messier. The 'linear transformation' is multiplication by a 3x3 matrix ( thinking of it as 3d ). Multiplication always takes zero to zero. This means the origin can't be moved. That makes the problem even harder. In fact, this is why you see 'homogeneous coordinates' in 3d graphics. That's the the trick which replaces the 3d point (x,y,z) with the 4d point (x,y,z,1) and uses 4x4 matrices. The corresponding 2d trick replaces (x,y) with (x,y,1). The 3x3 matrix transforms these points, always maintaining this special form. It always takes a point (?,?,1) to another with the same form, i.e. z=1. So good luck with this. The best bet is probably to go looking for an existing library in C/C++. Actually, this is getting interesting. Maybe I'll put some real thought into it. |
| ||
never quite grasped TFormImage I had a good play with TFormImage. Have a look at the Online Docs |
| ||
James - here ya go. It's old and dirty, and I've simplified it so you can use it as a starting point. It doesn't do any fancy filtering, nor even resize the pixels, so there is still some work for you. :)Const top = 0, bottom = 1 AppTitle "Quad function demo" Graphics 640,480 Dim xp#(1, bottom) , yp#(1,bottom) Dim xdelta#(1), ydelta#(1) image = LoadImage ("cat.png") Global imagew = ImageWidth(image), imageh = ImageHeight(image) Dim imageRGB(ImageW-1,ImageH-1) Dim position(ImageW-1,ImageH-1) LockBuffer (ImageBuffer(image)) For x = 0 To imagew-1 For y = 0 To imageh-1 imageRGB(x,y) = ReadPixelFast(x,y, ImageBuffer(image)) And $FFFFFF position(x,y) = 0 Next Next UnlockBuffer(ImageBuffer(image)) Dim xp#(ImageW, bottom) Dim yp#(imagew, bottom) Dim xdelta#(imagew) Dim ydelta#(imagew) SetBuffer BackBuffer() angle = 0 MoveMouse width/2, height/2 Repeat angle = (angle + 3) Mod 360 cosang = Cos(angle)*100 sinang = Sin(angle)*100 quad (image, 130+sinang / 3,130+cosang / 3, 400+sinang / 2,90+cosang / 2, 460,260, MouseX(), MouseY()) Color 255,255,255 Text 5,460, "Quad Mapping by Beaker 2001" Flip:Cls Until KeyHit(1) End Function Quad (image, x0#,y0#, x1#,y1#, x2#,y2#, x3#,y3#) xpdtop# = (x1 - x0) / (imagew - 1) ypdtop# = (y1 - y0) / (imagew - 1) xpdbott# = (x2 - x3) / (imagew - 1) ypdbott# = (y2 - y3) / (imagew - 1) For x = 0 To ImageW xp(x,top) = x0 + (x * xpdtop) yp(x,top) = y0 + (x * ypdtop) xp(x,bottom) = x3 + (x * xpdbott) yp(x,bottom) = y3 + (x * ypdbott) Next For x = 0 To imagew xdelta(x) = ((xp(x,bottom) - xp(x,top)) / (imageh - 1)) ydelta(x) = ((yp(x,bottom) - yp(x,top)) / (imageh - 1)) Next For x = 0 To imagew - 1 For y = 0 To imageh - 1 If imageRGB(x,y) > 0 xadderTL = (xdelta(x) * y) position(x,y) = (xp(x,top) + (y * xdelta(x)) Shr 16) Or yp(x,top) + (y * ydelta(x)) Color imageRGB(x,y) Shr 16 And $ff, imageRGB(x,y) Shr 8 And $ff, imageRGB(x,y) And $ff Oval xp(x,top) + (y * xdelta(x)), yp(x,top) + (y * ydelta(x)), 6,6 EndIf Next Next End Function |
| ||
Ah, that's pretty much what I'm after, Beaks! Thanks, I'll take a good look at that. Also, good call, Syntax -- hadn't seen that TForm stuff, so I'll check that too. Thanks, all :) |
| ||
if you want a faster one then have a look on the "3D Engine" in the 2D Graphics Code Archives. It has a (linear) Texturemapper which is pretty quick. |
| ||
BTW MasterBeaker - that's a nice Function - but using Oval is slowing it really down. Also the Size can be smaller than 6*6. I used: Rect xp(x,top) + (y * xdelta(x)), yp(x,top) + (y * ydelta(x)), 3,3,1 and it still looked good, but it was much faster. Some minutes ago I realized the first time that non-opac Rect is MUCH slower than opac Rect!! (filled Rects are faster) So when you use Rect for 90 Degs Lines Optimation, eg: Rect 50,20,100,1 instead of Line 50,20,150,20 then you should always use the Opac Flag: Rect 50,20,100,1,1 Now this is about 100 times faster than the Line Function. |
| ||
Oval was only really used for demonstration of the function. I used 6x6 because the image I tested it with was very small. |
| ||
I've still to take a look at your code, Norc (going to do it now), but thanks to Syntax, I finally have some sort of grasp of TFormImage now! I actually think it should be able to do this for me, if I can just figure out the calculations needed to scale/warp to the exact offsets required... Just posting this cos I suddenly love TFormImage (all it does is scale the image :) ; Load an image smaller than the screen size! AppTitle "TFormImage..." Graphics 808, 600, 0, 2 SetBuffer BackBuffer () image = LoadImage ("F:\My Documents\My Pictures\02porschecayenne.jpg") ; TFormImage image, a, b, c, d ; a -- Position of right edge (1 = normal) ; b -- Shear of right edge (0 = no shear) ; c -- Shear of bottom edge (0 = no shear) ; d -- Position of bottom edge (1 = normal) TFormImage image, 1, 0, 0, 1 DrawImage image, 0, 0 Flip ;MouseWait MoveMouse ImageWidth (image), ImageHeight (image) TFormFilter False Repeat If (MouseXSpeed ()) Or (MouseYSpeed ()) Cls timage = CopyImage (image) If (MouseX () > 0) And (MouseY () > 0) TFormImage timage, Float (MouseX ()) / Float (ImageWidth (timage)), 0, 0, Float (MouseY ()) / Float (ImageHeight (timage)) DrawImage timage, 0, 0 EndIf FreeImage timage Flip EndIf Until KeyHit (1) End |
| ||
Check 3d.* @ http://www.stud.ntnu.no/~paulrene/blitzbasic/ |
| ||
Thanks Paul -- I actually found that not long after this thread was last alive (I leeched *all* of your site's Blitz stuff a couple of months ago because it rules!). In fact I was thinking about this again today, weirdly enough, because I never quite got it right, and I remembered your engine had a function that looked like it would take care of this for me! |