GraphicsPath Warp Methods

void Warp(PointF[] aptfDst, RectangleF rectfSrc)

void Warp(PointF[] aptfDst, RectangleF rectfSrc, Matrix matrix)

void Warp(PointF[] aptfDst, RectangleF rectfSrc, Matrix matrix,

WarpMode wm)

void Warp(PointF[] aptfDst, RectangleF rectfSrc, Matrix matrix,

WarpMode wm, float fFlatness)

You can optionally also supply a Matrix object and a flatness value. The source points are transformed to the destination points like this:

■ aptfDst[0] is the destination of the upper left corner of the rectangle.

■ aptfDst[1] is the destination of the upper right corner of the rectangle.

■ aptfDst[2] is the destination of the lower left corner of the rectangle.

■ aptfDst[3] is the destination of the lower right corner of the rectangle.

An optional argument determines how intermediary points are calculated:

WarpMode Enumeration

Member

Value

Perspective

0

Bilinear

1

The PathWarping program lets you experiment with the Warp function. The form's constructor creates a path with a square 8-by-8 checkerboard pattern. You then use the mouse to indicate the destination of this path.

PathWarping.cs

// PathWarping.es ® 2001 by Charles Petzold //------------------------------------------

using System;

using System.Drawing;

using System.Drawing.DrawingîD;

using System.Windows.Forms;

elass PathWarping: Form {

Menultem miWarpMode;

GraphiesPath path;

PointF[] aptfDest = new PointF[4];

publie statie void Main() {

Applieation.Run(new PathWarpingO);

publie PathWarpingO {

Text = "Path Warping";

// Create menu. Menu = new MainMenuO; Menu.Menultems.Add("&Warp Mode");

EventHandler ehCliek = new EventHandler(MenuWarpModeOnCliek);

miWarpMode = new MenuItem("&" + (WarpMode)O, ehCliek); miWarpMode.RadioCheek = true; miWarpMode.Cheeked = true;

Menu.Menultems[0].MenuItems.Add(miWarpMode);

Menultem mi = new Menultem("&" + (WarpMode)l, ehCliek); mi.RadioCheck = true;

Menu.MenuItems[0].MenuItems.Add(mi);

path.StartFigure();

path.AddL ine(0, 100 * i, 800, 100 * i); path.StartFigure();

// Initialize Point array.

aptfDest[0] = new Point( 50, 50); aptfDest[1] = new Point(200, 50); aptfDest[2] = new Point( 50, 200); aptfDest[3] = new Point(200, 200);

void MenuWarpModeOnClick(object obj, EventArgs ea) {

miWarpMode.Checked = false; miWarpMode = (Menultem) obj; miWarpMode.Checked = true;

Invalidate();

protected override void OnMouseDown(MouseEventArgs mea) {

Point pt;

if (mea.Button == MouseButtons.Left) {

if (ModifierKeys == Keys.None)

pt = Point.Round(aptfDest[0]); else if (ModifierKeys == Keys.Shift) pt = Point.Round(aptfDest[2]);

else return;

else if (mea.Button == MouseButtons.Right) {

if (ModifierKeys == Keys.None)

pt = Point.Round(aptfDest[l]); else if (ModifierKeys == Keys.Shift) pt = Point.Round(aptfDest[3]);

else return;

else return;

Cursor.Position = PointToScreen(pt);

protected override void OnMouseMove(MouseEventArgs mea) {

if (mea.Button == MouseButtons.Left) {

if (ModifierKeys == Keys.None)

aptfDest[0] = pt; else if (ModifierKeys == Keys.Shift) aptfDest[2] = pt;

else return;

else if (mea.Button == MouseButtons.Right) {

if (ModifierKeys == Keys.None)

aptfDest[l] = pt; else if (ModifierKeys == Keys.Shift) aptfDest[3] = pt;

else return;

else return; Invalidate();

protected override void OnPaint(PaintEventArgs pea) {

Graphics grfx = pea.Graphics;

GraphicsPath pathWarped = (GraphicsPath) path.Clone(); WarpMode wm = (WarpMode) miWarpMode.Index;

pathWarped.Warp(aptfDest, path.GetBounds(), new Matrix(), wm)

grfx.DrawPath(new Pen(ForeColor), pathWarped);

Use the left and right mouse buttons to set the upper left and upper right destination coordinates. Use the left and right mouse buttons with the Shift key pressed to set the lower left and lower right destination coordinates. Use the menu to select between Perspective and Bilinear modes. (And notice the clever way in which the OnPaint method casts the Index property of the clicked menu item to a member of type WarpMode.) Here's an example of a Perspective warp:

Graphicspath Warp

The path provides a convenient way for you to implement your own nonlinear transforms. You first store the figure you want to display in a path. You then access the PathPoints and PathTypes properties of the path to obtain all the coordinate points. Modify these points in whatever way you want, and then use one of the nondefault GraphicsPath constructors to create a new path based on the modified arrays. I have two examples of this technique in Chapter 19.

0 0

Post a comment

  • Receive news updates via email from this site