[GRAPHICS] WarpBlt >> How to Draw A Quad to a Quad?...

Yoshiki Ohshima ohshima at is.titech.ac.jp
Sun Feb 11 23:54:40 UTC 2001


  Hello Ali,

  I thought similar thing when I was writing the
FisheyeMorph and actually posted the similar question to the
list while ago.  And I got a reply from Bob Arning.
Attached is his reply.

  I agree that it would be nice to have a generic 2D-2D
transformation, but the texture map feature of Balloon 3D
might be applicable for your purpose.  Put a Form as a
texture to a plane and get the rendered Form.  I once wrote
a "moving sphere screen saver" in this way...

  Hope this helps,

  -- Yoshiki

-------------------------------------------------------------
Subject: Warping rects to quads (was: [GOODIE] FishEyeMorph)
From: Bob Arning <arning at charm.net>
To: squeak at cs.uiuc.edu
Date: Thu, 16 Dec 1999 12:40:21 -0500 (EST)

Hi Yoshiki,

This one got my interest. After trying to analytically compute the reverse transformation, I gave up and tried something simpler: run the normal quad-to-rectangle code, but copy the bits in the other direction. Sample code is included below. There are some simplifications here that warrant further attention:

1. To make the minimal change, the notion of source and dest are reversed. It's ugly, but simple.
2. Again, in the interest of simplicity, I did not implement the smoothing part.
3. Smoothing is important in another regard since the algorithm as written steps through each pixel (once) in the rectangular form in order to put pixels into the arbitrary quad form. If the rectangular form is a good bit larger than the quad form, this works reasonably well, but if the situation is reversed, holes will appear in the quad form. Possible fixes: magnify the rectangular form yourself beforehand, step in sub-pixel increments or rewrite the algorithm altogether.
4. It is not a primitive, so it's not real fast.

Cheers,
Bob

======
'From Squeak2.7alpha of 9 November 1999 [latest update: #1716] on 16 December 1999 at 12:25:36 pm'!

!WarpBlt methodsFor: 'primitives' stamp: 'RAA 12/16/1999 12:16'!
warpBackwards
	| deltaP12 deltaP43 pA pB deltaPAB sp fixedPtOne picker poker nSteps |

	(width < 1) | (height < 1) ifTrue: [^ self].
	fixedPtOne _ 16384.  "1.0 in fixed-pt representation"

	nSteps _ height-1 max: 1.
	deltaP12 _ (self deltaFrom: p1x to: p2x nSteps: nSteps)
			@ (self deltaFrom: p1y to: p2y nSteps: nSteps).
	pA _ (self startFrom: p1x to: p2x offset: nSteps*deltaP12 x)
		@ (self startFrom: p1y to: p2y offset: nSteps*deltaP12 y).
	deltaP43 _ (self deltaFrom: p4x to: p3x nSteps: nSteps)
			@ (self deltaFrom: p4y to: p3y nSteps: nSteps).
	pB _ (self startFrom: p4x to: p3x offset: nSteps*deltaP43 x)
		@ (self startFrom: p4y to: p3y offset: nSteps*deltaP43 y).

	picker _ BitBlt bitPeekerFromForm: destForm.		"ugly"
	poker _ BitBlt bitPokerToForm: sourceForm .
	poker clipRect: sourceForm boundingBox.
	nSteps _ width-1 max: 1.
	destY to: destY+height-1 do: [:y |
		deltaPAB _ (self deltaFrom: pA x to: pB x nSteps: nSteps)
				@ (self deltaFrom: pA y to: pB y nSteps: nSteps).
		sp _ (self startFrom: pA x to: pB x offset: nSteps*deltaPAB x)
			@ (self startFrom: pA y to: pB y offset: nSteps*deltaPAB y).
		destX to: destX+width-1 do: [:x | 
			poker pixelAt: sp // fixedPtOne asPoint put: (picker pixelAt: x at y).
			sp _ sp + deltaPAB.
		].
		pA _ pA + deltaP12.
		pB _ pB + deltaP43.
	].! !


!WarpBlt class methodsFor: 'examples' stamp: 'RAA 12/16/1999 12:25'!
warpToQuad
"An experiment in warping FROM a rectangle TO a quad"

 "Here is an example: there is a Form whose bounding box is
(0 at 0 corner: 10 at 10), and I'd like to transform it onto a
quad specified as {0 at 0. 2 at 12. 7 at 8. 16 at -6}.  It's ok the
edges are distorted (inward) by WarpBlt but I want the
original corners to be transformed onto the corners of the
resulting quad."
"WarpBlt warpToQuad"

	| sourceForm destQuad destRect destForm |

	sourceForm _ Color colorRampForDepth: 32 extent: 256 at 80.
	destQuad _ {0 at 0. 2 at 12. 7 at 8. 16 at -6}.
	destRect _ destQuad min corner: destQuad max.
	(destForm _ Form extent: destRect extent depth: 32) fillColor: Color white.
	(self toForm: sourceForm)
		sourceForm: destForm;
		combinationRule: Form over;
		sourceQuad: (destQuad collect: [ :pt | pt - destRect topLeft]) 
		destRect: sourceForm boundingBox;
		warpBackwards.
	destForm bitEdit.

	
 ! !



======

On Thu, 16 Dec 1999 02:35:08 +0900 ohshima at is.titech.ac.jp wrote:
>  However, there are many other classes of the distorted
>views, including "polar fish eye", "polyfocal (close to the
>'science' screen saver of Windows)", etc.  Even I could
>include "Perspective Wall" among them.
>
>  In order to implement those views, it must be able to
>transform square Forms (or rectangle, more generally) onto
>arbitrary quadrilaterals.  The limitation of WarpBlt is it
>cannot perform such a kind of transformation. (At least my
>mathematics ability doesn't let me to do so).
>
>  I think such graphics primitive is very handy and more
>general than WarpBlt.
>
>  By the way, if I want to implement the approximation of
>those transformation by using WarpBlt, does anyone have idea
>how I can figure out the sourceQuad?
>
>  Here is an example: there is a Form whose bounding box is
>(0 at 0 corner: 10 at 10), and I'd like to transform it onto a
>quad specified as "{0 at 0. 2 at 12. 7 at 8. 16 at -6}".  It's ok the
>edges are distorted (inward) by WarpBlt but I want the
>original corners to be transformed onto the corners of the
>resulting quad.


-------------------------------------------------------------





More information about the Squeak-dev mailing list