summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/beziercurve.cc
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/utils/asymptote/beziercurve.cc')
-rw-r--r--Build/source/utils/asymptote/beziercurve.cc94
1 files changed, 94 insertions, 0 deletions
diff --git a/Build/source/utils/asymptote/beziercurve.cc b/Build/source/utils/asymptote/beziercurve.cc
new file mode 100644
index 00000000000..f3a675ce9ca
--- /dev/null
+++ b/Build/source/utils/asymptote/beziercurve.cc
@@ -0,0 +1,94 @@
+/*****
+ * drawbezierpatch.cc
+ * Author: John C. Bowman
+ *
+ * Render a Bezier curve.
+ *****/
+
+#include "bezierpatch.h"
+#include "beziercurve.h"
+
+namespace camp {
+
+#ifdef HAVE_GL
+
+void BezierCurve::init(double res)
+{
+ this->res=res;
+ res2=res*res;
+
+ MaterialIndex=materialIndex;
+}
+
+inline triple normal(triple bP, triple bPP)
+{
+ return dot(bP,bP)*bPP-dot(bP,bPP)*bP;
+}
+
+void BezierCurve::render(const triple *p, bool straight)
+{
+ triple p0=p[0];
+ triple p3=p[3];
+ triple n0,n1;
+
+ if(straight) {
+ n0=n1=triple(0.0,0.0,1.0);
+ } else {
+ triple p1=p[1];
+ triple p2=p[2];
+
+ n0=normal(p1-p0,p0+p2-2.0*p1);
+ n1=normal(p3-p2,p3+p1-2.0*p2);
+ }
+
+ GLuint i0=data.vertex(p0,n0);
+ GLuint i3=data.vertex(p3,n1);
+
+ if(straight) {
+ std::vector<GLuint> &q=data.indices;
+ q.push_back(i0);
+ q.push_back(i3);
+ } else
+ render(p,i0,i3);
+ append();
+}
+
+// Use a uniform partition to draw a Bezier curve.
+// p is an array of 4 triples representing the control points.
+// Ii are the vertex indices.
+void BezierCurve::render(const triple *p, GLuint I0, GLuint I1)
+{
+ triple p0=p[0];
+ triple p1=p[1];
+ triple p2=p[2];
+ triple p3=p[3];
+ if(Straightness(p0,p1,p2,p3) < res2) { // Segment is flat
+ triple P[]={p0,p3};
+ if(!offscreen(2,P)) {
+ std::vector<GLuint> &q=data.indices;
+ q.push_back(I0);
+ q.push_back(I1);
+ }
+ } else { // Segment is not flat
+ if(offscreen(4,p)) return;
+ triple m0=0.5*(p0+p1);
+ triple m1=0.5*(p1+p2);
+ triple m2=0.5*(p2+p3);
+ triple m3=0.5*(m0+m1);
+ triple m4=0.5*(m1+m2);
+ triple m5=0.5*(m3+m4);
+
+ triple s0[]={p0,m0,m3,m5};
+ triple s1[]={m5,m4,m2,p3};
+
+ triple n0=normal(bezierPh(p0,p1,p2,p3),bezierPPh(p0,p1,p2,p3));
+ GLuint i0=data.vertex(m5,n0);
+
+ render(s0,I0,i0);
+ render(s1,i0,I1);
+ }
+}
+
+#endif
+
+} //namespace camp