示例#1
0
        /// <inheritdoc />
        public override List <Vertex> GenerateVertexList(int resolutionU, int resolutionV)
        {
            // Generate the vertices of two end caps, and a shaft in between:
            List <Vertex> startCapList = startCap.GenerateVertexList(resolutionU, resolutionU / 4);
            List <Vertex> endCapList   = endCap.GenerateVertexList(resolutionU, resolutionU / 4);

            // Using a slice, remove the first and last ring of vertices of the shaft, which overlap with the last
            // rings of the startCap and endCap respectively. Later we will stitch the shaft and end caps together with
            // triangles between them, during the GenerateIndexList() step.
            Slice <Vertex> shaftSlice = new Slice <Vertex>(
                shaft.GenerateVertexList(resolutionU, resolutionV),
                resolutionU,
                Cylinder.CalculateVertexCount(resolutionU, resolutionV) - 2 * resolutionU);

            // Recalculate the surface normal between the cylinder and the start cap:
            for (int i = 0; i < (resolutionU - 1); i++)
            {
                dvec3 surfacePosition = startCapList[(resolutionU / 4 - 1) * resolutionU + i + 1].Position;
                dvec3 du = surfacePosition - startCapList[(resolutionU / 4 - 1) * resolutionU + i + 1 + 1].Position;
                dvec3 dv = surfacePosition - shaftSlice[i].Position;

                // Calculate the position of the rings of vertices:
                dvec3 surfaceNormal = dvec3.Cross(du.Normalized, dv.Normalized);

                startCapList[(resolutionU / 4 - 1) * resolutionU + i + 1] = new Vertex((vec3)surfacePosition, (vec3)surfaceNormal);
            }

            // Stitch the end of the triangles:
            dvec3 surfacePosition2 = startCapList[(resolutionU / 4 - 1) * resolutionU + resolutionU].Position;
            dvec3 du2 = surfacePosition2 - startCapList[(resolutionU / 4 - 1) * resolutionU + 1].Position;
            dvec3 dv2 = surfacePosition2 - shaftSlice[resolutionU].Position;

            // Calculate the position of the rings of vertices:
            dvec3 surfaceNormal2 = dvec3.Cross(du2.Normalized, dv2.Normalized);

            startCapList[(resolutionU / 4 - 1) * resolutionU + resolutionU] = new Vertex((vec3)surfacePosition2, (vec3)surfaceNormal2);

            return(startCapList.Concat(shaftSlice).Concat(endCapList).ToList());
        }
示例#2
0
        /// <summary>
        ///     Construct a new <c>Capsule</c> around a central curve, the <c>centerCurve</c>.
        ///     The radius at each point on the central axis is defined by a one-dimensional function <c>radius</c>.
        ///
        ///     The surface is parametrized with the coordinates \f$u, \phi\f$, with \f$u\f (along the length of the
        ///     shaft) and \f$\phi \in [0, 2 \pi]\f$ along the radial coordinate. A <c>Capsule</c> consists of a
        ///     cylindrical shaft with two hemisphere end caps. $\f$u \in [-\frac{1}{2} \pi, 0]\f$ marks the region
        ///     in parametrized coordinates of the hemisphere at the start point of the cylinder,
        ///     $\f$u \in [0, 1]\f$ marks the region in parametrized coordinates of the central shaft,
        ///     and $\f$u \in [1, 1 + \frac{1}{2} \pi]\f$ marks the region in parametrized coordinates of the hemisphere
        ///     at the end point of the cylinder. The <c>heightMap</c> is a two-dimensional function defined on these
        ///     coordinates on the domain given above.
        /// </summary>
        /// <param name="centerCurve">
        ///     <inheritdoc cref="Capsule.CenterCurve"/>
        /// </param>
        /// <param name="heightMap">
        ///     The radius at each point on the surface. A <c>Capsule</c> is generated around a central curve, with each
        ///     point on the surface at a certain distance from the curve defined by <c>heightMap</c>. <c>heightMap</c>
        ///     is therefore a two-dimensional function $h(u, \phi)$ that outputs a distance from the curve at each of
        ///     the surface's parametric coordinates.
        /// </param>
        public Capsule(Curve centerCurve, ContinuousMap <Vector2, float> heightMap)
        {
            Vector3 startTangent = -centerCurve.GetTangentAt(0.0f);
            Vector3 startNormal  = centerCurve.GetNormalAt(0.0f);

            Vector3 endTangent = centerCurve.GetTangentAt(1.0f);
            Vector3 endNormal  = centerCurve.GetNormalAt(1.0f);

            this.shaft    = new Cylinder(centerCurve, heightMap);
            this.startCap = new Hemisphere(
                new ShiftedMap2D <float>(new Vector2(0.0f, -0.5f * (float)Math.PI), heightMap),
                centerCurve.GetStartPosition(),
                startTangent,
                startNormal,
                -Vector3.Cross(startTangent, startNormal)
                );
            this.endCap = new Hemisphere(
                new ShiftedMap2D <float>(new Vector2(0.0f, 1.0f + 0.5f * (float)Math.PI), new Vector2(1.0f, -1.0f), heightMap),
                centerCurve.GetEndPosition(),
                endTangent,
                endNormal,
                -Vector3.Cross(endTangent, endNormal)
                );
        }
示例#3
0
        /// <summary>
        ///     Construct a new <c>Capsule</c> around a central curve, the <c>centerCurve</c>.
        ///     The radius at each point on the central axis is defined by a one-dimensional function <c>radius</c>.
        ///
        ///     The surface is parametrized with the coordinates \f$u, \phi\f$, with \f$u\f (along the length of the
        ///     shaft) and \f$\phi \in [0, 2 \pi]\f$ along the radial coordinate. A <c>Capsule</c> consists of a
        ///     cylindrical shaft with two hemisphere end caps. $\f$u \in [-\frac{1}{2} \pi, 0]\f$ marks the region
        ///     in parametrized coordinates of the hemisphere at the start point of the cylinder,
        ///     $\f$u \in [0, 1]\f$ marks the region in parametrized coordinates of the central shaft,
        ///     and $\f$u \in [1, 1 + \frac{1}{2} \pi]\f$ marks the region in parametrized coordinates of the hemisphere
        ///     at the end point of the cylinder. The <c>heightMap</c> is a two-dimensional function defined on these
        ///     coordinates on the domain given above.
        /// </summary>
        /// <param name="centerCurve">
        ///     <inheritdoc cref="Capsule.CenterCurve"/>
        /// </param>
        /// <param name="heightMap">
        ///     The radius at each point on the surface. A <c>Capsule</c> is generated around a central curve, with each
        ///     point on the surface at a certain distance from the curve defined by <c>heightMap</c>. <c>heightMap</c>
        ///     is therefore a two-dimensional function $h(u, \phi)$ that outputs a distance from the curve at each of
        ///     the surface's parametric coordinates.
        /// </param>
        public Capsule(Curve centerCurve, ContinuousMap <dvec2, double> heightMap)
        {
            dvec3 startTangent = -centerCurve.GetTangentAt(0.0);
            dvec3 startNormal  = centerCurve.GetNormalAt(0.0);

            dvec3 endTangent = centerCurve.GetTangentAt(1.0);
            dvec3 endNormal  = centerCurve.GetNormalAt(1.0);

            this.shaft    = new Cylinder(centerCurve, heightMap);
            this.startCap = new Hemisphere(
                new ShiftedMap2D <double>(new dvec2(0.0, -0.5 * Math.PI), heightMap),
                centerCurve.GetStartPosition(),
                startTangent,
                startNormal,
                -dvec3.Cross(startTangent, startNormal)
                );
            this.endCap = new Hemisphere(
                new ShiftedMap2D <double>(new dvec2(0.0, 1.0 + 0.5 * Math.PI), new dvec2(1.0, -1.0), heightMap),
                centerCurve.GetEndPosition(),
                endTangent,
                endNormal,
                -dvec3.Cross(endTangent, endNormal)
                );
        }