[Gtkradiant] r4793 - in GtkRadiant/trunk/libs: . math

svn-noreply at zerowing.idsoftware.com svn-noreply at zerowing.idsoftware.com
Wed Sep 22 05:27:24 CDT 2004


Author: spog
Date: 2004-09-21 14:11:36 -0500 (Tue, 21 Sep 2004)
New Revision: 4793

Modified:
   GtkRadiant/trunk/libs/libs.vcproj
   GtkRadiant/trunk/libs/math/curve.h
Log:
fixed blank curve-math header

Modified: GtkRadiant/trunk/libs/libs.vcproj
===================================================================
--- GtkRadiant/trunk/libs/libs.vcproj	2004-09-21 18:46:46 UTC (rev 4792)
+++ GtkRadiant/trunk/libs/libs.vcproj	2004-09-21 19:11:36 UTC (rev 4793)
@@ -115,6 +115,12 @@
 				RelativePath=".\math\aabb.h">
 			</File>
 			<File
+				RelativePath=".\math\curve.cpp">
+			</File>
+			<File
+				RelativePath=".\math\curve.h">
+			</File>
+			<File
 				RelativePath=".\math\frustum.cpp">
 			</File>
 			<File
@@ -133,12 +139,6 @@
 				RelativePath=".\math\matrix.h">
 			</File>
 			<File
-				RelativePath=".\math\nurbscurve.cpp">
-			</File>
-			<File
-				RelativePath=".\math\nurbscurve.h">
-			</File>
-			<File
 				RelativePath=".\math\pi.cpp">
 			</File>
 			<File

Modified: GtkRadiant/trunk/libs/math/curve.h
===================================================================
--- GtkRadiant/trunk/libs/math/curve.h	2004-09-21 18:46:46 UTC (rev 4792)
+++ GtkRadiant/trunk/libs/math/curve.h	2004-09-21 19:11:36 UTC (rev 4793)
@@ -1,5 +1,186 @@
 
-#if !defined(_INCLUDED_CURVE_H_)
-#define _INCLUDED_CURVE_H_
+#if !defined(_INCLUDED_NURBSCURVE_H_)
+#define _INCLUDED_NURBSCURVE_H_
 
+#include "radiant_assert.h"
+#include "auto_array.h"
+#include "math/vector.h"
+
+typedef double(*BernsteinPolynomialFunc)(double t);
+
+inline double bernstein_0_0(double t)
+{
+  return 1;
+}
+
+inline double bernstein_0_1(double t)
+{
+  return 1 - t;
+}
+
+inline double bernstein_1_1(double t)
+{
+  return t;
+}
+
+inline double bernstein_0_2(double t)
+{
+  return (1 - t) * (1 - t);
+}
+
+inline double bernstein_1_2(double t)
+{
+  return 2 * (1 - t) * t;
+}
+
+inline double bernstein_2_2(double t)
+{
+  return t * t;
+}
+
+inline double bernstein_0_3(double t)
+{
+  return (1 - t) * (1 - t) * (1 - t);
+}
+
+inline double bernstein_1_3(double t)
+{
+  return 3 * (1 - t) * (1 - t) * t;
+}
+
+inline double bernstein_2_3(double t)
+{
+  return 3 * (1 - t) * t * t;
+}
+
+inline double bernstein_3_3(double t)
+{
+  return t * t * t;
+}
+
+const BernsteinPolynomialFunc bernsteinPolynomialsDegree0[1] = { bernstein_0_0, };
+const BernsteinPolynomialFunc bernsteinPolynomialsDegree1[2] = { bernstein_0_1, bernstein_1_1, };
+const BernsteinPolynomialFunc bernsteinPolynomialsDegree2[3] = { bernstein_0_2, bernstein_1_2, bernstein_2_2, };
+const BernsteinPolynomialFunc bernsteinPolynomialsDegree3[4] = { bernstein_0_3, bernstein_1_3, bernstein_2_3, bernstein_3_3, };
+typedef const BernsteinPolynomialFunc* BernsteinPolynomialFuncs;
+const BernsteinPolynomialFuncs bernsteinPolynomials[4] = { bernsteinPolynomialsDegree0, bernsteinPolynomialsDegree1, bernsteinPolynomialsDegree2, bernsteinPolynomialsDegree3, };
+
+
+inline double Bezier_basis(int i, int degree, double t)
+{
+  RADIANT_ASSERT(degree < 4 && i <= degree, "only supporting curves of degree 3 or less");
+  return bernsteinPolynomials[degree][i](t);
+}
+
+typedef auto_array<Vector3> ControlPoints;
+
+inline Vector3 Bezier_evaluate(const Vector3* firstPoint, int degree, double t)
+{
+  Vector3 result(0, 0, 0);
+  double denominator = 0;
+  for(int i = 0; i < degree + 1; ++i)
+  {
+    double weight = Bezier_basis(i, degree, t);
+    result += vector3_scaled(*firstPoint++, weight);
+    denominator += weight;
+  }
+  return result / denominator;
+}
+
+inline Vector3 CatmullRom_evaluate(const ControlPoints& controlPoints, double t)
+{
+  // scale t to be segment-relative
+  t *= double(controlPoints.size() - 1);
+
+  // subtract segment index;
+  int segment = 0;
+  for(int i = 0; i < controlPoints.size() - 1; ++i)
+  {
+    if(t <= double(i+1))
+    {
+      segment = i;
+      break;
+    }
+  }
+  t -= segment;
+
+  const double reciprocal_alpha = 1.0 / 3.0;
+
+  Vector3 bezierPoints[4];
+  bezierPoints[0] = controlPoints[i];
+  bezierPoints[1] = (i > 0)
+    ? controlPoints[i] + vector3_scaled(controlPoints[i + 1] - controlPoints[i - 1], reciprocal_alpha * 0.5)
+    : controlPoints[i] + vector3_scaled(controlPoints[i + 1] - controlPoints[i], reciprocal_alpha);
+  bezierPoints[2] = (i < controlPoints.size() - 2)
+    ? controlPoints[i + 1] + vector3_scaled(controlPoints[i] - controlPoints[i + 2], reciprocal_alpha * 0.5)
+    : controlPoints[i + 1] + vector3_scaled(controlPoints[i] - controlPoints[i + 1], reciprocal_alpha);
+  bezierPoints[3] = controlPoints[i + 1];
+  return Bezier_evaluate(bezierPoints, 3, t);
+}
+
+typedef auto_array<float> Knots;
+
+inline double BSpline_basis(const Knots& knots, int i, int degree, double t)
+{
+  if(degree == 0)
+  {
+    if(knots[i] <= t
+      && t < knots[i + 1]
+      && knots[i] < knots[i + 1])
+    {
+      return 1;
+    }
+    return 0;
+  }
+  double leftDenom = knots[i + degree] - knots[i];
+  double left = (leftDenom == 0) ? 0 : ((t - knots[i]) / leftDenom) * BSpline_basis(knots, i, degree - 1, t);
+  double rightDenom = knots[i + degree + 1] - knots[i + 1];
+  double right = (rightDenom == 0) ? 0 : ((knots[i + degree + 1] - t) / rightDenom) * BSpline_basis(knots, i + 1, degree - 1, t);
+  return left + right;
+}
+
+inline Vector3 BSpline_evaluate(const ControlPoints& controlPoints, const Knots& knots, int degree, double t)
+{
+  Vector3 result(0, 0, 0);
+  for(int i = 0; i < controlPoints.size(); ++i)
+  {
+    result += vector3_scaled(controlPoints[i], BSpline_basis(knots, i, degree, t));
+  }
+  return result;
+}
+
+typedef auto_array<float> NURBSWeights;
+
+inline Vector3 NURBS_evaluate(const ControlPoints& controlPoints, const NURBSWeights& weights, const Knots& knots, int degree, double t)
+{
+  Vector3 result(0, 0, 0);
+  double denominator = 0;
+  for(int i = 0; i < controlPoints.size(); ++i)
+  {
+    double weight = weights[i] * BSpline_basis(knots, i, degree, t);
+    result += vector3_scaled(controlPoints[i], weight);
+    denominator += weight;
+  }
+  return result / denominator;
+}
+
+inline void KnotVector_openUniform(Knots& knots, std::size_t count, std::size_t degree)
+{
+  knots.allocate(count + degree + 1);
+
+  std::size_t equalKnots = 1;
+
+  for(std::size_t i = 0; i < equalKnots; ++i)
+  {
+    knots[i] = 0;
+    knots[knots.size() - (i + 1)] = 1;
+  }
+
+  std::size_t difference = knots.size() - 2 * (equalKnots);
+  for(std::size_t i = 0; i < difference; ++i)
+  {
+    knots[i + equalKnots] = double(i + 1) * 1.0 / double(difference + 1);
+  }
+}
+
 #endif




More information about the Gtkradiant mailing list