⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unit1.pas

📁 code for d bezier curve
💻 PAS
📖 第 1 页 / 共 4 页
字号:
//------------------------------------------------------------------------
//
// Author      : Maarten Kronberger
// Email       : Maartenk@tinderbox.co.za
// Website     : http://www.sulaco.co.za
//               http://www.tinderbox.co.za
// Date        : 6 October 2002
// Version     : 1.0
// Description : Bezier Curve Generator/Creator
//
// Special thanks to Digiben and the guys at www.gametutorials.com for the
// bezier curve source. :D
//------------------------------------------------------------------------

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, OpenGL,
  ExtCtrls, StdCtrls, ComCtrls, Menus,Math;

type
  TCoord = Record
    X, Y, Z : glFLoat;
  end;
  TForm1 = class(TForm)
    Panel1: TPanel;
    Panel2: TPanel;
    Button1: TButton;
    GroupBox3: TGroupBox;
    GroupBox4: TGroupBox;
    GroupBox2: TGroupBox;
    GroupBox1: TGroupBox;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    txtPoint1X: TEdit;
    txtPoint1Y: TEdit;
    txtPoint1Z: TEdit;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    txtPoint2Z: TEdit;
    txtPoint2Y: TEdit;
    txtPoint2X: TEdit;
    Label7: TLabel;
    Label8: TLabel;
    Label9: TLabel;
    txtPoint3Z: TEdit;
    txtPoint3Y: TEdit;
    txtPoint3X: TEdit;
    Label10: TLabel;
    Label11: TLabel;
    Label12: TLabel;
    txtPoint4Z: TEdit;
    txtPoint4Y: TEdit;
    txtPoint4X: TEdit;
    Button2: TButton;
    UpDown1: TUpDown;
    UpDown2: TUpDown;
    UpDown3: TUpDown;
    UpDown4: TUpDown;
    UpDown5: TUpDown;
    UpDown6: TUpDown;
    UpDown7: TUpDown;
    UpDown8: TUpDown;
    UpDown9: TUpDown;
    UpDown10: TUpDown;
    UpDown11: TUpDown;
    UpDown12: TUpDown;
    Button3: TButton;
    Button4: TButton;
    chkAllBeziers: TCheckBox;
    TTabControl1: TTabControl;
    Button5: TButton;
    Button6: TButton;
    chkRotate: TCheckBox;
    MainMenu1: TMainMenu;
    File1: TMenuItem;
    Save1: TMenuItem;
    View1: TMenuItem;
    ShowStart1: TMenuItem;
    Rotate1: TMenuItem;
    ShowAllCurves1: TMenuItem;
    SaveControlPoints1: TMenuItem;
    Timer1: TTimer;
    Timer2: TTimer;
    SaveDialog1: TSaveDialog;
    OpenDialog1: TOpenDialog;
    OpenControlPointFile1: TMenuItem;
    New1: TMenuItem;
    Help1: TMenuItem;
    About1: TMenuItem;
    procedure FormCreate(Sender: TObject);
    procedure Panel1Resize(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormKeyPress(Sender: TObject; var Key: Char);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure UpDown1Click(Sender: TObject; Button: TUDBtnType);
    procedure UpDown2Click(Sender: TObject; Button: TUDBtnType);
    procedure UpDown3Click(Sender: TObject; Button: TUDBtnType);
    procedure UpDown4Click(Sender: TObject; Button: TUDBtnType);
    procedure UpDown5Click(Sender: TObject; Button: TUDBtnType);
    procedure UpDown6Click(Sender: TObject; Button: TUDBtnType);
    procedure UpDown7Click(Sender: TObject; Button: TUDBtnType);
    procedure UpDown8Click(Sender: TObject; Button: TUDBtnType);
    procedure UpDown9Click(Sender: TObject; Button: TUDBtnType);
    procedure UpDown10Click(Sender: TObject; Button: TUDBtnType);
    procedure UpDown11Click(Sender: TObject; Button: TUDBtnType);
    procedure UpDown12Click(Sender: TObject; Button: TUDBtnType);
    procedure Button3Click(Sender: TObject);
    procedure GroupBox4Click(Sender: TObject);
    procedure GroupBox3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure ShowStart1Click(Sender: TObject);
    procedure Rotate1Click(Sender: TObject);
    procedure ShowAllCurves1Click(Sender: TObject);
    procedure Save1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure Panel1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Panel1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Timer2Timer(Sender: TObject);
    procedure Button5MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Button6MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Button6MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Button5MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure SaveControlPoints1Click(Sender: TObject);
    procedure OpenControlPointFile1Click(Sender: TObject);
    procedure txtPoint1XEnter(Sender: TObject);
    procedure txtPoint1XExit(Sender: TObject);
    procedure txtPoint1YEnter(Sender: TObject);
    procedure txtPoint1YExit(Sender: TObject);
    procedure txtPoint1ZEnter(Sender: TObject);
    procedure txtPoint1ZExit(Sender: TObject);
    procedure txtPoint2XEnter(Sender: TObject);
    procedure txtPoint2XExit(Sender: TObject);
    procedure txtPoint2YEnter(Sender: TObject);
    procedure txtPoint2YExit(Sender: TObject);
    procedure txtPoint2ZEnter(Sender: TObject);
    procedure txtPoint2ZExit(Sender: TObject);
    procedure txtPoint3XEnter(Sender: TObject);
    procedure txtPoint3XExit(Sender: TObject);
    procedure txtPoint3YEnter(Sender: TObject);
    procedure txtPoint3YExit(Sender: TObject);
    procedure txtPoint3ZEnter(Sender: TObject);
    procedure txtPoint3ZExit(Sender: TObject);
    procedure txtPoint4XEnter(Sender: TObject);
    procedure txtPoint4XExit(Sender: TObject);
    procedure txtPoint4YEnter(Sender: TObject);
    procedure txtPoint4YExit(Sender: TObject);
    procedure txtPoint4ZEnter(Sender: TObject);
    procedure txtPoint4ZExit(Sender: TObject);
    procedure New1Click(Sender: TObject);
    procedure About1Click(Sender: TObject);
  private
    { Private declarations }
    rc : HGLRC;    // Rendering Context
    dc  : HDC;     // Device Context
    ElapsedTime, AppStart, LastTime : DWord;  // Timing variables

    g_CurrentTime : GLfloat;  // This is the current position of the sphere along the curve (0 to 1)



    procedure glDraw;
    procedure Idle(Sender: TObject; var Done: Boolean);
    procedure glInit;
    procedure SetArrayLength;
    procedure UpdateTextValues;
    procedure SetTempValue(txtBox : TEdit);
    procedure SetCoordValue(txtBox : TEdit);
    procedure DoUpDown(txtBox : TEdit;Button: TUDBtnType);
    procedure UpdatePointValues();
  public
    { Public declarations }
  end;
const
  MAX_STEPS = 38.0;
  BALL_SPEED = 0.02;
var
  Form1: TForm1;
  g_CurrentTime : GLfloat;


  rotateY : GLfloat;

  g_arrvStartPoint : array of TCoord; // Starting point of the curve
  g_arrvControlPoint1 : array of TCoord; // First control point of the curve
  g_arrvControlPoint2 : array of TCoord; // Second control point of the curve
  g_arrvEndPoint : array of TCoord; // End point of the curve

  g_arrIndex : integer;

  zView : GLfloat;

  g_ControlPoint1Color : glFloat;
  g_ControlPoint2Color : glFloat;

  zViewModifier : glFloat;

  g_tempVar : glFloat;

implementation

{$R *.DFM}

Uses Unit2;


{------------------------------------------------------------------------}
{  This function renders a sphere to a given XYZ and with a given radius }
{------------------------------------------------------------------------}

procedure DrawSphere(x, y, z, radius : GLfloat);
var pSphere : GLUquadricObj;
begin
	// To use Quadrics, we need to create a new one first.  This is done below.
	// The GLUquadricObj type is defined with the GLU32 library and associated header file.

	pSphere := gluNewQuadric();			// Get a Quadric off the stack

	// Let's put on a matrix so what ever we do it doesn't effect the rest of
	// the objects we will display.

	glPushMatrix();										// Push on a new matrix

		glTranslatef(x, y, z);							// Move the sphere to the desired (x, y, z)

		// Draw the a sphere with a given radius and a width and height detail 
		// of 15 (15 by 15 is a good level of detail.  The lower the detail the 
		// more jagged the sphere becomes, where the high the detail the more round it is.
		gluSphere(pSphere, radius, 15, 15);				// Draw the sphere with a radius of 0.2

	glPopMatrix();										// Pop the current matrix

	// Since we are done rendering the Quadric, we can free the object.
	// gluDeleteQuadric() takes the object to be released. If you have a lot 
	// of Quadrics, you might not want to allocate and free them every frame.

	gluDeleteQuadric(pSphere);							// Free the quadric object
end;


{-----------------------------------------------------------------------------}
{	This function returns an XYZ point along the curve, depending on t (0 to 1) }
{-----------------------------------------------------------------------------}
function PointOnCurve(p1, p2, p3, p4: TCoord; t : GLfloat) : TCoord;
var var1, var2, var3 : glFloat;
    vPoint : TCoord;
begin
  vPoint.X := 0.0; vPoint.Y := 0.0; vPoint.Z := 0.0;

  {-----------------------------------------------------------------------------}
	{ Here is the juice of our tutorial.                                          }
  { Below is the equation for a 4 control point bezier curve:                   }
	{ B(t) = P1 * ( 1 - t )^3                                                     }
  {      + P2 * 3 * t * ( 1 - t )^2                                             }
  {      + P3 * 3 * t^2 * ( 1 - t )                                             }
  {      + P4 * t^3                                                             }
	{ Yes I agree, this isn't the most intuitive equation,                        }
  { but it is pretty straight forward.                                          }
	{ If you got up to Trig, you will notice that this is a polynomial.           }
  { That is what a curve is.                                                    }
	{ "t" is the time from 0 to 1.                                                }
  { You could also think of it as the distance along the curve,                 }
  { because that is really what it is.                                          }
  { P1 - P4 are the 4 control points.                                           }
	{ They each have an (x, y, z) associated with them.                           }
  { You notice that there is a lot of (1 - t) 's?                               }
  { Well, to clean up our code we will try to contain some of these             }
	{ repetitions into variables.                                                 }
  { This helps our repeated computations as well.                               }
  {-----------------------------------------------------------------------------}

	// Store the (1 - t) in a variable because it is used frequently
    var1 := 1 - t;

	// Store the (1 - t)^3 into a variable to cut down computation and create clean code
    var2 := var1 * var1 * var1;

	// Store the t^3 in a variable to cut down computation and create clean code
    var3 := t * t * t;

  {-----------------------------------------------------------------------------}
	{ Now that we have some computation cut down,                                 }
  { we just follow the equation above.                                          }
	{ If you multiply and simplify the equation,                                  }
  { you come up with what we have below.                                        }
	{ If you don't see how we came to here from the equation,                     }
  { multiply the equation out and it will become more clear.                    }
  { I don't intend to go into any more detail on the math of a bezier curve,    }
  { because there are far better places out there with graphical displays       }
  { and tons of examples.                                                       }
  { Look in our * Quick Notes * for an EXCELLENT web site that does just this.  }
  { It derives everything and has excellent visuals.                            }
  { It's the best I have seen so far.                                           }
  {-----------------------------------------------------------------------------}
  
    vPoint.x := var2*p1.x + 3*t*var1*var1*p2.x + 3*t*t*var1*p3.x + var3*p4.x;
    vPoint.y := var2*p1.y + 3*t*var1*var1*p2.y + 3*t*t*var1*p3.y + var3*p4.y;
    vPoint.z := var2*p1.z + 3*t*var1*var1*p2.z + 3*t*t*var1*p3.z + var3*p4.z;

	// Now we should have the point on the curve, so let's return it.
    result := vPoint;				
end;


{------------------------------------------------------------------}
{  Function to draw the actual scene                               }
{------------------------------------------------------------------}
procedure TForm1.glDraw();
var t : glFloat;
    vPoint : TCoord;
    I : integer;
begin


	glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);	// Clear The Screen And The Depth Buffer
	glLoadIdentity();									// Reset The matrix

  {-----------------------------------------------------------------------------}
	{ Below, we will draw a bezier curve with 4 control points                    }
	{ (including the start/end point).  We will use GL_LINES to draw the          }
	{ line segments of the curve.  Then, using Quadrics, we will draw a sphere    }
	{ on the curve.  You can use the LEFT and RIGHT arrow keys to move the        }
	{ sphere along the curve.  If you are not familiar with quadrics, you can     }
	{ view our quadric tutorial at www.GameTutorials.com.  I also include some    }
  { comments from the tutorial in here in case you just want the basics.        }
	{ Quadrics are used to create cylinders and spheres quickly and easily.       }
  {-----------------------------------------------------------------------------}

	// We set up our camera back a little bit to get the whole curve in view.

				// Position      View		Up Vector
	gluLookAt(0, 0.5, zView,   0, 0.5, 0,   0, 1, 0);	// Set up our camera position and view

	// Below we disable the lighting so you can clearly see the bezier curve.

	glDisable(GL_LIGHTING);								// Disable lighting for now

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -