AsphyreTorusKnot.pas
上传用户:ctlcnc
上传日期:2021-12-10
资源大小:4933k
文件大小:5k
源码类别:

2D图形编程

开发平台:

Delphi

  1. unit AsphyreTorusKnot;
  2. //---------------------------------------------------------------------------
  3. // AsphyreTorusKnot.pas                                 Modified: 02-Apr-2007
  4. // Torus PQ Knot implementation for Asphyre                       Version 1.0
  5. //---------------------------------------------------------------------------
  6. // This code is based on the description at:
  7. //  http://www.blackpawn.com/texts/pqtorus/default.html
  8. //---------------------------------------------------------------------------
  9. // Important Notice:
  10. //
  11. // If you modify/use this code or one of its parts either in original or
  12. // modified form, you must comply with Mozilla Public License v1.1,
  13. // specifically section 3, "Distribution Obligations". Failure to do so will
  14. // result in the license breach, which will be resolved in the court.
  15. // Remember that violating author's rights is considered a serious crime in
  16. // many countries. Thank you!
  17. //
  18. // !! Please *read* Mozilla Public License 1.1 document located at:
  19. //  http://www.mozilla.org/MPL/
  20. //
  21. // If you require any clarifications about the license, feel free to contact
  22. // us or post your question on our forums at: http://www.afterwarp.net
  23. //---------------------------------------------------------------------------
  24. // The contents of this file are subject to the Mozilla Public License
  25. // Version 1.1 (the "License"); you may not use this file except in
  26. // compliance with the License. You may obtain a copy of the License at
  27. // http://www.mozilla.org/MPL/
  28. //
  29. // Software distributed under the License is distributed on an "AS IS"
  30. // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
  31. // License for the specific language governing rights and limitations
  32. // under the License.
  33. //
  34. // The Original Code is AsphyreTorusKnot.pas.
  35. //
  36. // The Initial Developer of the Original Code is M. Sc. Yuriy Kotsarenko.
  37. // Portions created by M. Sc. Yuriy Kotsarenko are Copyright (C) 2007,
  38. // M. Sc. Yuriy Kotsarenko. All Rights Reserved.
  39. //---------------------------------------------------------------------------
  40. interface
  41. //---------------------------------------------------------------------------
  42. uses
  43.  Windows, Math, Vectors2, Vectors3, AsphyreProceduralMeshes;
  44. //---------------------------------------------------------------------------
  45. type
  46.  TAsphyreTorusKnot = class(TAsphyreProceduralMesh)
  47.  private
  48.  public
  49.   function Generate(Radius, TubeRadius: Single; p, q: Integer; Rings,
  50.    Sides: Integer; TexTilesX, TexTilesY: Single): Boolean;
  51.  end;
  52. //---------------------------------------------------------------------------
  53. implementation
  54. //---------------------------------------------------------------------------
  55. function TAsphyreTorusKnot.Generate(Radius, TubeRadius: Single; p,
  56.  q: Integer; Rings, Sides: Integer; TexTilesX, TexTilesY: Single): Boolean;
  57. var
  58.  SideBlock: Integer;
  59.  i, j, ni, nj: Integer;
  60.  Phi, ThetaInc: Single;
  61.  Theta, PhiInc, Phi1, r: Single;
  62.  Vertex, Pos, Next, t, n, b: TVector3;
  63.  Point: TPoint2;
  64.  Normal: TVector3;
  65. begin
  66.  SideBlock:= Sides + 1;
  67.  Result:= CreateBuffers(Rings * Sides * 2, (Rings + 1) * SideBlock);
  68.  if (not Result) then Exit;
  69.  Result:= LockBuffers();
  70.  if (not Result) then Exit;
  71.  Phi:= 0.0;
  72.  PhiInc:= 2.0 * Pi / Rings;
  73.  ThetaInc:= 2.0 * Pi / Sides;
  74.  for j:= 0 to Rings{ - 1} do
  75.   begin
  76.    Theta:= 0.0;
  77.    r:= 0.5 * (2.0 + Sin(q * Phi)) * Radius;
  78.    Pos.x:= r * Cos(p * Phi);
  79.    Pos.y:= r * Cos(q * Phi);
  80.    Pos.z:= r * Sin(p * Phi);
  81.    Phi1:= Phi + PhiInc;
  82.    r:= 0.5 * (2.0 + Sin(q * Phi1)) * Radius;
  83.    Next.x:= r * Cos(p * Phi1);
  84.    Next.y:= r * Cos(q * Phi1);
  85.    Next.z:= r * Sin(p * Phi1);
  86.    t:= Next - Pos;
  87.    n:= Next + Pos;
  88.    b:= Norm3(Cross3(t, n));
  89.    n:= Norm3(Cross3(b, t));
  90.    for i:= 0 to Sides{ - 1} do
  91.     begin
  92.      Point.x:= Sin(Theta) * TubeRadius;
  93.      Point.y:= Cos(Theta) * TubeRadius;
  94.      Vertex:= Pos + (n * Point.x) + (b * Point.y);
  95.      Normal:= Norm3(Vertex - Pos);
  96.      IncludeVertex(Vertex, Normal,
  97.       Point2(Phi * TexTilesX / (2.0 * Pi), Theta * TexTilesY / (2.0 * Pi)));
  98. {     ni:= (i + 1) mod Sides;
  99.      nj:= (j + 1) mod Rings;}
  100.      ni:= i + 1;
  101.      nj:= j + 1;
  102.      if (i < Sides)and(j < Rings) then
  103.       begin
  104.        IncludeIndex(i + j * SideBlock);
  105.        IncludeIndex(i + nj * SideBlock);
  106.        IncludeIndex(ni + nj * SideBlock);
  107.        IncludeIndex(i + j * SideBlock);
  108.        IncludeIndex(ni + nj * SideBlock);
  109.        IncludeIndex(ni + j * SideBlock);
  110.       end;
  111.      Theta:= Theta + ThetaInc;
  112.     end;
  113.    Phi:= Phi + PhiInc;
  114.   end;
  115.   
  116.  UnlockBuffers();
  117. end;
  118. //---------------------------------------------------------------------------
  119. end.