Click here to Skip to main content
15,893,814 members
Articles / Programming Languages / C++

A Normal / Exponential Random Generator and Histogram Class

Rate me:
Please Sign up or sign in to vote.
4.73/5 (11 votes)
2 Dec 20024 min read 276.7K   8.1K   55  
A fast random generator with normal or exponential distribution + a histogram class
In this article, you will find a fast generator for Random Variable, namely normal and exponential distributions. It is based on George Marsaglia's and Wai Wan Tsang's work.
/**************************************************************************\
* 
* Copyright (c) 1998-2001, Microsoft Corp.  All Rights Reserved.
*
* Module Name:
*
*   GdiplusPen.h
*
* Abstract:
*
*   GDI+ Pen class
*
\**************************************************************************/
#ifndef _GDIPLUSPEN_H
#define _GDIPLUSPEN_H

//--------------------------------------------------------------------------
// Pen class
//--------------------------------------------------------------------------

class Pen : public GdiplusBase
{
public:
    friend class GraphicsPath;
    friend class Graphics;

    Pen(IN const Color& color, 
        IN REAL width = 1.0f)
    {
        Unit unit = UnitWorld;
        nativePen = NULL;
        lastResult = DllExports::GdipCreatePen1(color.GetValue(),
                                    width, unit, &nativePen);
    }

    Pen(IN const Brush* brush, 
        IN REAL width = 1.0f)
    {
        Unit unit = UnitWorld;
        nativePen = NULL;
        lastResult = DllExports::GdipCreatePen2(brush->nativeBrush,
                                    width, unit, &nativePen);
    }

    ~Pen()
    {
        DllExports::GdipDeletePen(nativePen);
    }

    Pen* Clone() const
    {
        GpPen *clonePen = NULL;

        lastResult = DllExports::GdipClonePen(nativePen, &clonePen);
   
        return new Pen(clonePen, lastResult);
    }

    Status SetWidth(IN REAL width)
    {
        return SetStatus(DllExports::GdipSetPenWidth(nativePen, width));
    }

    REAL GetWidth() const
    {
        REAL width;

        SetStatus(DllExports::GdipGetPenWidth(nativePen, &width));
        
        return width;
    }
    
    // Set/get line caps: start, end, and dash

    // Line cap and join APIs by using LineCap and LineJoin enums.

    Status SetLineCap(IN LineCap startCap, 
                      IN LineCap endCap, 
                      IN DashCap dashCap)
    {
        return SetStatus(DllExports::GdipSetPenLineCap197819(nativePen, 
                                   startCap, endCap, dashCap));
    }

    Status SetStartCap(IN LineCap startCap)
    {
        return SetStatus(DllExports::GdipSetPenStartCap(nativePen, startCap));
    }

    Status SetEndCap(IN LineCap endCap)
    {
        return SetStatus(DllExports::GdipSetPenEndCap(nativePen, endCap));
    }

    Status SetDashCap(IN DashCap dashCap)
    {
        return SetStatus(DllExports::GdipSetPenDashCap197819(nativePen,
                                   dashCap));
    }

    LineCap GetStartCap() const
    {
        LineCap startCap;

        SetStatus(DllExports::GdipGetPenStartCap(nativePen, &startCap));
        
        return startCap;
    }

    LineCap GetEndCap() const
    {
        LineCap endCap;

        SetStatus(DllExports::GdipGetPenEndCap(nativePen, &endCap));

        return endCap;
    }

    DashCap GetDashCap() const
    {
        DashCap dashCap;

        SetStatus(DllExports::GdipGetPenDashCap197819(nativePen,
                            &dashCap));

        return dashCap;
    }

    Status SetLineJoin(IN LineJoin lineJoin)
    {
        return SetStatus(DllExports::GdipSetPenLineJoin(nativePen, lineJoin));
    }

    LineJoin GetLineJoin() const
    {
        LineJoin lineJoin;
        
        SetStatus(DllExports::GdipGetPenLineJoin(nativePen, &lineJoin));
        
        return lineJoin;
    }

    Status SetCustomStartCap(IN const CustomLineCap* customCap)
    {
        GpCustomLineCap* nativeCap = NULL;
        if(customCap)
            nativeCap = customCap->nativeCap;

        return SetStatus(DllExports::GdipSetPenCustomStartCap(nativePen, 
                                                              nativeCap));
    }

    Status GetCustomStartCap(OUT CustomLineCap* customCap) const
    {
        if(!customCap)
            return SetStatus(InvalidParameter);

        return SetStatus(DllExports::GdipGetPenCustomStartCap(nativePen, 
                                                    &(customCap->nativeCap)));
    }

    Status SetCustomEndCap(IN const CustomLineCap* customCap)
    {
        GpCustomLineCap* nativeCap = NULL;
        if(customCap)
            nativeCap = customCap->nativeCap;

        return SetStatus(DllExports::GdipSetPenCustomEndCap(nativePen, 
                                                            nativeCap));
    }

    Status GetCustomEndCap(OUT CustomLineCap* customCap) const
    {
        if(!customCap)
            return SetStatus(InvalidParameter);

        return SetStatus(DllExports::GdipGetPenCustomEndCap(nativePen, 
                                                    &(customCap->nativeCap)));
    }

    Status SetMiterLimit(IN REAL miterLimit)
    {
        return SetStatus(DllExports::GdipSetPenMiterLimit(nativePen, 
                                                    miterLimit));
    }

    REAL GetMiterLimit() const
    {
        REAL miterLimit;

        SetStatus(DllExports::GdipGetPenMiterLimit(nativePen, &miterLimit));

        return miterLimit;
    }

    Status SetAlignment(IN PenAlignment penAlignment)
    {
        return SetStatus(DllExports::GdipSetPenMode(nativePen, penAlignment));
    }

    PenAlignment GetAlignment() const
    {
        PenAlignment penAlignment;
        
        SetStatus(DllExports::GdipGetPenMode(nativePen, &penAlignment));
        
        return penAlignment;
    }
    
    Status SetTransform(IN const Matrix* matrix)
    {
        return SetStatus(DllExports::GdipSetPenTransform(nativePen, 
                                                       matrix->nativeMatrix));
    }

    Status GetTransform(OUT Matrix* matrix) const
    {
        return SetStatus(DllExports::GdipGetPenTransform(nativePen, 
                                                         matrix->nativeMatrix));
    }

    Status ResetTransform()
    {
        return SetStatus(DllExports::GdipResetPenTransform(nativePen));
    }

    Status MultiplyTransform(IN const Matrix* matrix,
                             IN MatrixOrder order = MatrixOrderPrepend)
    {
        return SetStatus(DllExports::GdipMultiplyPenTransform(nativePen,
                                                         matrix->nativeMatrix,
                                                         order));
    }

    Status TranslateTransform(IN REAL dx, 
                              IN REAL dy,
                              IN MatrixOrder order = MatrixOrderPrepend)
    {
        return SetStatus(DllExports::GdipTranslatePenTransform(nativePen,
                                                               dx, 
                                                               dy, 
                                                               order));
    }

    Status ScaleTransform(IN REAL sx, 
                          IN REAL sy,
                          IN MatrixOrder order = MatrixOrderPrepend)
    {
        return SetStatus(DllExports::GdipScalePenTransform(nativePen,
                                                           sx, 
                                                           sy, 
                                                           order));
    }

    Status RotateTransform(IN REAL angle, 
                           IN MatrixOrder order = MatrixOrderPrepend)
    {
        return SetStatus(DllExports::GdipRotatePenTransform(nativePen,
                                                            angle, 
                                                            order));
    }

    PenType GetPenType() const
    {
       PenType type;
       SetStatus(DllExports::GdipGetPenFillType(nativePen, &type));

       return type;
    }

    Status SetColor(IN const Color& color)
    {
        return SetStatus(DllExports::GdipSetPenColor(nativePen,
                                                     color.GetValue()));
    }

    Status SetBrush(IN const Brush* brush)
    {
        return SetStatus(DllExports::GdipSetPenBrushFill(nativePen, 
                                       brush->nativeBrush));
    }

    Status GetColor(OUT Color* color) const
    {
        if (color == NULL) 
        {
            return SetStatus(InvalidParameter);
        }
        
        PenType type = GetPenType();

        if (type != PenTypeSolidColor) 
        {
            return WrongState;
        }
        
        ARGB argb;
        
        SetStatus(DllExports::GdipGetPenColor(nativePen,
                                              &argb));
        if (lastResult == Ok)
        {
            color->SetValue(argb);
        }
        
        return lastResult;
    }

    Brush* GetBrush() const
    {
       PenType type = GetPenType();

       Brush* brush = NULL;

       switch(type)
       {
       case PenTypeSolidColor:
           brush = new SolidBrush();
           break;

       case PenTypeHatchFill:
           brush = new HatchBrush();
           break;

       case PenTypeTextureFill:
           brush = new TextureBrush();
           break;

       case PenTypePathGradient:
           brush = new Brush();
           break;

       case PenTypeLinearGradient:
           brush = new LinearGradientBrush();
           break;

       default:
           break;
       }

       if(brush)
       {
           GpBrush* nativeBrush;

           SetStatus(DllExports::GdipGetPenBrushFill(nativePen, 
                                                     &nativeBrush));
           brush->SetNativeBrush(nativeBrush);
       }

       return brush;
    }

    DashStyle GetDashStyle() const
    {
        DashStyle dashStyle;

        SetStatus(DllExports::GdipGetPenDashStyle(nativePen, &dashStyle));

        return dashStyle;
    }

    Status SetDashStyle(IN DashStyle dashStyle)
    {
        return SetStatus(DllExports::GdipSetPenDashStyle(nativePen, 
                                                         dashStyle));
    }

    REAL GetDashOffset() const
    {
        REAL dashOffset;

        SetStatus(DllExports::GdipGetPenDashOffset(nativePen, &dashOffset));

        return dashOffset;
    }

    Status SetDashOffset(IN REAL dashOffset)
    {
        return SetStatus(DllExports::GdipSetPenDashOffset(nativePen, 
                                                          dashOffset));
    }
    
    Status SetDashPattern(IN const REAL* dashArray, IN INT count)
    {
        return SetStatus(DllExports::GdipSetPenDashArray(nativePen,
                                                         dashArray, 
                                                         count));
    }
    
    INT GetDashPatternCount() const
    {
        INT count = 0;
        
        SetStatus(DllExports::GdipGetPenDashCount(nativePen, &count));
        
        return count;
    }

    Status GetDashPattern(OUT REAL* dashArray, 
                          IN INT count) const
    {
        if (dashArray == NULL || count <= 0)
            return SetStatus(InvalidParameter); 
        
        return SetStatus(DllExports::GdipGetPenDashArray(nativePen, 
                                                         dashArray, 
                                                         count));
    }

    Status SetCompoundArray(IN const REAL* compoundArray,
                            IN INT count)
    {
        return SetStatus(DllExports::GdipSetPenCompoundArray(nativePen, 
                                                             compoundArray,
                                                             count));
    }

    INT GetCompoundArrayCount() const
    {
        INT count = 0;
        
        SetStatus(DllExports::GdipGetPenCompoundCount(nativePen, &count));
        
        return count;
    }

    Status GetCompoundArray(OUT REAL* compoundArray, 
                            IN INT count) const
    {
        if (compoundArray == NULL || count <= 0)
            return SetStatus(InvalidParameter); 
        
        return SetStatus(DllExports::GdipGetPenCompoundArray(nativePen, 
                                                             compoundArray, 
                                                             count));
    }

    Status GetLastStatus() const
    {
        Status lastStatus = lastResult;
        lastResult = Ok;

        return lastStatus;
    }

private:
    Pen(const Pen &);
    Pen& operator=(const Pen &);

protected:
    Pen(GpPen* nativePen, Status status)
    {
        lastResult = status;
        SetNativePen(nativePen);
    }

    VOID SetNativePen(GpPen* nativePen)
    {
        this->nativePen = nativePen;
    }
    
    Status SetStatus(Status status) const
    {
        if (status != Ok)
            return (lastResult = status);
        else 
            return status;
    }

protected:
    GpPen* nativePen;
    mutable Status lastResult;
};

#endif

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.


Written By
Engineer
United States United States
Jonathan de Halleux is Civil Engineer in Applied Mathematics. He finished his PhD in 2004 in the rainy country of Belgium. After 2 years in the Common Language Runtime (i.e. .net), he is now working at Microsoft Research on Pex (http://research.microsoft.com/pex).

Comments and Discussions