Beispiel #1
0
        /// <summary>
        /// Template to get a fill path.
        /// </summary>
        /// <param name="gp">Graphics path to fill with data.</param>
        /// <param name="pdata">The plot data. Don't use the Range property of the pdata, since it is overriden by the next argument.</param>
        /// <param name="range">The plot range to use.</param>
        /// <param name="layer">Graphics layer.</param>
        /// <param name="fillDirection">Designates a bound to fill to.</param>
        /// <param name="linePoints">The points that mark the line.</param>
        /// <param name="connectCircular">If true, a circular connection is drawn.</param>
        /// <param name="allLinePointsShiftedAlready">The plot positions, already shifted when a logical shift needed to be applied. Don't use the Range property of the pdata, since it is overriden by the next argument.</param>
        /// <param name="logicalShiftX">The logical shift in x-direction.</param>
        /// <param name="logicalShiftY">The logical shift in x-direction.</param>
        public virtual void FillOneRange(
            GraphicsPath gp,
            Processed2DPlotData pdata,
            IPlotRange range,
            IPlotArea layer,
            CSPlaneID fillDirection,
            PointF[] linePoints,
            bool connectCircular,
            PointF[] allLinePointsShiftedAlready,
            double logicalShiftX,
            double logicalShiftY
            )
        {
            if (connectCircular)
            {
                gp.AddLines(linePoints);
                gp.CloseFigure();
            }
            else
            {
                Logical3D r0 = layer.GetLogical3D(pdata, range.OriginalFirstPoint);
                r0.RX += logicalShiftX;
                r0.RY += logicalShiftY;

                layer.CoordinateSystem.GetIsolineFromPlaneToPoint(gp, fillDirection, r0);
                gp.AddLines(linePoints);

                Logical3D r1 = layer.GetLogical3D(pdata, range.OriginalLastPoint);
                r1.RX += logicalShiftX;
                r1.RY += logicalShiftY;

                layer.CoordinateSystem.GetIsolineFromPointToPlane(gp, r1, fillDirection);
                layer.CoordinateSystem.GetIsolineOnPlane(gp, fillDirection, r1, r0);
                gp.CloseFigure();
            }
        }
Beispiel #2
0
		public void PaintPreprocessing(System.Drawing.Graphics g, IPaintContext paintContext, IPlotArea layer, PlotItemCollection coll)
		{
			var paintData = new CachedPaintData
			{
				_clippingColl = new System.Drawing.Region[coll.Count],
				_plotDataColl = new Processed2DPlotData[coll.Count],
				_xincColl = new double[coll.Count],
				_yincColl = new double[coll.Count]
			};

			paintContext.AddValue(this, paintData);

			// First prepare
			int idx = -1;
			Processed2DPlotData previousPlotData = null;
			for (int i = 0; i < coll.Count; i++)
			{
				if (coll[i] is G2DPlotItem)
				{
					idx++;
					double currxinc = paintData._xincColl[i] = idx * _xinc * _scaleXInc;
					double curryinc = paintData._yincColl[i] = idx * _yinc * _scaleYInc;

					G2DPlotItem gpi = coll[i] as G2DPlotItem;
					Processed2DPlotData plotdata = paintData._plotDataColl[i] = gpi.GetRangesAndPoints(layer);
					plotdata.PreviousItemData = previousPlotData;
					previousPlotData = plotdata;

					int j = -1;
					foreach (int rowIndex in plotdata.RangeList.OriginalRowIndices())
					{
						j++;

						AltaxoVariant xx = plotdata.GetXPhysical(rowIndex) + currxinc;
						AltaxoVariant yy = plotdata.GetYPhysical(rowIndex) + curryinc;

						Logical3D rel = new Logical3D(layer.XAxis.PhysicalVariantToNormal(xx), layer.YAxis.PhysicalVariantToNormal(yy));
						double xabs, yabs;
						layer.CoordinateSystem.LogicalToLayerCoordinates(rel, out xabs, out yabs);
						plotdata.PlotPointsInAbsoluteLayerCoordinates[j] = new System.Drawing.PointF((float)xabs, (float)yabs);
					}

					// if clipping is used, we must get a clipping region for every plot item
					// and combine the regions from
					if (_useClipping)
					{
						if (i == 0)
							paintData._clippingColl[i] = g.Clip;

						Plot.Styles.LinePlotStyle linestyle = null;
						foreach (Plot.Styles.IG2DPlotStyle st in gpi.Style)
						{
							if (st is Plot.Styles.LinePlotStyle)
							{
								linestyle = st as Plot.Styles.LinePlotStyle;
								break;
							}
						}

						if (null != linestyle)
						{
							GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath();
							linestyle.GetFillPath(path, layer, plotdata, CSPlaneID.Bottom);
							if ((i + 1) < paintData._clippingColl.Length)
							{
								paintData._clippingColl[i + 1] = (Region)paintData._clippingColl[i].Clone();
								paintData._clippingColl[i + 1].Exclude(path);
							}
						}
						else
						{
							if ((i + 1) < paintData._clippingColl.Length)
								paintData._clippingColl[i + 1] = paintData._clippingColl[i];
						}
					}
				}
			}
		}
Beispiel #3
0
        /// <summary>
        /// Calculates from two layer coordinate values (in points usually) the relative coordinates of the point (between 0 and 1). Returns true if the conversion
        /// is possible, otherwise false.
        /// </summary>
        /// <param name="xlocation">On return, gives the x coordinate of the converted value (for instance location).</param>
        /// <param name="ylocation">On return, gives the y coordinate of the converted value (for instance location).</param>
        /// <param name="r">The logical coordinate as the result of the conversion.</param>
        /// <returns>True if the conversion was successfull, false if the conversion was not possible.</returns>
        public override bool LayerToLogicalCoordinates(double xlocation, double ylocation, out Logical3D r)
        {
            r = new Logical3D();
            double wx = xlocation - _midX;
            double wy = -ylocation + _midY;

            if (wx == 0 && wy == 0)
            {
                r.RX = 0;
                r.RY = 0;
            }
            else
            {
                r.RX = Math.Atan2(wy, wx) / (2 * Math.PI);
                r.RY = 2 * Math.Sqrt(wx * wx + wy * wy) / _radius;
            }

            if (_isXreverse)
            {
                r.RX = 1 - r.RX;
            }
            if (_isYreverse)
            {
                r.RY = 1 - r.RY;
            }
            if (_isXYInterchanged)
            {
                double hr = r.RX;
                r.RX = r.RY;
                r.RY = hr;
            }

            return(!double.IsNaN(r.RX) && !double.IsNaN(r.RY));
        }
Beispiel #4
0
        /// <summary>
        /// Paints the axis style labels.
        /// </summary>
        /// <param name="g">Graphics environment.</param>
        /// <param name="coordSyst">The coordinate system. Used to get the path along the axis.</param>
        /// <param name="scale">Scale.</param>
        /// <param name="tickSpacing">If not <c>null</c>, this parameter provides a custom tick spacing that is used instead of the default tick spacing of the scale.</param>
        /// <param name="styleInfo">Information about begin of axis, end of axis.</param>
        /// <param name="outerDistance">Distance between axis and labels.</param>
        /// <param name="useMinorTicks">If true, minor ticks are shown.</param>
        public virtual void Paint(Graphics g, G2DCoordinateSystem coordSyst, Scale scale, TickSpacing tickSpacing, CSAxisInformation styleInfo, double outerDistance, bool useMinorTicks)
        {
            _cachedAxisStyleInfo = styleInfo;
            CSLineID    styleID = styleInfo.Identifier;
            Scale       raxis   = scale;
            TickSpacing ticking = tickSpacing;

            _enclosingPath.Reset();
            _enclosingPath.FillMode = FillMode.Winding; // with Winding also overlapping rectangles are selected
            var helperPath = new GraphicsPath();
            var math       = new Matrix();

            Logical3D r0 = styleID.GetLogicalPoint(styleInfo.LogicalValueAxisOrg);
            Logical3D r1 = styleID.GetLogicalPoint(styleInfo.LogicalValueAxisEnd);

            Logical3D outer;
            var       dist_x = outerDistance; // Distance from axis tick point to label
            var       dist_y = outerDistance; // y distance from axis tick point to label

            // dist_x += this._font.SizeInPoints/3; // add some space to the horizontal direction in order to separate the chars a little from the ticks

            // next statement is necessary to have a consistent string length both
            // on 0 degree rotated text and rotated text
            // without this statement, the text is fitted to the pixel grid, which
            // leads to "steps" during scaling
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;

            double[]        relpositions;
            AltaxoVariant[] ticks;
            if (useMinorTicks)
            {
                relpositions = ticking.GetMinorTicksNormal(raxis);
                ticks        = ticking.GetMinorTicksAsVariant();
            }
            else
            {
                relpositions = ticking.GetMajorTicksNormal(raxis);
                ticks        = ticking.GetMajorTicksAsVariant();
            }

            if (!_suppressedLabels.IsEmpty)
            {
                var filteredTicks        = new List <AltaxoVariant>();
                var filteredRelPositions = new List <double>();

                for (int i = 0; i < ticks.Length; i++)
                {
                    if (_suppressedLabels.ByValues.Contains(ticks[i]))
                    {
                        continue;
                    }
                    if (_suppressedLabels.ByNumbers.Contains(i))
                    {
                        continue;
                    }
                    if (_suppressedLabels.ByNumbers.Contains(i - ticks.Length))
                    {
                        continue;
                    }

                    filteredTicks.Add(ticks[i]);
                    filteredRelPositions.Add(relpositions[i]);
                }
                ticks        = filteredTicks.ToArray();
                relpositions = filteredRelPositions.ToArray();
            }

            IMeasuredLabelItem[] labels = _labelFormatting.GetMeasuredItems(g, _font, _stringFormat, ticks);

            double     emSize    = _font.Size;
            CSAxisSide labelSide = null != _labelSide ? _labelSide.Value : styleInfo.PreferredLabelSide;

            for (int i = 0; i < ticks.Length; i++)
            {
                double r = relpositions[i];

                if (!Altaxo.Calc.RMath.IsInIntervalCC(r, -1000, 1000))
                {
                    continue;
                }

                outer = coordSyst.GetLogicalDirection(styleID.ParallelAxisNumber, labelSide);
                PointD2D tickorg = coordSyst.GetNormalizedDirection(r0, r1, r, outer, out var outVector);
                PointD2D tickend = tickorg + outVector * outerDistance;

                PointD2D msize = labels[i].Size;
                PointD2D morg  = tickend;

                if (_automaticRotationShift)
                {
                    double alpha = _rotation * Math.PI / 180 - Math.Atan2(outVector.Y, outVector.X);
                    double shift = msize.Y * 0.5 * Math.Abs(Math.Sin(alpha)) + (msize.X + _font.Size / 2) * 0.5 * Math.Abs(Math.Cos(alpha));
                    morg = morg + outVector * shift;
                }
                else
                {
                    morg = morg.WithXPlus(outVector.X * _font.Size / 3);
                }

                var mrect = new RectangleD2D(morg, msize);
                if (_automaticRotationShift)
                {
                    AdjustRectangle(ref mrect, StringAlignment.Center, StringAlignment.Center);
                }
                else
                {
                    AdjustRectangle(ref mrect, _horizontalAlignment, _verticalAlignment);
                }

                math.Reset();
                math.Translate((float)morg.X, (float)morg.Y);
                if (_rotation != 0)
                {
                    math.Rotate((float)-_rotation);
                }
                math.Translate((float)(mrect.X - morg.X + emSize * _xOffset), (float)(mrect.Y - morg.Y + emSize * _yOffset));

                System.Drawing.Drawing2D.GraphicsState gs = g.Save();
                g.MultiplyTransform(math);

                if (_backgroundStyle != null)
                {
                    _backgroundStyle.Draw(g, new RectangleD2D(PointD2D.Empty, msize));
                }

                _brush.SetEnvironment(new RectangleD2D(PointD2D.Empty, msize), BrushX.GetEffectiveMaximumResolution(g, 1));
                labels[i].Draw(g, _brush, new PointF(0, 0));
                g.Restore(gs); // Restore the graphics state

                helperPath.Reset();
                helperPath.AddRectangle(new RectangleF(PointF.Empty, (SizeF)msize));
                helperPath.Transform(math);

                _enclosingPath.AddPath(helperPath, true);
            }
        }
    /// <summary>
    /// Calculates from two logical values (values between 0 and 1) the coordinates of the point. Returns true if the conversion
    /// is possible, otherwise false.
    /// </summary>
    /// <param name="r">The logical point to convert.</param>
    /// <param name="xlocation">On return, gives the x coordinate of the converted value (for instance location).</param>
    /// <param name="ylocation">On return, gives the y coordinate of the converted value (for instance location).</param>
    /// <returns>True if the conversion was successfull, false if the conversion was not possible.</returns>
    public override bool LogicalToLayerCoordinates(Logical3D r, out double xlocation, out double ylocation)
    {
      if (_isXreverse)
        r.RX = 1 - r.RX;
      if (_isYreverse)
        r.RY = 1 - r.RY;
      if (_isXYInterchanged)
      {
        double hr = r.RX;
        r.RX = r.RY;
        r.RY = hr;
      }

      double phi = r.RX * 2 * Math.PI;
      double rad = _radius * r.RY;
      xlocation = _midX + rad * Math.Cos(phi);
      ylocation = _midY - rad * Math.Sin(phi);
      return !double.IsNaN(xlocation) && !double.IsNaN(ylocation);
    }
Beispiel #6
0
        // CoordinateSystem is not affine, or scales are non-linear
        private void BuildImageV3(Graphics gfrx, IPlotArea gl,
                                  IReadOnlyList <double> lx,
                                  IReadOnlyList <double> ly,
                                  IROMatrix <double> vcolumns)
        {
            // allocate a bitmap of same dimensions than the underlying layer
            _imageType = CachedImageType.Other;

            int dimX = (int)Math.Ceiling(gl.Size.X / 72.0 * gfrx.DpiX);
            int dimY = (int)Math.Ceiling(gl.Size.Y / 72.0 * gfrx.DpiY);

            dimX = Math.Min(2048, dimX);
            dimY = Math.Min(2048, dimY);

            // look if the image has the right dimensions
            if (null == _cachedImage || _cachedImage.Width != dimX || _cachedImage.Height != dimY)
            {
                if (null != _cachedImage)
                {
                    _cachedImage.Dispose();
                }

                // please notice: the horizontal direction of the image is related to the row index!!! (this will turn the image in relation to the table)
                // and the vertical direction of the image is related to the column index
                _cachedImage = new System.Drawing.Bitmap(dimX, dimY, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            }

            byte[] imageBytes = new byte[dimX * dimY * 4];

            double widthByDimX  = gl.Size.X / dimX;
            double heightByDimY = gl.Size.Y / dimY;
            var    rel          = new Logical3D();

            double minRX = lx[0];
            double maxRX = lx[lx.Count - 1];
            double minRY = ly[0];
            double maxRY = ly[ly.Count - 1];

            if (minRX > maxRX)
            {
                double h = minRX;
                minRX = maxRX;
                maxRX = h;
            }
            if (minRY > maxRY)
            {
                double h = minRY;
                minRY = maxRY;
                maxRY = h;
            }

            var interpol = new BivariateLinearSpline(lx, ly, vcolumns);

            Color colorInvalid = _colorProvider.GetColor(double.NaN);

            int addr = 0;

            for (int ny = 0; ny < dimY; ny++)
            {
                double py = (ny + 0.5) * heightByDimY;

                for (int nx = 0; nx < dimX; nx++, addr += 4)
                {
                    double px = (nx + 0.5) * widthByDimX;

                    if (false == gl.CoordinateSystem.LayerToLogicalCoordinates(px, py, out rel))
                    {
                        _cachedImage.SetPixel(nx, ny, colorInvalid);
                    }
                    else // conversion to relative coordinates was possible
                    {
                        double rx = rel.RX;
                        double ry = rel.RY;

                        if (rx < minRX || rx > maxRX || ry < minRY || ry > maxRY)
                        {
                            //_cachedImage.SetPixel(nx, ny, _colorInvalid);
                            imageBytes[addr + 0] = colorInvalid.B;
                            imageBytes[addr + 1] = colorInvalid.G;
                            imageBytes[addr + 2] = colorInvalid.R;
                            imageBytes[addr + 3] = colorInvalid.A;
                        }
                        else
                        {
                            double val = interpol.Interpolate(rx, ry);
                            if (double.IsNaN(val))
                            {
                                //_cachedImage.SetPixel(nx, ny, _colorInvalid);
                                imageBytes[addr + 0] = colorInvalid.B;
                                imageBytes[addr + 1] = colorInvalid.G;
                                imageBytes[addr + 2] = colorInvalid.R;
                                imageBytes[addr + 3] = colorInvalid.A;
                            }
                            else
                            {
                                //_cachedImage.SetPixel(nx, ny, GetColor(val));
                                Color c = GetColor(val);
                                imageBytes[addr + 0] = c.B;
                                imageBytes[addr + 1] = c.G;
                                imageBytes[addr + 2] = c.R;
                                imageBytes[addr + 3] = c.A;
                            }
                        }
                    }
                }
            }

            // Lock the bitmap's bits.
            var rect = new Rectangle(0, 0, _cachedImage.Width, _cachedImage.Height);

            System.Drawing.Imaging.BitmapData bmpData =
                _cachedImage.LockBits(rect, System.Drawing.Imaging.ImageLockMode.WriteOnly,
                                      _cachedImage.PixelFormat);

            // Get the address of the first line.
            IntPtr ptr = bmpData.Scan0;

            // Copy the RGB values back to the bitmap
            System.Runtime.InteropServices.Marshal.Copy(imageBytes, 0, ptr, imageBytes.Length);

            _cachedImage.UnlockBits(bmpData);
        }
Beispiel #7
0
        /// <summary>
        /// Calculates from two layer coordinate values (in points usually) the relative coordinates of the point (between 0 and 1). Returns true if the conversion
        /// is possible, otherwise false.
        /// </summary>
        /// <param name="xlocation">On return, gives the x coordinate of the converted value (for instance location).</param>
        /// <param name="ylocation">On return, gives the y coordinate of the converted value (for instance location).</param>
        /// <param name="r">The logical coordinates as the result of conversion.</param>
        /// <returns>True if the conversion was successfull, false if the conversion was not possible.</returns>
        public override bool LayerToLogicalCoordinates(double xlocation, double ylocation, out Logical3D r)
        {
            r = new Logical3D(xlocation / _layerWidth, 1 - ylocation / _layerHeight);

            if (_isXYInterchanged)
            {
                double hr = r.RX;
                r.RX = r.RY;
                r.RY = hr;
            }

            if (_isXreverse)
            {
                r.RX = 1 - r.RX;
            }
            if (_isYreverse)
            {
                r.RY = 1 - r.RY;
            }

            return(!double.IsNaN(r.RX) && !double.IsNaN(r.RY));
        }
    public override bool LogicalToLayerCoordinates(Logical3D r, out double xlocation, out double ylocation)
    {

      xlocation = _projectionMatrix.M11 * r.RX + _projectionMatrix.M12 * r.RY + _projectionMatrix.M13 * r.RZ;
      ylocation = _projectionMatrix.M21 * r.RX + _projectionMatrix.M22 * r.RY + _projectionMatrix.M23 * r.RZ;
      ylocation = _projectionMatrix.M22 - ylocation;

      return true;
    }
Beispiel #9
0
		/// <summary>
		/// Draws an isoline on the plot area.
		/// </summary>
		/// <param name="g">Graphics context.</param>
		/// <param name="pen">The style of the pen used to draw the line.</param>
		/// <param name="r0">Starting point in logical coordinates.</param>
		/// <param name="r1">End point in logical coordinates.</param>
		public virtual void DrawIsoline(System.Drawing.Graphics g, System.Drawing.Pen pen, Logical3D r0, Logical3D r1)
		{
			using (GraphicsPath path = new GraphicsPath())
			{
				GetIsoline(path, r0, r1);
				g.DrawPath(pen, path);
			}
		}
Beispiel #10
0
		/// <summary>
		/// Gets a iso line in a path object.
		/// </summary>
		/// <param name="path">The graphics path.</param>
		/// <param name="r0">Starting position in logical coordinates.</param>
		/// <param name="r1">End position in logical coordinates.</param>
		public abstract void GetIsoline(System.Drawing.Drawing2D.GraphicsPath path, Logical3D r0, Logical3D r1);
Beispiel #11
0
		/// <summary>
		/// Calculates from two  coordinates of a point the logical values (values between 0 and 1). Returns true if the conversion
		/// is possible, otherwise false.
		/// </summary>
		/// <param name="xlocation">The x coordinate of the converted value (for instance location).</param>
		/// <param name="ylocation">The y coordinate of the converted value (for instance location).</param>
		/// <param name="r">The computed logical position value.</param>
		/// <returns>True if the conversion was successfull, false if the conversion was not possible. For 3D coordinate systems,
		/// the relative values of x and y with z=0 should be returned.</returns>
		public abstract bool LayerToLogicalCoordinates(double xlocation, double ylocation, out Logical3D r);
Beispiel #12
0
        private void PaintOneRange(Graphics g, IPlotArea layer, IPlotRange range, Processed2DPlotData pdata)
        {
            // adjust the skip frequency if it was not set appropriate
            if (_skipFrequency <= 0)
            {
                _skipFrequency = 1;
            }

            var dropTargets = new List <CSPlaneID>(_dropTargets.Select(id => layer.UpdateCSPlaneID(id)));

            if (_additionalDropTargetIsEnabled)
            {
                CSPlaneID userPlane;
                if (_additionalDropTargetUsePhysicalBaseValue)
                {
                    userPlane = new CSPlaneID(_additionalDropTargetPerpendicularAxis, layer.Scales[_additionalDropTargetPerpendicularAxis].PhysicalVariantToNormal(_additionalDropTargetBaseValue));
                }
                else
                {
                    userPlane = new CSPlaneID(_additionalDropTargetPerpendicularAxis, _additionalDropTargetBaseValue);
                }
                dropTargets.Add(userPlane);
            }

            // paint the scatter style

            PointD3D pos   = PointD3D.Empty;
            var      gpath = new GraphicsPath();

            if (null == _cachedSymbolSizeForIndexFunction && null == _cachedColorForIndexFunction) // using a constant symbol size and constant color
            {
                // update pen widths
                var    pen = _pen.Clone();
                double w1  = _lineWidth1Offset + _lineWidth1Factor * _cachedSymbolSize;
                pen.Width = w1;

                var gapStart = 0.5 * (_gapAtStartOffset + _gapAtStartFactor * _cachedSymbolSize);
                var gapEnd   = 0.5 * (_gapAtEndOffset + _gapAtEndFactor * _cachedSymbolSize);

                int lower = range.LowerBound;
                int upper = range.UpperBound;

                for (int j = lower; j < upper; j += _skipFrequency)
                {
                    var originalRowIndex = range.GetOriginalRowIndexFromPlotPointIndex(j);

                    Logical3D r3d = layer.GetLogical3D(pdata, originalRowIndex);
                    r3d.RX += _cachedLogicalShiftX;
                    r3d.RY += _cachedLogicalShiftY;

                    foreach (CSPlaneID id in dropTargets)
                    {
                        gpath.Reset();
                        layer.CoordinateSystem.GetIsolineFromPointToPlane(gpath, r3d, id);
                        PointF[] shortenedPathPoints = null;
                        if (gapStart != 0 || gapEnd != 0)
                        {
                            gpath.Flatten();
                            var pathPoints = gpath.PathPoints;
                            shortenedPathPoints = GdiExtensionMethods.ShortenedBy(pathPoints, RADouble.NewAbs(gapStart), RADouble.NewAbs(gapEnd));
                            if (null != shortenedPathPoints)
                            {
                                g.DrawLines(pen, shortenedPathPoints);
                            }
                        }
                        else
                        {
                            g.DrawPath(pen, gpath);
                        }
                    }
                }
            }
            else // using a variable symbol size or variable symbol color
            {
                int lower = range.LowerBound;
                int upper = range.UpperBound;
                for (int j = lower; j < upper; j += _skipFrequency)
                {
                    var originalRowIndex = range.GetOriginalRowIndexFromPlotPointIndex(j);
                    var pen = _pen.Clone();
                    if (null == _cachedColorForIndexFunction)
                    {
                        _cachedSymbolSize = _cachedSymbolSizeForIndexFunction(originalRowIndex);
                        double w1 = _lineWidth1Offset + _lineWidth1Factor * _cachedSymbolSize;
                        pen.Width = w1;
                    }
                    else
                    {
                        _cachedSymbolSize = null == _cachedSymbolSizeForIndexFunction ? _cachedSymbolSize : _cachedSymbolSizeForIndexFunction(originalRowIndex);
                        double w1 = _lineWidth1Offset + _lineWidth1Factor * _cachedSymbolSize;

                        var customSymbolColor = _cachedColorForIndexFunction(originalRowIndex);
                        pen.Width = w1;
                        pen.Color = NamedColor.FromArgb(customSymbolColor.A, customSymbolColor.R, customSymbolColor.G, customSymbolColor.B);
                    }

                    var gapStart = 0.5 * (_gapAtStartOffset + _gapAtStartFactor * _cachedSymbolSize);
                    var gapEnd   = 0.5 * (_gapAtEndOffset + _gapAtEndFactor * _cachedSymbolSize);

                    Logical3D r3d = layer.GetLogical3D(pdata, originalRowIndex);
                    r3d.RX += _cachedLogicalShiftX;
                    r3d.RY += _cachedLogicalShiftY;

                    foreach (CSPlaneID id in _dropTargets)
                    {
                        gpath.Reset();
                        layer.CoordinateSystem.GetIsolineFromPointToPlane(gpath, r3d, id);
                        PointF[] shortenedPathPoints = null;
                        if (gapStart != 0 || gapEnd != 0)
                        {
                            gpath.Flatten();
                            var pathPoints = gpath.PathPoints;
                            shortenedPathPoints = GdiExtensionMethods.ShortenedBy(pathPoints, RADouble.NewAbs(gapStart), RADouble.NewAbs(gapEnd));
                            if (null != shortenedPathPoints)
                            {
                                g.DrawLines(pen, shortenedPathPoints);
                            }
                        }
                        else
                        {
                            g.DrawPath(pen, gpath);
                        }
                    }
                }
            }
        }
Beispiel #13
0
        public void Paint(IGraphicsContext3D g, IPlotArea layer, Processed3DPlotData pdata, Processed3DPlotData prevItemData, Processed3DPlotData nextItemData)
        {
            PlotRangeList rangeList = pdata.RangeList;
            var           ptArray   = pdata.PlotPointsInAbsoluteLayerCoordinates;

            // adjust the skip frequency if it was not set appropriate
            if (_skipFreq <= 0)
            {
                _skipFreq = 1;
            }

            var dropTargets = new List <CSPlaneID>(_dropTargets.Select(id => layer.UpdateCSPlaneID(id)));

            if (_additionalDropTargetIsEnabled)
            {
                CSPlaneID userPlane;
                if (_additionalDropTargetUsePhysicalBaseValue)
                {
                    userPlane = new CSPlaneID(_additionalDropTargetPerpendicularAxis, layer.Scales[_additionalDropTargetPerpendicularAxis].PhysicalVariantToNormal(_additionalDropTargetBaseValue));
                }
                else
                {
                    userPlane = new CSPlaneID(_additionalDropTargetPerpendicularAxis, _additionalDropTargetBaseValue);
                }
                dropTargets.Add(userPlane);
            }

            // paint the scatter style

            PointD3D pos = PointD3D.Empty;

            if (null == _cachedSymbolSizeForIndexFunction && null == _cachedColorForIndexFunction) // using a constant symbol size and constant color
            {
                var pen = _pen;
                // update pen widths
                double w1 = _lineWidth1Offset + _lineWidth1Factor * _cachedSymbolSize;
                double w2 = _lineWidth2Offset + _lineWidth2Factor * _cachedSymbolSize;
                pen = pen.WithThickness1(w1).WithThickness2(w2);

                var gapStart = 0.5 * (_gapAtStartOffset + _gapAtStartFactor * _cachedSymbolSize);
                var gapEnd   = 0.5 * (_gapAtEndOffset + _gapAtEndFactor * _cachedSymbolSize);

                for (int r = 0; r < rangeList.Count; r++)
                {
                    var range = rangeList[r];
                    int lower = range.LowerBound;
                    int upper = range.UpperBound;

                    for (int j = lower; j < upper; j += _skipFreq)
                    {
                        Logical3D r3d = layer.GetLogical3D(pdata, j + range.OffsetToOriginal);
                        foreach (CSPlaneID id in dropTargets)
                        {
                            layer.CoordinateSystem.GetIsolineFromPointToPlane(r3d, id, out var isoLine);
                            if (gapStart != 0 || gapEnd != 0)
                            {
                                isoLine = isoLine.ShortenedBy(RADouble.NewAbs(gapStart), RADouble.NewAbs(gapEnd));
                            }

                            if (null != isoLine)
                            {
                                g.DrawLine(pen, isoLine);
                            }
                        }
                    }
                } // for each range
            }
            else  // using a variable symbol size or variable symbol color
            {
                for (int r = 0; r < rangeList.Count; r++)
                {
                    var range  = rangeList[r];
                    int lower  = range.LowerBound;
                    int upper  = range.UpperBound;
                    int offset = range.OffsetToOriginal;
                    for (int j = lower; j < upper; j += _skipFreq)
                    {
                        var pen = _pen;
                        if (null == _cachedColorForIndexFunction)
                        {
                            _cachedSymbolSize = _cachedSymbolSizeForIndexFunction(j + offset);
                            double w1 = _lineWidth1Offset + _lineWidth1Factor * _cachedSymbolSize;
                            double w2 = _lineWidth2Offset + _lineWidth2Factor * _cachedSymbolSize;
                            pen = _pen.WithThickness1(w1).WithThickness2(w2);
                        }
                        else
                        {
                            _cachedSymbolSize = null == _cachedSymbolSizeForIndexFunction ? _cachedSymbolSize : _cachedSymbolSizeForIndexFunction(j + offset);
                            double w1 = _lineWidth1Offset + _lineWidth1Factor * _cachedSymbolSize;
                            double w2 = _lineWidth2Offset + _lineWidth2Factor * _cachedSymbolSize;

                            var customSymbolColor = _cachedColorForIndexFunction(j + offset);
                            pen = _pen.WithThickness1(w1).WithThickness2(w2).WithColor(NamedColor.FromArgb(customSymbolColor.A, customSymbolColor.R, customSymbolColor.G, customSymbolColor.B));
                        }

                        var gapStart = 0.5 * (_gapAtStartOffset + _gapAtStartFactor * _cachedSymbolSize);
                        var gapEnd   = 0.5 * (_gapAtEndOffset + _gapAtEndFactor * _cachedSymbolSize);

                        Logical3D r3d = layer.GetLogical3D(pdata, j + rangeList[r].OffsetToOriginal);
                        foreach (CSPlaneID id in _dropTargets)
                        {
                            layer.CoordinateSystem.GetIsolineFromPointToPlane(r3d, id, out var isoLine);

                            if (gapStart != 0 || gapEnd != 0)
                            {
                                isoLine = isoLine.ShortenedBy(RADouble.NewAbs(gapStart), RADouble.NewAbs(gapEnd));
                            }
                            if (null != isoLine)
                            {
                                g.DrawLine(pen, isoLine);
                            }
                        }
                    }
                }
            }
        }
Beispiel #14
0
			public Logical3D GetLogical3D(AltaxoVariant x, AltaxoVariant y)
			{
				Logical3D shifted = new Logical3D(
					_xScale.PhysicalVariantToNormal(x),
					_yScale.PhysicalVariantToNormal(y));
				return shifted;
			}
Beispiel #15
0
			public Logical3D GetLogical3D(I3DPhysicalVariantAccessor acc, int idx)
			{
				Logical3D shifted = new Logical3D(
					_xScale.PhysicalVariantToNormal(acc.GetXPhysical(idx)),
					_yScale.PhysicalVariantToNormal(acc.GetYPhysical(idx)));
				return shifted;
			}
		public override bool LogicalToLayerCoordinatesAndDirection(
		 Logical3D r0, Logical3D r1,
		 double t,
		 out double ax, out double ay, out double adx, out double ady)
		{
			if (_isXreverse)
			{
				r0.RX = 1 - r0.RX;
				r1.RX = 1 - r1.RX;
			}
			if (_isYreverse)
			{
				r0.RY = 1 - r0.RY;
				r1.RY = 1 - r1.RY;
			}
			if (_isXYInterchanged)
			{
				double hr0 = r0.RX;
				r0.RX = r0.RY;
				r0.RY = hr0;

				double hr1 = r1.RX;
				r1.RX = r1.RY;
				r1.RY = hr1;
			}

			double rx = r0.RX + t * (r1.RX - r0.RX);
			double ry = r0.RY + t * (r1.RY - r0.RY);

			ax = _layerWidth * rx;
			ay = _layerHeight * (1 - ry);

			adx = _layerWidth * (r1.RX - r0.RX);
			ady = _layerHeight * (r0.RY - r1.RY);

			return !double.IsNaN(ax) && !double.IsNaN(ay);
		}
		public override void GetIsoline(System.Drawing.Drawing2D.GraphicsPath g, Logical3D r0, Logical3D r1)
		{
			double ax0, ax1, ay0, ay1;
			if (LogicalToLayerCoordinates(r0, out ax0, out ay0) && LogicalToLayerCoordinates(r1, out ax1, out ay1))
			{
				g.AddLine((float)ax0, (float)ay0, (float)ax1, (float)ay1);
			}
		}
Beispiel #18
0
		/// <summary>
		/// Draws an isoline beginning from a given point to the axis.
		/// </summary>
		/// <param name="path">Graphics path to fill with the isoline.</param>
		/// <param name="r">Logical coordinate of the start point.</param>
		/// <param name="id">The logical plane to end the isoline.</param>
		public virtual void GetIsolineFromPointToPlane(GraphicsPath path, Logical3D r, CSPlaneID id)
		{
			if (id.PerpendicularAxisNumber == 0)
			{
				GetIsoline(path, r, new Logical3D(id.LogicalValue, r.RY, r.RZ));
			}
			else if (id.PerpendicularAxisNumber == 1)
			{
				GetIsoline(path, r, new Logical3D(r.RX, id.LogicalValue, r.RZ));
			}
			else
			{
				GetIsoline(path, r, new Logical3D(r.RX, r.RY, id.LogicalValue));
			}
		}
 public override bool LayerToLogicalCoordinates(double xlocation, double ylocation, out Logical3D r)
 {
   throw new Exception("The method or operation is not implemented.");
 }
Beispiel #20
0
		/// <summary>
		/// Draws an isoline beginning from a given point to a plane.
		/// </summary>
		/// <param name="g">Graphics to draw the isoline to.</param>
		/// <param name="pen">The pen to use.</param>
		/// <param name="r">Logical coordinate of the start point.</param>
		/// <param name="id">The logical plane to end the isoline.</param>
		public virtual void DrawIsolineFromPointToPlane(Graphics g, System.Drawing.Pen pen, Logical3D r, CSPlaneID id)
		{
			if (id.PerpendicularAxisNumber == 0)
			{
				DrawIsoline(g, pen, r, new Logical3D(id.LogicalValue, r.RY, r.RZ));
			}
			else if (id.PerpendicularAxisNumber == 1)
			{
				DrawIsoline(g, pen, r, new Logical3D(r.RX, id.LogicalValue, r.RZ));
			}
			else
			{
				DrawIsoline(g, pen, r, new Logical3D(r.RX, r.RY, id.LogicalValue));
			}
		}
    public void Paint(System.Drawing.Graphics g, IPlotArea layer, PlotItemCollection coll)
    {
      Dictionary<G2DPlotItem, Processed2DPlotData> plotDataDict;
      if (!CanUseStyle(layer, coll, out plotDataDict))
      {
        CoordinateTransformingStyleBase.Paint(g, layer, coll);
        return;
      }

      AltaxoVariant[] ysumArray = null;
      foreach (IGPlotItem pi in coll)
      {
        if (pi is G2DPlotItem)
        {
          G2DPlotItem gpi = pi as G2DPlotItem;
          Processed2DPlotData pdata = plotDataDict[gpi];
          ysumArray = AbsoluteStackTransform.AddUp(ysumArray, pdata);
        }
      }


     

      // now plot the data - the summed up y is in yArray
      AltaxoVariant[] yArray = null;
      Processed2DPlotData previousItemData = null;
      foreach (IGPlotItem pi in coll)
      {
        if (pi is G2DPlotItem)
        {
          G2DPlotItem gpi = pi as G2DPlotItem;
          Processed2DPlotData pdata = plotDataDict[gpi];
          yArray = AbsoluteStackTransform.AddUp(yArray, pdata);
          AltaxoVariant[] localArray = new AltaxoVariant[yArray.Length];

          int j = -1;
          foreach (int originalIndex in pdata.RangeList.OriginalRowIndices())
          {
            j++;
            AltaxoVariant y = 100*yArray[j]/ysumArray[j];
            localArray[j] = y;

            Logical3D rel = new Logical3D(
            layer.XAxis.PhysicalVariantToNormal(pdata.GetXPhysical(originalIndex)),
            layer.YAxis.PhysicalVariantToNormal(y));

            double xabs, yabs;
            layer.CoordinateSystem.LogicalToLayerCoordinates(rel, out xabs, out yabs);
            pdata.PlotPointsInAbsoluteLayerCoordinates[j] = new System.Drawing.PointF((float)xabs, (float)yabs);

          }
          // we have also to exchange the accessor for the physical y value and replace it by our own one
          pdata.YPhysicalAccessor = new IndexedPhysicalValueAccessor(delegate(int i) { return localArray[i]; });
          pdata.PreviousItemData = previousItemData;
          previousItemData = pdata;
        }
      }

      for (int i = coll.Count - 1; i >= 0; --i)
      {
        IGPlotItem pi = coll[i];
        if (pi is G2DPlotItem)
        {
          G2DPlotItem gpi = pi as G2DPlotItem;
          Processed2DPlotData pdata = plotDataDict[gpi];
          gpi.Paint(g, layer, pdata);
        }
        else
        {
          pi.Paint(g, layer);
        }
      }
    }
Beispiel #22
0
		/// <summary>
		/// Draws an isoline on a plane beginning from r0 to r1. For r0,r1 either ry0,ry1 is used (if it is an x-axis),
		/// otherwise rx0,rx1 is used. The other parameter pair is not used.
		/// </summary>
		/// <param name="path">Graphics path to fill with the isoline.</param>
		/// <param name="r0">Logical coordinate of the start point.</param>
		/// <param name="r1">Logical coordinate of the end point.</param>
		/// <param name="id">The axis to end the isoline.</param>
		public virtual void GetIsolineOnPlane(GraphicsPath path, CSPlaneID id, Logical3D r0, Logical3D r1)
		{
			if (id.PerpendicularAxisNumber == 0)
			{
				GetIsoline(path, new Logical3D(id.LogicalValue, r0.RY, r0.RZ), new Logical3D(id.LogicalValue, r1.RY, r1.RZ));
			}
			else if (id.PerpendicularAxisNumber == 1)
			{
				GetIsoline(path, new Logical3D(r0.RX, id.LogicalValue, r0.RZ), new Logical3D(r1.RX, id.LogicalValue, r1.RZ));
			}
			else
			{
				GetIsoline(path, new Logical3D(r0.RX, r0.RY, id.LogicalValue), new Logical3D(r1.RX, r1.RY, id.LogicalValue));
			}
		}
    public void Paint(System.Drawing.Graphics g, IPlotArea layer, PlotItemCollection coll)
    {
      Dictionary<G2DPlotItem, Processed2DPlotData> plotDataDict;
      if (!CanUseStyle(layer, coll, out plotDataDict))
      {
        CoordinateTransformingStyleBase.Paint(g, layer, coll);
        return;
      }

      AltaxoVariant[] yArray = null;
      // First, add up all items since we start always with the last item
      int idx = -1;
      Processed2DPlotData previousItemData = null;
      foreach (IGPlotItem pi in coll)
       {
         
        if (pi is G2DPlotItem)
        {
          idx++;

          G2DPlotItem gpi = pi as G2DPlotItem;
          Processed2DPlotData pdata = plotDataDict[gpi];
          yArray = AddUp(yArray, pdata);
        
          if(idx>0) // this is not the first item
          {
            int j = -1;
            foreach (int originalIndex in pdata.RangeList.OriginalRowIndices())
            {
              j++;
              Logical3D rel = new Logical3D(
              layer.XAxis.PhysicalVariantToNormal(pdata.GetXPhysical(originalIndex)),
              layer.YAxis.PhysicalVariantToNormal(yArray[j]));

              double xabs, yabs;
              layer.CoordinateSystem.LogicalToLayerCoordinates(rel, out xabs, out yabs);
              pdata.PlotPointsInAbsoluteLayerCoordinates[j] = new System.Drawing.PointF((float)xabs, (float)yabs);
            }
          }

          // we have also to exchange the accessor for the physical y value and replace it by our own one
          AltaxoVariant[] localArray = (AltaxoVariant[])yArray.Clone();
          pdata.YPhysicalAccessor = new IndexedPhysicalValueAccessor(delegate(int i) { return localArray[i]; });
          pdata.PreviousItemData = previousItemData;
          previousItemData = pdata;
        }
      }

      for (int i = coll.Count - 1; i >= 0; --i)
      {
        IGPlotItem pi = coll[i];
        if (pi is G2DPlotItem)
        {
          G2DPlotItem gpi = pi as G2DPlotItem;
          Processed2DPlotData pdata = plotDataDict[gpi];
          gpi.Paint(g, layer, pdata);
        }
        else
        {
          pi.Paint(g, layer);
        }
      }

    }
Beispiel #24
0
		public PointD2D GetPointOnPlane(CSPlaneID id, Logical3D r)
		{
			double x, y;
			if (id.PerpendicularAxisNumber == 0)
				LogicalToLayerCoordinates(new Logical3D(id.LogicalValue, r.RY, r.RZ), out x, out y);
			else if (id.PerpendicularAxisNumber == 1)
				LogicalToLayerCoordinates(new Logical3D(r.RX, id.LogicalValue, r.RZ), out x, out y);
			else
				LogicalToLayerCoordinates(new Logical3D(r.RX, r.RY, id.LogicalValue), out x, out y);

			return new PointD2D(x, y);
		}
    /// <summary>
    /// Calculates from two layer coordinate values (in points usually) the relative coordinates of the point (between 0 and 1). Returns true if the conversion
    /// is possible, otherwise false.
    /// </summary>
    /// <param name="xlocation">On return, gives the x coordinate of the converted value (for instance location).</param>
    /// <param name="ylocation">On return, gives the y coordinate of the converted value (for instance location).</param>
    /// <param name="r">The logical coordinate as the result of the conversion.</param>
    /// <returns>True if the conversion was successfull, false if the conversion was not possible.</returns>
    public override bool LayerToLogicalCoordinates(double xlocation, double ylocation, out Logical3D r)
    {
      r = new Logical3D();
      double wx = xlocation - _midX;
      double wy = -ylocation + _midY;
      if (wx == 0 && wy == 0)
      {
        r.RX = 0;
        r.RY = 0;
      }
      else
      {
        r.RX = Math.Atan2(wy, wx) / (2 * Math.PI);
        r.RY = 2 * Math.Sqrt(wx * wx + wy * wy) / _radius;
      }

      if (_isXreverse)
        r.RX = 1 - r.RX;
      if (_isYreverse)
        r.RY = 1 - r.RY;
      if (_isXYInterchanged)
      {
        double hr = r.RX;
        r.RX = r.RY;
        r.RY = hr;
      }

      return !double.IsNaN(r.RX) && !double.IsNaN(r.RY);
    }
Beispiel #26
0
		/// <summary>
		/// Converts logical coordinates along an isoline to layer coordinates and returns the direction of the isoline at this point.
		/// </summary>
		/// <param name="r0">Logical coordinates of starting point of the isoline.</param>
		/// <param name="r1">Logical coordinates of end point of the isoline.</param>
		/// <param name="t">Parameter between 0 and 1 that determines the point on the isoline.
		/// A value of 0 denotes the starting point of the isoline, a value of 1 the end point. The logical
		/// coordinates are linear interpolated between starting point and end point.</param>
		/// <param name="angle">Angle between direction of the isoline and returned normalized direction vector.</param>
		/// <param name="normalizeddirection">Returns the normalized direction vector,i.e. a vector of norm 1, that
		/// has the angle <paramref name="angle"/> to the tangent of the isoline. </param>
		/// <returns>The location (in layer coordinates) of the isoline point.</returns>
		public PointD2D GetNormalizedDirection(
			Logical3D r0, Logical3D r1,
			double t,
			double angle,
			out PointD2D normalizeddirection)
		{
			double ax, ay, adx, ady;
			this.LogicalToLayerCoordinatesAndDirection(
				r0, r1,
				t,
				out ax, out ay, out adx, out ady);

			if (angle != 0)
			{
				double phi = Math.PI * angle / 180;
				double hdx = adx * Math.Cos(phi) + ady * Math.Sin(phi);
				ady = -adx * Math.Sin(phi) + ady * Math.Cos(phi);
				adx = hdx;
			}

			// Normalize the vector
			double rr = Calc.RMath.Hypot(adx, ady);
			if (rr > 0)
			{
				adx /= rr;
				ady /= rr;
			}

			normalizeddirection = new PointD2D(adx, ady);

			return new PointD2D(ax, ay);
		}
 public override void GetIsoline(System.Drawing.Drawing2D.GraphicsPath path, Logical3D r0, Logical3D r1)
 {
     LogicalToLayerCoordinates(r0, out var x0, out var y0);
     LogicalToLayerCoordinates(r1, out var x1, out var y1);
     path.AddLine((float)x0, (float)y0, (float)x1, (float)y1);
 }
Beispiel #28
0
		/// <summary>
		/// Converts logical coordinates along an isoline to layer coordinates and returns the direction of the isoline at this point.
		/// </summary>
		/// <param name="r0">Logical starting point of the isoline.</param>
		/// <param name="r1">Logical end point of the isoline.</param>
		/// <param name="t">Parameter between 0 and 1 that determines the point on the isoline.
		/// A value of 0 denotes the starting point of the isoline, a value of 1 the end point. The logical
		/// coordinates are linear interpolated between starting point and end point.</param>
		/// <param name="direction">Logical direction vector.</param>
		/// <param name="normalizeddirection">Returns the normalized direction vector,i.e. a vector of norm 1, that
		/// goes in the logical direction provided by the previous argument. </param>
		/// <returns>The location (in layer coordinates) of the isoline point.</returns>
		public virtual PointD2D GetNormalizedDirection(
				Logical3D r0, Logical3D r1,
				double t,
				Logical3D direction,
				out PointD2D normalizeddirection)
		{
			double ax, ay, adx, ady;
			Logical3D rn0 = Logical3D.Interpolate(r0, r1, t);
			Logical3D rn1 = rn0 + direction;
			this.LogicalToLayerCoordinatesAndDirection(rn0, rn1, 0, out ax, out ay, out adx, out ady);
			double hypot = Calc.RMath.Hypot(adx, ady);
			if (0 == hypot)
			{
				// then we look a little bit displaced - we might be at the midpoint where the directions are undefined
				double displT = t;
				if (displT < 0.5)
					displT += 1E-6;
				else
					displT -= 1E-6;

				Logical3D displR = Logical3D.Interpolate(r0, r1, displT);
				Logical3D displD = displR + direction;
				double dummyx, dummyy;
				LogicalToLayerCoordinatesAndDirection(displR, displD, 0, out dummyx, out dummyy, out adx, out ady);
				hypot = Calc.RMath.Hypot(adx, ady);
			}

			// Normalize the vector
			if (hypot > 0)
			{
				adx /= hypot;
				ady /= hypot;
			}

			normalizeddirection = new PointD2D(adx, ady);

			return new PointD2D(ax, ay);
		}
Beispiel #29
0
        /// <summary>
        /// Paint the axis in the Graphics context.
        /// </summary>
        /// <param name="g">The graphics context painting to.</param>
        /// <param name="layer">The layer the axis belongs to.</param>
        /// <param name="styleInfo">The axis information of the axis to paint.</param>
        /// <param name="customTickSpacing">If not <c>null</c>, this parameter provides a custom tick spacing that is used instead of the default tick spacing of the scale.</param>
        public void Paint(IGraphicsContext3D g, IPlotArea layer, CSAxisInformation styleInfo, TickSpacing customTickSpacing)
        {
            CSLineID styleID = styleInfo.Identifier;

            _cachedAxisStyleInfo = styleInfo;
            Scale axis = layer.Scales[styleID.ParallelAxisNumber];

            TickSpacing ticking = null != customTickSpacing ? customTickSpacing : layer.Scales[styleID.ParallelAxisNumber].TickSpacing;

            Logical3D r0 = styleID.GetLogicalPoint(styleInfo.LogicalValueAxisOrg);
            Logical3D r1 = styleID.GetLogicalPoint(styleInfo.LogicalValueAxisEnd);

            var sweepPath = layer.CoordinateSystem.GetIsoline(r0, r1);

            g.DrawLine(_axisPen, sweepPath);

            _cachedMainLinePointsUsedForHitTesting = sweepPath.Points.ToArray();
            var majorTickLinesUsedForHitTesting = new List <LineD3D>();
            var minorTickLinesUsedForHitTesting = new List <LineD3D>();

            Logical3D outer;

            // now the major ticks
            VectorD3D outVector;

            double[] majorticks = ticking.GetMajorTicksNormal(axis);
            for (int i = 0; i < majorticks.Length; i++)
            {
                double r = majorticks[i];

                if (_showFirstUpMajorTicks)
                {
                    outer = layer.CoordinateSystem.GetLogicalDirection(styleID.ParallelAxisNumber, CSAxisSide.FirstUp);
                    var tickorg = layer.CoordinateSystem.GetPositionAndNormalizedDirection(r0, r1, r, outer, out outVector);
                    var tickend = tickorg + outVector * _majorTickLength;
                    g.DrawLine(_majorTickPen, tickorg, tickend);
                    majorTickLinesUsedForHitTesting.Add(new LineD3D(tickorg, tickend));
                }
                if (_showFirstDownMajorTicks)
                {
                    outer = layer.CoordinateSystem.GetLogicalDirection(styleID.ParallelAxisNumber, CSAxisSide.FirstDown);
                    var tickorg = layer.CoordinateSystem.GetPositionAndNormalizedDirection(r0, r1, r, outer, out outVector);
                    var tickend = tickorg + outVector * _majorTickLength;
                    g.DrawLine(_majorTickPen, tickorg, tickend);
                    majorTickLinesUsedForHitTesting.Add(new LineD3D(tickorg, tickend));
                }
                if (_showSecondUpMajorTicks)
                {
                    outer = layer.CoordinateSystem.GetLogicalDirection(styleID.ParallelAxisNumber, CSAxisSide.SecondUp);
                    var tickorg = layer.CoordinateSystem.GetPositionAndNormalizedDirection(r0, r1, r, outer, out outVector);
                    var tickend = tickorg + outVector * _majorTickLength;
                    g.DrawLine(_majorTickPen, tickorg, tickend);
                    majorTickLinesUsedForHitTesting.Add(new LineD3D(tickorg, tickend));
                }
                if (_showSecondDownMajorTicks)
                {
                    outer = layer.CoordinateSystem.GetLogicalDirection(styleID.ParallelAxisNumber, CSAxisSide.SecondDown);
                    var tickorg = layer.CoordinateSystem.GetPositionAndNormalizedDirection(r0, r1, r, outer, out outVector);
                    var tickend = tickorg + outVector * _majorTickLength;
                    g.DrawLine(_majorTickPen, tickorg, tickend);
                    majorTickLinesUsedForHitTesting.Add(new LineD3D(tickorg, tickend));
                }
            }

            // now the major ticks
            double[] minorticks = ticking.GetMinorTicksNormal(axis);
            for (int i = 0; i < minorticks.Length; i++)
            {
                double r = minorticks[i];

                if (_showFirstUpMinorTicks)
                {
                    outer = layer.CoordinateSystem.GetLogicalDirection(styleID.ParallelAxisNumber, CSAxisSide.FirstUp);
                    var tickorg = layer.CoordinateSystem.GetPositionAndNormalizedDirection(r0, r1, r, outer, out outVector);
                    var tickend = tickorg + outVector * _minorTickLength;
                    g.DrawLine(_minorTickPen, tickorg, tickend);
                    minorTickLinesUsedForHitTesting.Add(new LineD3D(tickorg, tickend));
                }
                if (_showFirstDownMinorTicks)
                {
                    outer = layer.CoordinateSystem.GetLogicalDirection(styleID.ParallelAxisNumber, CSAxisSide.FirstDown);
                    var tickorg = layer.CoordinateSystem.GetPositionAndNormalizedDirection(r0, r1, r, outer, out outVector);
                    var tickend = tickorg + outVector * _minorTickLength;
                    g.DrawLine(_minorTickPen, tickorg, tickend);
                    minorTickLinesUsedForHitTesting.Add(new LineD3D(tickorg, tickend));
                }

                if (_showSecondUpMinorTicks)
                {
                    outer = layer.CoordinateSystem.GetLogicalDirection(styleID.ParallelAxisNumber, CSAxisSide.SecondUp);
                    var tickorg = layer.CoordinateSystem.GetPositionAndNormalizedDirection(r0, r1, r, outer, out outVector);
                    var tickend = tickorg + outVector * _minorTickLength;
                    g.DrawLine(_minorTickPen, tickorg, tickend);
                    minorTickLinesUsedForHitTesting.Add(new LineD3D(tickorg, tickend));
                }
                if (_showSecondDownMinorTicks)
                {
                    outer = layer.CoordinateSystem.GetLogicalDirection(styleID.ParallelAxisNumber, CSAxisSide.SecondDown);
                    var tickorg = layer.CoordinateSystem.GetPositionAndNormalizedDirection(r0, r1, r, outer, out outVector);
                    var tickend = tickorg + outVector * _minorTickLength;
                    g.DrawLine(_minorTickPen, tickorg, tickend);
                    minorTickLinesUsedForHitTesting.Add(new LineD3D(tickorg, tickend));
                }
            }

            _cachedMajorTickLinesUsedForHitTesting = majorTickLinesUsedForHitTesting.ToArray();
            _cachedMinorTickLinesUsedForHitTesting = minorTickLinesUsedForHitTesting.ToArray();
        }
Beispiel #30
0
		/// <summary>
		/// Calculates from two logical values (values between 0 and 1) the coordinates of the point. Returns true if the conversion
		/// is possible, otherwise false.
		/// </summary>
		/// <param name="r">The logical position value.</param>
		/// <param name="xlocation">On return, gives the x coordinate of the converted value (for instance location).</param>
		/// <param name="ylocation">On return, gives the y coordinate of the converted value (for instance location).</param>
		/// <returns>True if the conversion was successfull, false if the conversion was not possible.</returns>
		public abstract bool LogicalToLayerCoordinates(Logical3D r, out double xlocation, out double ylocation);
		/// <summary>
		/// Calculates from two logical values (values between 0 and 1) the coordinates of the point. Returns true if the conversion
		/// is possible, otherwise false.
		/// </summary>
		/// <param name="r">The logical coordinates to convert.</param>
		/// <param name="xlocation">On return, gives the x coordinate of the converted value (for instance location).</param>
		/// <param name="ylocation">On return, gives the y coordinate of the converted value (for instance location).</param>
		/// <returns>True if the conversion was successfull, false if the conversion was not possible.</returns>
		public override bool LogicalToLayerCoordinates(Logical3D r, out double xlocation, out double ylocation)
		{
			if (_isXreverse)
				r.RX = 1 - r.RX;
			if (_isYreverse)
				r.RY = 1 - r.RY;
			if (_isXYInterchanged)
			{
				double hr = r.RX;
				r.RX = r.RY;
				r.RY = hr;
			}

			xlocation = _layerWidth * r.RX;
			ylocation = _layerHeight * (1 - r.RY);
			return !double.IsNaN(xlocation) && !double.IsNaN(ylocation);
		}
Beispiel #32
0
		/// <summary>
		/// Converts logical coordinates along an isoline to layer coordinates and the appropriate derivative.
		/// </summary>
		/// <param name="r0">Logical position of starting point of the isoline.</param>
		/// <param name="r1">Logical position of end point of the isoline.</param>
		/// <param name="t">Parameter between 0 and 1 that determines the point on the isoline.
		/// A value of 0 denotes the starting point of the isoline, a value of 1 the end point. The logical
		/// coordinates are linear interpolated between starting point and end point.</param>
		/// <param name="ax">Layer coordinate x of the isoline point.</param>
		/// <param name="ay">Layer coordinate y of the isoline point.</param>
		/// <param name="adx">Derivative of layer coordinate x with respect to parameter t at the point (ax,ay).</param>
		/// <param name="ady">Derivative of layer coordinate y with respect to parameter t at the point (ax,ay).</param>
		/// <returns>True if the conversion was sucessfull, otherwise false.</returns>
		public abstract bool LogicalToLayerCoordinatesAndDirection(
			Logical3D r0, Logical3D r1,
			double t,
			out double ax, out double ay, out double adx, out double ady);
		/// <summary>
		/// Calculates from two layer coordinate values (in points usually) the relative coordinates of the point (between 0 and 1). Returns true if the conversion
		/// is possible, otherwise false.
		/// </summary>
		/// <param name="xlocation">On return, gives the x coordinate of the converted value (for instance location).</param>
		/// <param name="ylocation">On return, gives the y coordinate of the converted value (for instance location).</param>
		/// <param name="r">The logical coordinates as the result of conversion.</param>
		/// <returns>True if the conversion was successfull, false if the conversion was not possible.</returns>
		public override bool LayerToLogicalCoordinates(double xlocation, double ylocation, out Logical3D r)
		{
			r = new Logical3D(xlocation / _layerWidth, 1 - ylocation / _layerHeight);

			if (_isXYInterchanged)
			{
				double hr = r.RX;
				r.RX = r.RY;
				r.RY = hr;
			}

			if (_isXreverse)
				r.RX = 1 - r.RX;
			if (_isYreverse)
				r.RY = 1 - r.RY;

			return !double.IsNaN(r.RX) && !double.IsNaN(r.RY);
		}
Beispiel #34
0
 /// <summary>
 /// Converts logical coordinates along an isoline to layer coordinates and the appropriate derivative.
 /// </summary>
 /// <param name="r0">Logical position of starting point of the isoline.</param>
 /// <param name="r1">Logical position of end point of the isoline.</param>
 /// <param name="t">Parameter between 0 and 1 that determines the point on the isoline.
 /// A value of 0 denotes the starting point of the isoline, a value of 1 the end point. The logical
 /// coordinates are linear interpolated between starting point and end point.</param>
 /// <param name="ax">Layer coordinate x of the isoline point.</param>
 /// <param name="ay">Layer coordinate y of the isoline point.</param>
 /// <param name="adx">Derivative of layer coordinate x with respect to parameter t at the point (ax,ay).</param>
 /// <param name="ady">Derivative of layer coordinate y with respect to parameter t at the point (ax,ay).</param>
 /// <returns>True if the conversion was sucessfull, otherwise false.</returns>
 public abstract bool LogicalToLayerCoordinatesAndDirection(
     Logical3D r0, Logical3D r1,
     double t,
     out double ax, out double ay, out double adx, out double ady);
Beispiel #35
0
 /// <summary>
 /// Calculates from two  coordinates of a point the logical values (values between 0 and 1). Returns true if the conversion
 /// is possible, otherwise false.
 /// </summary>
 /// <param name="xlocation">The x coordinate of the converted value (for instance location).</param>
 /// <param name="ylocation">The y coordinate of the converted value (for instance location).</param>
 /// <param name="r">The computed logical position value.</param>
 /// <returns>True if the conversion was successfull, false if the conversion was not possible. For 3D coordinate systems,
 /// the relative values of x and y with z=0 should be returned.</returns>
 public abstract bool LayerToLogicalCoordinates(double xlocation, double ylocation, out Logical3D r);
Beispiel #36
0
 /// <summary>
 /// Gets a iso line in a path object.
 /// </summary>
 /// <param name="path">The graphics path.</param>
 /// <param name="r0">Starting position in logical coordinates.</param>
 /// <param name="r1">End position in logical coordinates.</param>
 public abstract void GetIsoline(System.Drawing.Drawing2D.GraphicsPath path, Logical3D r0, Logical3D r1);
    public override bool LogicalToLayerCoordinatesAndDirection(Logical3D r0, Logical3D r1, double t, out double ax, out double ay, out double adx, out double ady)
    {
      LogicalToLayerCoordinates(Logical3D.Interpolate(r0,r1,t),out ax, out ay);

      double x0, y0, x1, y1;
      LogicalToLayerCoordinates(r0, out x0, out y0);
      LogicalToLayerCoordinates(r1, out x1, out y1);
      adx = x1 - x0;
      ady = y1 - y0;

      return true;
    }
Beispiel #38
0
 /// <summary>
 /// Draws an isoline on the plot area.
 /// </summary>
 /// <param name="g">Graphics context.</param>
 /// <param name="pen">The style of the pen used to draw the line.</param>
 /// <param name="r0">Starting point in logical coordinates.</param>
 /// <param name="r1">End point in logical coordinates.</param>
 public virtual void DrawIsoline(System.Drawing.Graphics g, System.Drawing.Pen pen, Logical3D r0, Logical3D r1)
 {
     using (GraphicsPath path = new GraphicsPath())
     {
         GetIsoline(path, r0, r1);
         g.DrawPath(pen, path);
     }
 }
 public override void GetIsoline(System.Drawing.Drawing2D.GraphicsPath path, Logical3D r0, Logical3D r1)
 {
   double x0, y0, x1, y1;
   LogicalToLayerCoordinates(r0, out x0, out y0);
   LogicalToLayerCoordinates(r1, out x1, out y1);
   path.AddLine((float)x0, (float)y0, (float)x1, (float)y1);
 }
Beispiel #40
0
 /// <summary>
 /// Draws an isoline beginning from a plane to the given point.
 /// </summary>
 /// <param name="path">Graphics path to fill with the isoline.</param>
 /// <param name="id">The logical plane to start drawing from.</param>
 /// <param name="r">Logical coordinates of the end point.</param>
 public virtual void GetIsolineFromPlaneToPoint(GraphicsPath path, CSPlaneID id, Logical3D r)
 {
     if (id.PerpendicularAxisNumber == 0)
     {
         GetIsoline(path, new Logical3D(id.LogicalValue, r.RY, r.RZ), r);
     }
     else if (id.PerpendicularAxisNumber == 1)
     {
         GetIsoline(path, new Logical3D(r.RX, id.LogicalValue, r.RZ), r);
     }
     else
     {
         GetIsoline(path, new Logical3D(r.RX, r.RY, id.LogicalValue), r);
     }
 }
Beispiel #41
0
 public override void GetIsoline(System.Drawing.Drawing2D.GraphicsPath g, Logical3D r0, Logical3D r1)
 {
     if (LogicalToLayerCoordinates(r0, out var ax0, out var ay0) && LogicalToLayerCoordinates(r1, out var ax1, out var ay1))
     {
         g.AddLine((float)ax0, (float)ay0, (float)ax1, (float)ay1);
     }
 }
Beispiel #42
0
 /// <summary>
 /// Draws an isoline beginning from a given point to a plane.
 /// </summary>
 /// <param name="g">Graphics to draw the isoline to.</param>
 /// <param name="pen">The pen to use.</param>
 /// <param name="r">Logical coordinate of the start point.</param>
 /// <param name="id">The logical plane to end the isoline.</param>
 public virtual void DrawIsolineFromPointToPlane(Graphics g, System.Drawing.Pen pen, Logical3D r, CSPlaneID id)
 {
     if (id.PerpendicularAxisNumber == 0)
     {
         DrawIsoline(g, pen, r, new Logical3D(id.LogicalValue, r.RY, r.RZ));
     }
     else if (id.PerpendicularAxisNumber == 1)
     {
         DrawIsoline(g, pen, r, new Logical3D(r.RX, id.LogicalValue, r.RZ));
     }
     else
     {
         DrawIsoline(g, pen, r, new Logical3D(r.RX, r.RY, id.LogicalValue));
     }
 }
Beispiel #43
0
        /// <summary>
        /// Paint the axis in the Graphics context.
        /// </summary>
        /// <param name="g">The graphics context painting to.</param>
        /// <param name="layer">The layer the axis belongs to.</param>
        /// <param name="styleInfo">The axis information of the axis to paint.</param>
        public void Paint(Graphics g, XYPlotLayer layer, CSAxisInformation styleInfo)
        {
            CSLineID styleID = styleInfo.Identifier;

            _cachedAxisStyleInfo = styleInfo.Clone();
            Scale axis = styleID.ParallelAxisNumber == 0 ? layer.XAxis : layer.YAxis;

            Logical3D r0 = styleID.Begin;
            Logical3D r1 = styleID.End;

            layer.CoordinateSystem.DrawIsoline(g, _axisPen, r0, r1);

            Logical3D outer;



            // now the major ticks
            PointF outVector;

            double[] majorticks = axis.GetMajorTicksNormal();
            for (int i = 0; i < majorticks.Length; i++)
            {
                double r = majorticks[i];

                if (_showFirstUpMajorTicks)
                {
                    outer = layer.CoordinateSystem.GetLogicalDirection(styleID.ParallelAxisNumber, CSAxisSide.FirstUp);
                    PointF tickorg = layer.CoordinateSystem.GetNormalizedDirection(r0, r1, r, outer, out outVector);
                    PointF tickend = tickorg;
                    tickend.X += outVector.X * _majorTickLength;
                    tickend.Y += outVector.Y * _majorTickLength;
                    g.DrawLine(_majorTickPen, tickorg, tickend);
                }
                if (_showFirstDownMajorTicks)
                {
                    outer = layer.CoordinateSystem.GetLogicalDirection(styleID.ParallelAxisNumber, CSAxisSide.FirstDown);
                    PointF tickorg = layer.CoordinateSystem.GetNormalizedDirection(r0, r1, r, outer, out outVector);
                    PointF tickend = tickorg;
                    tickend.X += outVector.X * _majorTickLength;
                    tickend.Y += outVector.Y * _majorTickLength;
                    g.DrawLine(_majorTickPen, tickorg, tickend);
                }
            }
            // now the major ticks
            double[] minorticks = axis.GetMinorTicksNormal();
            for (int i = 0; i < minorticks.Length; i++)
            {
                double r = minorticks[i];

                if (_showFirstUpMinorTicks)
                {
                    outer = layer.CoordinateSystem.GetLogicalDirection(styleID.ParallelAxisNumber, CSAxisSide.FirstUp);
                    PointF tickorg = layer.CoordinateSystem.GetNormalizedDirection(r0, r1, r, outer, out outVector);
                    PointF tickend = tickorg;
                    tickend.X += outVector.X * _minorTickLength;
                    tickend.Y += outVector.Y * _minorTickLength;
                    g.DrawLine(_minorTickPen, tickorg, tickend);
                }
                if (_showFirstDownMinorTicks)
                {
                    outer = layer.CoordinateSystem.GetLogicalDirection(styleID.ParallelAxisNumber, CSAxisSide.FirstDown);
                    PointF tickorg = layer.CoordinateSystem.GetNormalizedDirection(r0, r1, r, outer, out outVector);
                    PointF tickend = tickorg;
                    tickend.X += outVector.X * _minorTickLength;
                    tickend.Y += outVector.Y * _minorTickLength;
                    g.DrawLine(_minorTickPen, tickorg, tickend);
                }
            }
        }
Beispiel #44
0
 /// <summary>
 /// Draws an isoline on a plane beginning from r0 to r1. For r0,r1 either ry0,ry1 is used (if it is an x-axis),
 /// otherwise rx0,rx1 is used. The other parameter pair is not used.
 /// </summary>
 /// <param name="path">Graphics path to fill with the isoline.</param>
 /// <param name="r0">Logical coordinate of the start point.</param>
 /// <param name="r1">Logical coordinate of the end point.</param>
 /// <param name="id">The axis to end the isoline.</param>
 public virtual void GetIsolineOnPlane(GraphicsPath path, CSPlaneID id, Logical3D r0, Logical3D r1)
 {
     if (id.PerpendicularAxisNumber == 0)
     {
         GetIsoline(path, new Logical3D(id.LogicalValue, r0.RY, r0.RZ), new Logical3D(id.LogicalValue, r1.RY, r1.RZ));
     }
     else if (id.PerpendicularAxisNumber == 1)
     {
         GetIsoline(path, new Logical3D(r0.RX, id.LogicalValue, r0.RZ), new Logical3D(r1.RX, id.LogicalValue, r1.RZ));
     }
     else
     {
         GetIsoline(path, new Logical3D(r0.RX, r0.RY, id.LogicalValue), new Logical3D(r1.RX, r1.RY, id.LogicalValue));
     }
 }
Beispiel #45
0
        /// <summary>
        /// Paints the axis style labels.
        /// </summary>
        /// <param name="g">Graphics environment.</param>
        /// <param name="coordSyst">The coordinate system. Used to get the path along the axis.</param>
        /// <param name="scale">Scale.</param>
        /// <param name="tickSpacing">If not <c>null</c>, this parameter provides a custom tick spacing that is used instead of the default tick spacing of the scale.</param>
        /// <param name="styleInfo">Information about begin of axis, end of axis.</param>
        /// <param name="outerDistance">Distance between axis and labels.</param>
        /// <param name="useMinorTicks">If true, minor ticks are shown.</param>
        public virtual void Paint(IGraphicsContext3D g, G3DCoordinateSystem coordSyst, Scale scale, TickSpacing tickSpacing, CSAxisInformation styleInfo, double outerDistance, bool useMinorTicks)
        {
            _cachedAxisStyleInfo = styleInfo;
            CSLineID    styleID = styleInfo.Identifier;
            Scale       raxis   = scale;
            TickSpacing ticking = tickSpacing;

            var math = Matrix4x3.Identity;

            Logical3D r0 = styleID.GetLogicalPoint(styleInfo.LogicalValueAxisOrg);
            Logical3D r1 = styleID.GetLogicalPoint(styleInfo.LogicalValueAxisEnd);

            Logical3D outer;

            double[]        relpositions;
            AltaxoVariant[] ticks;
            if (useMinorTicks)
            {
                relpositions = ticking.GetMinorTicksNormal(raxis);
                ticks        = ticking.GetMinorTicksAsVariant();
            }
            else
            {
                relpositions = ticking.GetMajorTicksNormal(raxis);
                ticks        = ticking.GetMajorTicksAsVariant();
            }

            if (!_suppressedLabels.IsEmpty)
            {
                var filteredTicks        = new List <AltaxoVariant>();
                var filteredRelPositions = new List <double>();

                for (int i = 0; i < ticks.Length; i++)
                {
                    if (_suppressedLabels.ByValues.Contains(ticks[i]))
                    {
                        continue;
                    }
                    if (_suppressedLabels.ByNumbers.Contains(i))
                    {
                        continue;
                    }
                    if (_suppressedLabels.ByNumbers.Contains(i - ticks.Length))
                    {
                        continue;
                    }

                    filteredTicks.Add(ticks[i]);
                    filteredRelPositions.Add(relpositions[i]);
                }
                ticks        = filteredTicks.ToArray();
                relpositions = filteredRelPositions.ToArray();
            }

            IMeasuredLabelItem[] labels = _labelFormatting.GetMeasuredItems(g, _font, ticks);

            double     emSize        = _font.Size;
            CSAxisSide labelSide     = null != _labelSide ? _labelSide.Value : styleInfo.PreferredLabelSide;
            var        labelOutlines = new RectangularObjectOutline[ticks.Length];

            for (int i = 0; i < ticks.Length; i++)
            {
                double r = relpositions[i];

                if (!Altaxo.Calc.RMath.IsInIntervalCC(r, -1000, 1000))
                {
                    continue;
                }

                outer = coordSyst.GetLogicalDirection(styleID.ParallelAxisNumber, labelSide);
                PointD3D tickorg = coordSyst.GetPositionAndNormalizedDirection(r0, r1, r, outer, out var outVector);
                PointD3D tickend = tickorg + outVector * outerDistance;

                var msize = labels[i].Size;
                var morg  = tickend;

                if (_automaticRotationShift)
                {
                    // if this option is choosen, we have to find a shift value that shifts the center of the text outwards so that the bounding box of the text will not cross the plane that is
                    // defined by the tickend point and the normal vector outVector

                    // Assume that the text is now centered x, y, and z around the point tickend (but here we use origin instead tickend)
                    math = Matrix4x3.NewRotation(_rotationX, _rotationY, _rotationZ);
                    // we have to find all points with negative distance to the plane spanned by tickend and the vector outVector (but again instead of tickend we use origin)
                    var msizePad = msize + new VectorD3D(
                        (_font.Size * 1) / 3,                                            // whereas above and below text no padding is neccessary, it is optically nicer to have left and right padding of the string by 1/6 of font size.
                        0,
                        (_font.Size * 1) / 3                                             // same padding applies to z
                        );
                    var crect = new RectangleD3D((PointD3D)(-0.5 * msizePad), msizePad); // our text centered around origin

                    double shift = 0;
                    foreach (PointD3D p in crect.Vertices)
                    {
                        PointD3D ps       = math.Transform(p);
                        double   distance = Math3D.GetDistancePointToPlane(ps, PointD3D.Empty, outVector);
                        if (-distance > shift)
                        {
                            shift = -distance; // only negative distances will count here
                        }
                    }
                    morg += outVector * shift;
                }
                else
                {
                    morg = morg.WithXPlus(outVector.X * _font.Size / 3);
                }

                var mrect = new RectangleD3D(morg, msize);
                if (_automaticRotationShift)
                {
                    mrect = AdjustRectangle(mrect, Alignment.Center, Alignment.Center, Alignment.Center);
                }
                else
                {
                    mrect = AdjustRectangle(mrect, _alignmentX, _alignmentY, _alignmentZ);
                }

                math = Matrix4x3.Identity;
                math.TranslatePrepend(morg.X, morg.Y, morg.Z);

                if (_rotationZ != 0)
                {
                    math.RotationZDegreePrepend(_rotationZ);
                }
                if (_rotationY != 0)
                {
                    math.RotationYDegreePrepend(_rotationY);
                }
                if (_rotationX != 0)
                {
                    math.RotationXDegreePrepend(_rotationX);
                }

                math.TranslatePrepend((mrect.X - morg.X + emSize * _offsetX), (mrect.Y - morg.Y + emSize * _offsetY), (mrect.Z - morg.Z + emSize * _offsetZ));

                var gs = g.SaveGraphicsState();
                g.PrependTransform(math);

                if (_backgroundStyle != null)
                {
                    var itemRectangle = new RectangleD3D(PointD3D.Empty, msize);
                    _backgroundStyle.Measure(itemRectangle);
                    _backgroundStyle.Draw(g, itemRectangle);
                }

                labels[i].Draw(g, _brush, PointD3D.Empty);
                labelOutlines[i] = new RectangularObjectOutline(new RectangleD3D(PointD3D.Empty, msize), math);
                g.RestoreGraphicsState(gs); // Restore the graphics state
            }

            _cachedLabelOutlines = labelOutlines;
        }
Beispiel #46
0
 /// <summary>
 /// Calculates from two logical values (values between 0 and 1) the coordinates of the point. Returns true if the conversion
 /// is possible, otherwise false.
 /// </summary>
 /// <param name="r">The logical position value.</param>
 /// <param name="xlocation">On return, gives the x coordinate of the converted value (for instance location).</param>
 /// <param name="ylocation">On return, gives the y coordinate of the converted value (for instance location).</param>
 /// <returns>True if the conversion was successfull, false if the conversion was not possible.</returns>
 public abstract bool LogicalToLayerCoordinates(Logical3D r, out double xlocation, out double ylocation);
Beispiel #47
0
        public void PaintPreprocessing(System.Drawing.Graphics g, IPaintContext paintContext, IPlotArea layer, PlotItemCollection coll)
        {
            var paintData = new CachedPaintData
            {
                _clippingColl = new System.Drawing.Region[coll.Count],
                _plotDataColl = new Processed2DPlotData[coll.Count],
                _xincColl     = new double[coll.Count],
                _yincColl     = new double[coll.Count]
            };

            paintContext.AddValue(this, paintData);

            // First prepare
            int idx = -1;
            Processed2DPlotData previousPlotData = null;

            for (int i = 0; i < coll.Count; i++)
            {
                if (coll[i] is G2DPlotItem)
                {
                    idx++;
                    double currxinc = paintData._xincColl[i] = idx * _xinc * _scaleXInc;
                    double curryinc = paintData._yincColl[i] = idx * _yinc * _scaleYInc;

                    var gpi = coll[i] as G2DPlotItem;
                    Processed2DPlotData plotdata = paintData._plotDataColl[i] = gpi.GetRangesAndPoints(layer);
                    plotdata.PreviousItemData = previousPlotData;
                    previousPlotData          = plotdata;

                    int j = -1;
                    foreach (int rowIndex in plotdata.RangeList.OriginalRowIndices())
                    {
                        j++;

                        AltaxoVariant xx = plotdata.GetXPhysical(rowIndex) + currxinc;
                        AltaxoVariant yy = plotdata.GetYPhysical(rowIndex) + curryinc;

                        var rel = new Logical3D(layer.XAxis.PhysicalVariantToNormal(xx), layer.YAxis.PhysicalVariantToNormal(yy));
                        layer.CoordinateSystem.LogicalToLayerCoordinates(rel, out var xabs, out var yabs);
                        plotdata.PlotPointsInAbsoluteLayerCoordinates[j] = new System.Drawing.PointF((float)xabs, (float)yabs);
                    }

                    // if clipping is used, we must get a clipping region for every plot item
                    // and combine the regions from
                    if (_useClipping)
                    {
                        if (i == 0)
                        {
                            paintData._clippingColl[i] = g.Clip;
                        }

                        Plot.Styles.LinePlotStyle linestyle = null;
                        foreach (Plot.Styles.IG2DPlotStyle st in gpi.Style)
                        {
                            if (st is Plot.Styles.LinePlotStyle)
                            {
                                linestyle = st as Plot.Styles.LinePlotStyle;
                                break;
                            }
                        }

                        if (null != linestyle)
                        {
                            var path = new System.Drawing.Drawing2D.GraphicsPath();
                            linestyle.GetFillPath(path, layer, plotdata, CSPlaneID.Bottom);
                            if ((i + 1) < paintData._clippingColl.Length)
                            {
                                paintData._clippingColl[i + 1] = paintData._clippingColl[i].Clone();
                                paintData._clippingColl[i + 1].Exclude(path);
                            }
                        }
                        else
                        {
                            if ((i + 1) < paintData._clippingColl.Length)
                            {
                                paintData._clippingColl[i + 1] = paintData._clippingColl[i];
                            }
                        }
                    }
                }
            }
        }
Beispiel #48
0
 /// <summary>
 /// Gets a iso line in a path object.
 /// </summary>
 /// <param name="r0">Starting position in logical coordinates.</param>
 /// <param name="r1">End position in logical coordinates.</param>
 /// <returns>The graphics path for the isoline.</returns>
 public abstract IPolylineD3D GetIsoline(Logical3D r0, Logical3D r1);
    public override bool LogicalToLayerCoordinatesAndDirection(
      Logical3D r0, Logical3D r1,
      double t,
      out double ax, out double ay, out double adx, out double ady)
    {
      if (_isXreverse)
      {
        r0.RX = 1 - r0.RX;
        r1.RX = 1 - r1.RX;
      }
      if (_isYreverse)
      {
        r0.RY = 1 - r0.RY;
        r1.RY = 1 - r1.RY;
      }
      if (_isXYInterchanged)
      {
        double hr0 = r0.RX;
        r0.RX = r0.RY;
        r0.RY = hr0;

        double hr1 = r1.RX;
        r1.RX = r1.RY;
        r1.RY = hr1;
      }

      double rx = r0.RX + t * (r1.RX - r0.RX);
      double ry = r0.RY + t * (r1.RY - r0.RY);
      double phi = -2 * Math.PI * rx;
      double rad = _radius * ry;

      ax = _midX + rad * Math.Cos(phi);
      ay = _midY + rad * Math.Sin(phi);

      adx = _radius * ((r1.RY - r0.RY) * Math.Cos(phi) + 2 * Math.PI * (r1.RX - r0.RX) * ry * Math.Sin(phi));
      ady = _radius * ((r1.RY - r0.RY) * Math.Sin(phi) - 2 * Math.PI * (r1.RX - r0.RX) * ry * Math.Cos(phi));

      return !double.IsNaN(ax) && !double.IsNaN(ay);
    }
Beispiel #50
0
 /// <summary>
 /// Calculates from two logical values (values between 0 and 1) the coordinates of the point. Returns true if the conversion
 /// is possible, otherwise false.
 /// </summary>
 /// <param name="r">The logical position value.</param>
 /// <param name="location">On return, gives the coordinates of the converted value (for instance location).</param>
 /// <returns>True if the conversion was successfull, false if the conversion was not possible.</returns>
 public abstract bool LogicalToLayerCoordinates(Logical3D r, out PointD3D location);
 public override void GetIsoline(System.Drawing.Drawing2D.GraphicsPath g, Logical3D r0, Logical3D r1)
 {
   double ax0, ax1, ay0, ay1;
   if (LogicalToLayerCoordinates(r0, out ax0, out ay0) && LogicalToLayerCoordinates(r1, out ax1, out ay1))
   {
     // add a line when this is a radial ray
     if (((r0.RX == r1.RX) && !_isXYInterchanged) || ((r0.RY == r1.RY) && _isXYInterchanged))
     {
       g.AddLine((float)ax0, (float)ay0, (float)ax1, (float)ay1);
     }
     // add an arc if this is a tangential ray
     else if (((r0.RY == r1.RY) && !_isXYInterchanged) || ((r0.RX == r1.RX) && _isXYInterchanged))
     {
       double startAngle = 180 * Math.Atan2(_midY - ay0, ax0 - _midX) / Math.PI;
       double sweepAngle;
       if (_isXYInterchanged)
       {
         sweepAngle = (r1.RY - r0.RY) * 360;
         if (_isYreverse)
           sweepAngle = -sweepAngle;
       }
       else
       {
         sweepAngle = (r1.RX - r0.RX) * 360;
         if (_isXreverse)
           sweepAngle = -sweepAngle;
       }
       double r = Calc.RMath.Hypot(_midY - ay0, ax0 - _midX);
       if (r > 0)
         g.AddArc((float)(_midX - r), (float)(_midY - r), (float)(2 * r), (float)(2 * r), (float)-startAngle, (float)-sweepAngle);
     }
     else // if it is neither radial nor tangential
     {
       int points = _isXYInterchanged ? (int)(Math.Abs(r1.RY - r0.RY) * 360) : (int)(Math.Abs(r1.RX - r0.RX) * 360);
       points = Math.Max(1, Math.Min(points, 3600)); // in case there is a rotation more than one turn limit the number of points
       PointF[] pts = new PointF[points + 1];
       for (int i = 0; i <= points; i++)
       {
         Logical3D r = new Logical3D(r0.RX + i * (r1.RX - r0.RX) / points, r0.RY + i * (r1.RY - r0.RY) / points);
         double ax, ay;
         LogicalToLayerCoordinates(r, out ax, out ay);
         pts[i] = new PointF((float)ax, (float)ay);
       }
       g.AddLines(pts);
     }
   }
 }
Beispiel #52
0
 /// <summary>
 /// Converts logical coordinates along an isoline to layer coordinates and the appropriate derivative.
 /// </summary>
 /// <param name="r0">Logical position of starting point of the isoline.</param>
 /// <param name="r1">Logical position of end point of the isoline.</param>
 /// <param name="t">Parameter between 0 and 1 that determines the point on the isoline.
 /// A value of 0 denotes the starting point of the isoline, a value of 1 the end point. The logical
 /// coordinates are linear interpolated between starting point and end point.</param>
 /// <param name="position">Layer coordinate of the isoline point.</param>
 /// <param name="direction">Derivative of layer coordinate with respect to parameter t at the point <paramref name="position"/>.</param>
 /// <returns>True if the conversion was sucessfull, otherwise false.</returns>
 public abstract bool LogicalToLayerCoordinatesAndDirection(
     Logical3D r0, Logical3D r1,
     double t,
     out PointD3D position, out VectorD3D direction);
 public override bool LayerToLogicalCoordinates(double xlocation, double ylocation, out Logical3D r)
 {
     throw new Exception("The method or operation is not implemented.");
 }
Beispiel #54
0
 /// <summary>
 /// Calculates from two  coordinates of a point the logical values (values between 0 and 1). Returns true if the conversion
 /// is possible, otherwise false.
 /// </summary>
 /// <param name="location">The x coordinate of the converted value (for instance location).</param>
 /// <param name="r">The computed logical position value.</param>
 /// <returns>True if the conversion was successfull, false if the conversion was not possible. For 3D coordinate systems,
 /// the relative values of x and y with z=0 should be returned.</returns>
 public abstract bool LayerToLogicalCoordinates(PointD3D location, out Logical3D r);
Beispiel #55
0
 public override IPolylineD3D GetIsoline(Logical3D r0, Logical3D r1)
 {
     LogicalToLayerCoordinates(r0, out var pt0);
     LogicalToLayerCoordinates(r1, out var pt1);
     return(new StraightLineAsPolylineD3D(pt0, pt1));
 }
Beispiel #56
0
		// CoordinateSystem is not affine, or scales are non-linear
		private void BuildImageV3(Graphics gfrx, IPlotArea gl,
			IROVector lx,
			IROVector ly,
			IROMatrix vcolumns)
		{
			// allocate a bitmap of same dimensions than the underlying layer
			_imageType = CachedImageType.Other;

			int dimX = (int)Math.Ceiling(gl.Size.X / 72.0 * gfrx.DpiX);
			int dimY = (int)Math.Ceiling(gl.Size.Y / 72.0 * gfrx.DpiY);

			dimX = Math.Min(2048, dimX);
			dimY = Math.Min(2048, dimY);

			// look if the image has the right dimensions
			if (null == _cachedImage || _cachedImage.Width != dimX || _cachedImage.Height != dimY)
			{
				if (null != _cachedImage)
					_cachedImage.Dispose();

				// please notice: the horizontal direction of the image is related to the row index!!! (this will turn the image in relation to the table)
				// and the vertical direction of the image is related to the column index
				_cachedImage = new System.Drawing.Bitmap(dimX, dimY, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
			}

			byte[] imageBytes = new byte[dimX * dimY * 4];

			double widthByDimX = gl.Size.X / dimX;
			double heightByDimY = gl.Size.Y / dimY;
			Logical3D rel = new Logical3D();

			double minRX = lx[0];
			double maxRX = lx[lx.Length - 1];
			double minRY = ly[0];
			double maxRY = ly[ly.Length - 1];

			if (minRX > maxRX)
			{
				double h = minRX;
				minRX = maxRX;
				maxRX = h;
			}
			if (minRY > maxRY)
			{
				double h = minRY;
				minRY = maxRY;
				maxRY = h;
			}

			BivariateLinearSpline interpol = new BivariateLinearSpline(lx, ly, vcolumns);

			Color colorInvalid = _colorProvider.GetColor(double.NaN);

			int addr = 0;
			for (int ny = 0; ny < dimY; ny++)
			{
				double py = (ny + 0.5) * heightByDimY;

				for (int nx = 0; nx < dimX; nx++, addr += 4)
				{
					double px = (nx + 0.5) * widthByDimX;

					if (false == gl.CoordinateSystem.LayerToLogicalCoordinates(px, py, out rel))
					{
						_cachedImage.SetPixel(nx, ny, colorInvalid);
					}
					else // conversion to relative coordinates was possible
					{
						double rx = rel.RX;
						double ry = rel.RY;

						if (rx < minRX || rx > maxRX || ry < minRY || ry > maxRY)
						{
							//_cachedImage.SetPixel(nx, ny, _colorInvalid);
							imageBytes[addr + 0] = colorInvalid.B;
							imageBytes[addr + 1] = colorInvalid.G;
							imageBytes[addr + 2] = colorInvalid.R;
							imageBytes[addr + 3] = colorInvalid.A;
						}
						else
						{
							double val = interpol.Interpolate(rx, ry);
							if (double.IsNaN(val))
							{
								//_cachedImage.SetPixel(nx, ny, _colorInvalid);
								imageBytes[addr + 0] = colorInvalid.B;
								imageBytes[addr + 1] = colorInvalid.G;
								imageBytes[addr + 2] = colorInvalid.R;
								imageBytes[addr + 3] = colorInvalid.A;
							}
							else
							{
								//_cachedImage.SetPixel(nx, ny, GetColor(val));
								Color c = GetColor(val);
								imageBytes[addr + 0] = c.B;
								imageBytes[addr + 1] = c.G;
								imageBytes[addr + 2] = c.R;
								imageBytes[addr + 3] = c.A;
							}
						}
					}
				}
			}

			// Lock the bitmap's bits.
			Rectangle rect = new Rectangle(0, 0, _cachedImage.Width, _cachedImage.Height);
			System.Drawing.Imaging.BitmapData bmpData =
					_cachedImage.LockBits(rect, System.Drawing.Imaging.ImageLockMode.WriteOnly,
					_cachedImage.PixelFormat);

			// Get the address of the first line.
			IntPtr ptr = bmpData.Scan0;

			// Copy the RGB values back to the bitmap
			System.Runtime.InteropServices.Marshal.Copy(imageBytes, 0, ptr, imageBytes.Length);

			_cachedImage.UnlockBits(bmpData);
		}
Beispiel #57
0
        public override void GetIsoline(System.Drawing.Drawing2D.GraphicsPath g, Logical3D r0, Logical3D r1)
        {
            double ax0, ax1, ay0, ay1;

            if (LogicalToLayerCoordinates(r0, out ax0, out ay0) && LogicalToLayerCoordinates(r1, out ax1, out ay1))
            {
                // add a line when this is a radial ray
                if (((r0.RX == r1.RX) && !_isXYInterchanged) || ((r0.RY == r1.RY) && _isXYInterchanged))
                {
                    g.AddLine((float)ax0, (float)ay0, (float)ax1, (float)ay1);
                }
                // add an arc if this is a tangential ray
                else if (((r0.RY == r1.RY) && !_isXYInterchanged) || ((r0.RX == r1.RX) && _isXYInterchanged))
                {
                    double startAngle = 180 * Math.Atan2(_midY - ay0, ax0 - _midX) / Math.PI;
                    double sweepAngle;
                    if (_isXYInterchanged)
                    {
                        sweepAngle = (r1.RY - r0.RY) * 360;
                        if (_isYreverse)
                        {
                            sweepAngle = -sweepAngle;
                        }
                    }
                    else
                    {
                        sweepAngle = (r1.RX - r0.RX) * 360;
                        if (_isXreverse)
                        {
                            sweepAngle = -sweepAngle;
                        }
                    }
                    double r = Calc.RMath.Hypot(_midY - ay0, ax0 - _midX);
                    if (r > 0)
                    {
                        g.AddArc((float)(_midX - r), (float)(_midY - r), (float)(2 * r), (float)(2 * r), (float)-startAngle, (float)-sweepAngle);
                    }
                }
                else // if it is neither radial nor tangential
                {
                    int points = _isXYInterchanged ? (int)(Math.Abs(r1.RY - r0.RY) * 360) : (int)(Math.Abs(r1.RX - r0.RX) * 360);
                    points = Math.Max(1, Math.Min(points, 3600)); // in case there is a rotation more than one turn limit the number of points
                    PointF[] pts = new PointF[points + 1];
                    for (int i = 0; i <= points; i++)
                    {
                        Logical3D r = new Logical3D(r0.RX + i * (r1.RX - r0.RX) / points, r0.RY + i * (r1.RY - r0.RY) / points);
                        double    ax, ay;
                        LogicalToLayerCoordinates(r, out ax, out ay);
                        pts[i] = new PointF((float)ax, (float)ay);
                    }
                    g.AddLines(pts);
                }
            }
        }
Beispiel #58
0
        /// <summary>
        /// Paint the axis in the Graphics context.
        /// </summary>
        /// <param name="g">The graphics context painting to.</param>
        /// <param name="layer">The layer the axis belongs to.</param>
        /// <param name="styleInfo">The axis information of the axis to paint.</param>
        /// <param name="customTickSpacing">If not <c>null</c>, this parameter provides a custom tick spacing that is used instead of the default tick spacing of the scale.</param>
        public void Paint(Graphics g, IPlotArea layer, CSAxisInformation styleInfo, TickSpacing customTickSpacing)
        {
            CSLineID styleID = styleInfo.Identifier;

            _cachedAxisStyleInfo = styleInfo;
            Scale axis = layer.Scales[styleID.ParallelAxisNumber];

            TickSpacing ticking = null != customTickSpacing ? customTickSpacing : layer.Scales[styleID.ParallelAxisNumber].TickSpacing;

            Logical3D r0 = styleID.GetLogicalPoint(styleInfo.LogicalValueAxisOrg);
            Logical3D r1 = styleID.GetLogicalPoint(styleInfo.LogicalValueAxisEnd);

            layer.CoordinateSystem.DrawIsoline(g, _axisPen, r0, r1);

            Logical3D outer;

            // now the major ticks
            PointD2D outVector;

            double[] majorticks = ticking.GetMajorTicksNormal(axis);
            for (int i = 0; i < majorticks.Length; i++)
            {
                double r = majorticks[i];

                if (_showFirstUpMajorTicks)
                {
                    outer = layer.CoordinateSystem.GetLogicalDirection(styleID.ParallelAxisNumber, CSAxisSide.FirstUp);
                    var tickorg = layer.CoordinateSystem.GetNormalizedDirection(r0, r1, r, outer, out outVector);
                    var tickend = tickorg + outVector * _majorTickLength;
                    g.DrawLine(_majorTickPen, (PointF)tickorg, (PointF)tickend);
                }
                if (_showFirstDownMajorTicks)
                {
                    outer = layer.CoordinateSystem.GetLogicalDirection(styleID.ParallelAxisNumber, CSAxisSide.FirstDown);
                    var tickorg = layer.CoordinateSystem.GetNormalizedDirection(r0, r1, r, outer, out outVector);
                    var tickend = tickorg + outVector * _majorTickLength;
                    g.DrawLine(_majorTickPen, (PointF)tickorg, (PointF)tickend);
                }
            }
            // now the major ticks
            double[] minorticks = ticking.GetMinorTicksNormal(axis);
            for (int i = 0; i < minorticks.Length; i++)
            {
                double r = minorticks[i];

                if (_showFirstUpMinorTicks)
                {
                    outer = layer.CoordinateSystem.GetLogicalDirection(styleID.ParallelAxisNumber, CSAxisSide.FirstUp);
                    var tickorg = layer.CoordinateSystem.GetNormalizedDirection(r0, r1, r, outer, out outVector);
                    var tickend = tickorg + outVector * _minorTickLength;
                    g.DrawLine(_minorTickPen, (PointF)tickorg, (PointF)tickend);
                }
                if (_showFirstDownMinorTicks)
                {
                    outer = layer.CoordinateSystem.GetLogicalDirection(styleID.ParallelAxisNumber, CSAxisSide.FirstDown);
                    var tickorg = layer.CoordinateSystem.GetNormalizedDirection(r0, r1, r, outer, out outVector);
                    var tickend = tickorg + outVector * _minorTickLength;
                    g.DrawLine(_minorTickPen, (PointF)tickorg, (PointF)tickend);
                }
            }
        }
Beispiel #59
0
		public void PaintPreprocessing(IPaintContext paintContext, IPlotArea layer, PlotItemCollection coll)
		{
			Dictionary<G3DPlotItem, Processed3DPlotData> plotDataDict = null;
			if (!CanUseStyle(layer, coll, out plotDataDict))
			{
				return;
			}
			else
			{
				paintContext.AddValue(this, plotDataDict);
			}

			AltaxoVariant[] vArray = null;
			// First, add up all items since we start always with the last item
			int idx = -1;
			Processed3DPlotData previousItemData = null;
			foreach (IGPlotItem pi in coll)
			{
				if (pi is G3DPlotItem)
				{
					idx++;

					G3DPlotItem gpi = pi as G3DPlotItem;
					Processed3DPlotData pdata = plotDataDict[gpi];
					vArray = AddUp(vArray, pdata);

					if (idx > 0) // this is not the first item
					{
						int j = -1;
						foreach (int originalIndex in pdata.RangeList.OriginalRowIndices())
						{
							j++;
							Logical3D rel = new Logical3D(
							layer.XAxis.PhysicalVariantToNormal(pdata.GetXPhysical(originalIndex)),
							layer.YAxis.PhysicalVariantToNormal(pdata.GetYPhysical(originalIndex)),
							layer.ZAxis.PhysicalVariantToNormal(vArray[j]));

							PointD3D pabs;
							layer.CoordinateSystem.LogicalToLayerCoordinates(rel, out pabs);
							pdata.PlotPointsInAbsoluteLayerCoordinates[j] = pabs;
						}
					}

					// we have also to exchange the accessor for the physical y value and replace it by our own one
					AltaxoVariant[] localArray = (AltaxoVariant[])vArray.Clone();
					LocalArrayHolder localArrayHolder = new LocalArrayHolder(localArray, pdata);
					pdata.ZPhysicalAccessor = localArrayHolder.GetPhysical;
					pdata.PreviousItemData = previousItemData;
					previousItemData = pdata;
				}
			}
		}
        public void Paint(System.Drawing.Graphics g, IPlotArea layer, PlotItemCollection coll)
        {
            Dictionary <G2DPlotItem, Processed2DPlotData> plotDataDict;

            if (!CanUseStyle(layer, coll, out plotDataDict))
            {
                CoordinateTransformingStyleBase.Paint(g, layer, coll);
                return;
            }

            AltaxoVariant[] ysumArray = null;
            foreach (IGPlotItem pi in coll)
            {
                if (pi is G2DPlotItem)
                {
                    G2DPlotItem         gpi   = pi as G2DPlotItem;
                    Processed2DPlotData pdata = plotDataDict[gpi];
                    ysumArray = AbsoluteStackTransform.AddUp(ysumArray, pdata);
                }
            }



            // now plot the data - the summed up y is in yArray
            AltaxoVariant[]     yArray           = null;
            Processed2DPlotData previousItemData = null;

            foreach (IGPlotItem pi in coll)
            {
                if (pi is G2DPlotItem)
                {
                    G2DPlotItem         gpi   = pi as G2DPlotItem;
                    Processed2DPlotData pdata = plotDataDict[gpi];
                    yArray = AbsoluteStackTransform.AddUp(yArray, pdata);
                    AltaxoVariant[] localArray = new AltaxoVariant[yArray.Length];

                    int j = -1;
                    foreach (int originalIndex in pdata.RangeList.OriginalRowIndices())
                    {
                        j++;
                        AltaxoVariant y = 100 * yArray[j] / ysumArray[j];
                        localArray[j] = y;

                        Logical3D rel = new Logical3D(
                            layer.XAxis.PhysicalVariantToNormal(pdata.GetXPhysical(originalIndex)),
                            layer.YAxis.PhysicalVariantToNormal(y));

                        double xabs, yabs;
                        layer.CoordinateSystem.LogicalToLayerCoordinates(rel, out xabs, out yabs);
                        pdata.PlotPointsInAbsoluteLayerCoordinates[j] = new System.Drawing.PointF((float)xabs, (float)yabs);
                    }
                    // we have also to exchange the accessor for the physical y value and replace it by our own one
                    pdata.YPhysicalAccessor = new IndexedPhysicalValueAccessor(delegate(int i) { return(localArray[i]); });
                    pdata.PreviousItemData  = previousItemData;
                    previousItemData        = pdata;
                }
            }

            for (int i = coll.Count - 1; i >= 0; --i)
            {
                IGPlotItem pi = coll[i];
                if (pi is G2DPlotItem)
                {
                    G2DPlotItem         gpi   = pi as G2DPlotItem;
                    Processed2DPlotData pdata = plotDataDict[gpi];
                    gpi.Paint(g, layer, pdata);
                }
                else
                {
                    pi.Paint(g, layer);
                }
            }
        }