コード例 #1
0
        public void Initialize(
            ICrossSectionOfLine crossSection,
            double thickness1,
            double thickness2,
            ILineCap startCap,
            ILineCap endCap,
            VectorD3D westVector,
            VectorD3D northVector,
            LineD3D line)
        {
            _crossSection                  = crossSection;
            _crossSectionVertexCount       = crossSection.NumberOfVertices;
            _crossSectionNormalCount       = crossSection.NumberOfNormals;
            _dashStartCap                  = startCap;
            _dashStartCapBaseInsetAbsolute = null == _dashStartCap ? 0 : _dashStartCap.GetAbsoluteBaseInset(thickness1, thickness2);
            _dashEndCap = endCap;
            _dashEndCapBaseInsetAbsolute = null == _dashEndCap ? 0 : _dashEndCap.GetAbsoluteBaseInset(thickness1, thickness2);
            _westVector                    = westVector;
            _northVector                   = northVector;
            _forwardVector                 = line.LineVectorNormalized;
            _lastNormalsTransformed        = new VectorD3D[_crossSectionNormalCount];
            _lastPositionsTransformedStart = new PointD3D[_crossSectionVertexCount];
            _lastPositionsTransformedEnd   = new PointD3D[_crossSectionVertexCount];

            // Get the matrix for the start plane
            var matrix = Math3D.Get2DProjectionToPlane(westVector, northVector, PointD3D.Empty);

            // note: for a single line segment, the normals need to be calculated only once

            for (int i = 0; i < _lastNormalsTransformed.Length; ++i)
            {
                _lastNormalsTransformed[i] = matrix.Transform(crossSection.Normals(i));
            }
        }
コード例 #2
0
 /// <summary>
 /// Initialization that is needed only once per straigth line (not once per dash).
 /// </summary>
 /// <param name="pen">The pen that is used to draw the line.</param>
 /// <param name="west">The west vector.</param>
 /// <param name="north">The north vector.</param>
 /// <param name="line">The global line to draw. This argument is needed to extract the line vector, which for a straight line is also the line vector for each individual dash segment.</param>
 public void Initialize(
     PenX3D pen,
     VectorD3D west,
     VectorD3D north,
     LineD3D line)
 {
     Initialize(
         pen.CrossSection,
         pen.Thickness1,
         pen.Thickness2,
         pen.DashStartCap,
         pen.DashEndCap,
         west,
         north,
         line
         );
 }
コード例 #3
0
        public void AddGeometry(
            Action <PointD3D, VectorD3D> AddPositionAndNormal,
            Action <int, int, int, bool> AddIndices,
            ref int vertexIndexOffset,
            LineD3D dashSegment,
            ILineCap overrideStartCap,
            ILineCap overrideEndCap)
        {
            if (null == _lastNormalsTransformed)
            {
                throw new InvalidProgramException("The structure is not initialized yet. Call Initialize before using it!");
            }

            PointD3D lineStart = dashSegment.P0;
            PointD3D lineEnd   = dashSegment.P1;

            var    lineVector = dashSegment.LineVector;
            double lineLength = lineVector.Length;

            if (null != _dashStartCap && null == overrideStartCap)
            {
                if (_dashStartCapBaseInsetAbsolute < 0)
                {
                    lineStart  += -_dashStartCapBaseInsetAbsolute * _forwardVector;
                    lineLength += _dashStartCapBaseInsetAbsolute;
                }
            }

            if (null != _dashEndCap && null == overrideEndCap)
            {
                if (_dashEndCapBaseInsetAbsolute < 0)
                {
                    lineEnd    += _dashEndCapBaseInsetAbsolute * _forwardVector;
                    lineLength += _dashEndCapBaseInsetAbsolute;
                }
            }

            AddGeometry(AddPositionAndNormal,
                        AddIndices,
                        ref vertexIndexOffset,
                        lineStart,
                        lineEnd,
                        lineLength > 0,
                        overrideStartCap,
                        overrideEndCap);
        }
コード例 #4
0
ファイル: HitTestPointData.cs プロジェクト: olesar/Altaxo
        public bool IsHit(LineD3D line, double thickness1, double thickness2)
        {
            if (!(line.Length > 0))
            {
                return(false);
            }

            var eastnorth = PolylineMath3D.GetWestNorthVectors(line);
            var e         = eastnorth.Item1; // east vector
            var n         = eastnorth.Item2; // north vector

            double thickness1By2 = thickness1 / 2;
            double thickness2By2 = thickness2 / 2;
            var    pts           = new PointD3D[8];

            pts[0] = _hitTransformation.Transform(line.P0 - thickness1By2 * e - thickness2By2 * n);
            pts[1] = _hitTransformation.Transform(line.P1 - thickness1By2 * e - thickness2By2 * n);
            pts[2] = _hitTransformation.Transform(line.P0 + thickness1By2 * e - thickness2By2 * n);
            pts[3] = _hitTransformation.Transform(line.P1 + thickness1By2 * e - thickness2By2 * n);
            pts[4] = _hitTransformation.Transform(line.P0 - thickness1By2 * e + thickness2By2 * n);
            pts[5] = _hitTransformation.Transform(line.P1 - thickness1By2 * e + thickness2By2 * n);
            pts[6] = _hitTransformation.Transform(line.P0 + thickness1By2 * e + thickness2By2 * n);
            pts[7] = _hitTransformation.Transform(line.P1 + thickness1By2 * e + thickness2By2 * n);

            double z;

            foreach (var ti in RectangleD3D.GetTriangleIndices())
            {
                if (HitTestWithAlreadyTransformedPoints(pts[ti.Item1], pts[ti.Item2], pts[ti.Item3], out z) && z >= 0)
                {
                    return(true);
                }
            }

            z = double.NaN;
            return(false);
        }
コード例 #5
0
        public void AddGeometry(
            Action <PointD3D, VectorD3D> AddPositionAndNormal,
            Action <int, int, int, bool> AddIndices,
            ref int vertexIndexOffset,
            PenX3D pen,
            LineD3D line
            )
        {
            var westnorth   = PolylineMath3D.GetWestNorthVectors(line);
            var westVector  = westnorth.Item1;
            var northVector = westnorth.Item2;

            if (pen.DashPattern is DashPatterns.Solid)
            {
                // draw without a dash pattern - we consider the whole line as one dash segment, but instead of dash caps, with line caps
                _dashSegment.Initialize(pen.CrossSection, pen.Thickness1, pen.Thickness2, pen.LineStartCap, pen.LineEndCap, westVector, northVector, line);
                _dashSegment.AddGeometry(AddPositionAndNormal, AddIndices, ref vertexIndexOffset, line, null, null);
            }
            else
            {
                // draw with a dash pattern
                _dashSegment.Initialize(pen, westVector, northVector, line);

                double   dashOffset = 0;
                PointD3D lineStart  = line.P0;
                PointD3D lineEnd    = line.P1;

                var    lineVector           = line.LineVector;
                double lineLength           = lineVector.Length;
                var    lineVectorNormalized = lineVector / lineLength;

                // calculate the real start and end of the line, taking the line start and end cap length into account
                if (null != pen.LineStartCap)
                {
                    var v = pen.LineStartCap.GetAbsoluteBaseInset(pen.Thickness1, pen.Thickness2);

                    if (v < 0)
                    {
                        dashOffset  = -v;
                        lineStart  += -v * lineVectorNormalized;
                        lineLength += v;
                    }
                }

                if (null != pen.LineEndCap)
                {
                    var v = pen.LineEndCap.GetAbsoluteBaseInset(pen.Thickness1, pen.Thickness2);
                    if (v < 0)
                    {
                        lineEnd    += v * lineVectorNormalized;
                        lineLength += v;
                    }
                }

                // now draw the individual dash segments

                bool wasLineStartCapDrawn = false;
                bool wasLineEndCapDrawn   = false;

                if (lineLength > 0)
                {
                    foreach (var seg in Math3D.DissectStraightLineWithDashPattern(new LineD3D(lineStart, lineEnd), pen.DashPattern, pen.DashPattern.DashOffset, Math.Max(pen.Thickness1, pen.Thickness2), dashOffset))
                    {
                        if (seg.P0 == lineStart) // this is the start of the line, thus we must use the lineStartCap instead of the dashStartCap
                        {
                            _dashSegment.AddGeometry(AddPositionAndNormal, AddIndices, ref vertexIndexOffset, seg, pen.LineStartCap, null);
                            wasLineStartCapDrawn = true;
                        }
                        else if (seg.P1 == lineEnd) // this is the end of the line, thus we must use the lineEndCap instead of the dashEndCap
                        {
                            _dashSegment.AddGeometry(AddPositionAndNormal, AddIndices, ref vertexIndexOffset, seg, null, pen.LineEndCap);
                            wasLineEndCapDrawn = true;
                        }
                        else // this is a normal dashSegment, thus we can use dashStartCap and dashEndCap
                        {
                            _dashSegment.AddGeometry(AddPositionAndNormal, AddIndices, ref vertexIndexOffset, seg, null, null);
                        }
                    }
                }

                object temporaryStorageSpace = null;

                // if the start cap was not drawn before, it must be drawn now
                if (!wasLineStartCapDrawn && null != pen.LineStartCap)
                {
                    pen.LineStartCap.AddGeometry(
                        AddPositionAndNormal,
                        AddIndices,
                        ref vertexIndexOffset,
                        true,
                        lineStart,
                        westVector,
                        northVector,
                        lineVectorNormalized,
                        pen.CrossSection,
                        null,
                        null,
                        ref temporaryStorageSpace);
                }

                // if the end cap was not drawn before, it must be drawn now
                if (!wasLineEndCapDrawn && null != pen.LineEndCap)
                {
                    pen.LineEndCap.AddGeometry(
                        AddPositionAndNormal,
                        AddIndices,
                        ref vertexIndexOffset,
                        false,
                        lineEnd,
                        westVector,
                        northVector,
                        lineVectorNormalized,
                        pen.CrossSection,
                        null,
                        null,
                        ref temporaryStorageSpace);
                }
            }
        }