/// <summary>
            /// Compute and update the display area from the two points of the ruler.
            /// This function also compute the orientation of the ruler based on the two points.
            /// Then it compute the distance between the two points in stud and call the method
            /// to update the image of the mesurement text.
            /// This method should be called when the two points of the ruler is updated
            /// or when the ruler is moved.
            /// </summary>
            protected override void updateDisplayData()
            {
                // get the geometry data in local variable
                PointF point1 = mControlPoint[0].mPoint;
                PointF point2 = mControlPoint[1].mPoint;
                float distance = mMeasuredDistance.DistanceInStud;

                // compute the vector of the offset. This vector is turned by 90 deg from the Orientation, so
                // just invert the X and Y of the normalized vector (the offset vector can be null)
                PointF offsetNormalizedVector = new PointF(mUnitVector.Y, -mUnitVector.X);

                // compute the offset distance depending on the flag
                float offsetDistance = mAllowOffset ? mOffsetDistance : 0.0f;

                // compute the offset coordinates in stud
                float offsetX = offsetNormalizedVector.X * offsetDistance;
                float offsetY = offsetNormalizedVector.Y * offsetDistance;
                PointF originalOffsetPoint1 = new PointF(point1.X + offsetX, point1.Y + offsetY);
                PointF originalOffsetPoint2 = new PointF(point2.X + offsetX, point2.Y + offsetY);
                PointF offsetPoint1 = originalOffsetPoint1;
                PointF offsetPoint2 = originalOffsetPoint2;

                // special case: if the distance is too small to draw the unit, we widden the offest point
                bool needToEnlargeWithText = mDisplayDistance && (distance < GUARANTIED_SPACE_FOR_DISTANCE_DRAWING_IN_STUD);
                bool needToEnlargeWithoutText = !mDisplayDistance && (distance < MINIMUM_SIZE_FOR_DRAWING_HELPER_IN_STUD);
                if (needToEnlargeWithText || needToEnlargeWithoutText)
                {
                    float enlargeSize = 0.0f;
                    if (needToEnlargeWithText)
                        enlargeSize = (GUARANTIED_SPACE_FOR_DISTANCE_DRAWING_IN_STUD - distance) * 0.5f;
                    else if (needToEnlargeWithoutText)
                        enlargeSize = HALF_MINIMUM_SIZE_FOR_DRAWING_HELPER_IN_STUD;
                    enlargeSize *= (point2.X > point1.X) ? 1.0f : -1.0f;
                    PointF enlargeVector = new PointF(mUnitVector.X * enlargeSize, mUnitVector.Y * enlargeSize);
                    offsetPoint1 = new PointF(offsetPoint1.X - enlargeVector.X, offsetPoint1.Y - enlargeVector.Y);
                    offsetPoint2 = new PointF(offsetPoint2.X + enlargeVector.X, offsetPoint2.Y + enlargeVector.Y);

                    // also enlarge the offset if there's the text
                    if (needToEnlargeWithText)
                    {
                        originalOffsetPoint1 = offsetPoint1;
                        originalOffsetPoint2 = offsetPoint2;
                    }
                }

                // when the offset points are finished to be computed, assign them in the data members
                mControlPoint[0].mOffsetPoint = originalOffsetPoint1;
                mControlPoint[1].mOffsetPoint = originalOffsetPoint2;

                // extend a little more the offset point to draw a margin
                float extendInStud = MINIMUM_SIZE_FOR_DRAWING_HELPER_IN_STUD;
                if (mDisplayDistance)
                    extendInStud = (float)(((double)MesurementTextHeightInPixel * 0.5) / MainForm.Instance.MapViewScale);
                float extendX = offsetNormalizedVector.X * ((mOffsetDistance > 0.0f) ? extendInStud : -extendInStud);
                float extendY = offsetNormalizedVector.Y * ((mOffsetDistance > 0.0f) ? extendInStud : -extendInStud);
                PointF[] selectionArea = new PointF[4];
                selectionArea[(int)SelectionAreaIndex.EXTERNAL_1] = new PointF(offsetPoint1.X + extendX, offsetPoint1.Y + extendY);
                selectionArea[(int)SelectionAreaIndex.EXTERNAL_2] = new PointF(offsetPoint2.X + extendX, offsetPoint2.Y + extendY);
                selectionArea[(int)SelectionAreaIndex.INTERNAL_1] = new PointF(offsetPoint1.X - extendX, offsetPoint1.Y - extendY);
                selectionArea[(int)SelectionAreaIndex.INTERNAL_2] = new PointF(offsetPoint2.X - extendX, offsetPoint2.Y - extendY);
                mSelectionArea = new Tools.Polygon(selectionArea);

                // finally update the display area
                updateDisplayArea();
            }
Beispiel #2
0
 /// <summary>
 /// Copy constructor
 /// </summary>
 /// <param name="model">the model from which copy</param>
 public Polygon(Polygon model)
 {
     this.mVertice = model.Vertice;
 }
Beispiel #3
0
            private void updateBitmap(bool redrawImage)
            {
                // create a bitmap if the text is not empty
                if (mText != "")
                {
                    // create a font to mesure the text
                    Font textFont = new Font(mTextFont.FontFamily, mTextFont.Size, mTextFont.Style);

                    Graphics graphics     = Graphics.FromImage(mImage);
                    SizeF    textFontSize = graphics.MeasureString(mText, textFont);
                    float    halfWidth    = textFontSize.Width * 0.5f;
                    float    halfHeight   = textFontSize.Height * 0.5f;

                    Matrix rotation = new Matrix();
                    rotation.Rotate(mOrientation);
                    // compute the rotated corners
                    PointF[] corners = new PointF[] { new PointF(-halfWidth, -halfHeight), new PointF(-halfWidth, halfHeight), new PointF(halfWidth, halfHeight), new PointF(halfWidth, -halfHeight) };
                    rotation.TransformVectors(corners);

                    PointF min = corners[0];
                    PointF max = corners[0];
                    for (int i = 1; i < 4; ++i)
                    {
                        if (corners[i].X < min.X)
                        {
                            min.X = corners[i].X;
                        }
                        if (corners[i].Y < min.Y)
                        {
                            min.Y = corners[i].Y;
                        }
                        if (corners[i].X > max.X)
                        {
                            max.X = corners[i].X;
                        }
                        if (corners[i].Y > max.Y)
                        {
                            max.Y = corners[i].Y;
                        }
                    }
                    // adjust the display area and selection area
                    mDisplayArea.Width  = Math.Abs(max.X - min.X);
                    mDisplayArea.Height = Math.Abs(max.Y - min.Y);

                    // adjust the selection area (after adjusting the display area such as the center properties is correct)
                    Matrix translation = new Matrix();
                    translation.Translate(Center.X, Center.Y);
                    translation.TransformPoints(corners);

                    // then create the new selection area
                    mSelectionArea = new Tools.Polygon(corners);

                    if (redrawImage)
                    {
                        // now create a scaled font from the current one, to avoid aliasing
                        Font scaledTextFont = new Font(mTextFont.FontFamily, mTextFont.Size * ANTI_ALIASING_FONT_SCALE, mTextFont.Style);
                        mImage = new Bitmap(mImage, new Size((int)(textFontSize.Width * ANTI_ALIASING_FONT_SCALE), (int)(textFontSize.Height * ANTI_ALIASING_FONT_SCALE)));

                        // compute the position where to draw according to the alignment (if centered == 0)
                        float posx = 0;
                        if (this.TextAlignment == StringAlignment.Far)
                        {
                            posx = halfWidth;
                        }
                        else if (this.TextAlignment == StringAlignment.Near)
                        {
                            posx = -halfWidth;
                        }

                        graphics = Graphics.FromImage(mImage);
                        rotation = new Matrix();
                        rotation.Translate(mImage.Width / 2, mImage.Height / 2, MatrixOrder.Append);
                        graphics.Transform = rotation;
                        graphics.Clear(Color.Transparent);
                        graphics.SmoothingMode = SmoothingMode.HighQuality;
                        graphics.DrawString(mText, scaledTextFont, mTextBrush, posx * ANTI_ALIASING_FONT_SCALE, 0, mTextStringFormat);
                        graphics.Flush();
                    }
                }
            }
            private void updateBitmap(bool redrawImage)
            {
                // create a bitmap if the text is not empty
                if (mText != "")
                {
                    // create a font to mesure the text
                    Font textFont = new Font(mTextFont.FontFamily, mTextFont.Size, mTextFont.Style);

                    Graphics graphics = Graphics.FromImage(mImage);
                    SizeF textFontSize = graphics.MeasureString(mText, textFont);
                    float halfWidth = textFontSize.Width * 0.5f;
                    float halfHeight = textFontSize.Height * 0.5f;

                    Matrix rotation = new Matrix();
                    rotation.Rotate(mOrientation);
                    // compute the rotated corners
                    PointF[] corners = new PointF[] { new PointF(-halfWidth, -halfHeight), new PointF(-halfWidth, halfHeight), new PointF(halfWidth, halfHeight), new PointF(halfWidth, -halfHeight) };
                    rotation.TransformVectors(corners);

                    PointF min = corners[0];
                    PointF max = corners[0];
                    for (int i = 1; i < 4; ++i)
                    {
                        if (corners[i].X < min.X)
                            min.X = corners[i].X;
                        if (corners[i].Y < min.Y)
                            min.Y = corners[i].Y;
                        if (corners[i].X > max.X)
                            max.X = corners[i].X;
                        if (corners[i].Y > max.Y)
                            max.Y = corners[i].Y;
                    }
                    // adjust the display area and selection area
                    mDisplayArea.Width = Math.Abs(max.X - min.X);
                    mDisplayArea.Height = Math.Abs(max.Y - min.Y);

                    // adjust the selection area (after adjusting the display area such as the center properties is correct)
                    Matrix translation = new Matrix();
                    translation.Translate(Center.X, Center.Y);
                    translation.TransformPoints(corners);

                    // then create the new selection area
                    mSelectionArea = new Tools.Polygon(corners);

                    if (redrawImage)
                    {
                        // now create a scaled font from the current one, to avoid aliasing
                        Font scaledTextFont = new Font(mTextFont.FontFamily, mTextFont.Size * ANTI_ALIASING_FONT_SCALE, mTextFont.Style);
                        mImage = new Bitmap(mImage, new Size((int)(textFontSize.Width * ANTI_ALIASING_FONT_SCALE), (int)(textFontSize.Height * ANTI_ALIASING_FONT_SCALE)));

                        // compute the position where to draw according to the alignment (if centered == 0)
                        float posx = 0;
                        if (this.TextAlignment == StringAlignment.Far)
                            posx = halfWidth;
                        else if (this.TextAlignment == StringAlignment.Near)
                            posx = -halfWidth;

                        graphics = Graphics.FromImage(mImage);
                        rotation = new Matrix();
                        rotation.Translate(mImage.Width / 2, mImage.Height / 2, MatrixOrder.Append);
                        graphics.Transform = rotation;
                        graphics.Clear(Color.Transparent);
                        graphics.SmoothingMode = SmoothingMode.HighQuality;
                        graphics.DrawString(mText, scaledTextFont, mTextBrush, posx * ANTI_ALIASING_FONT_SCALE, 0, mTextStringFormat);
                        graphics.Flush();
                    }
                }
            }
            private void updateImage()
            {
                List<PointF> boundingBox = null;
                List<PointF> hull = null;
                mOriginalImageReference = BrickLibrary.Instance.getImage(mPartNumber, ref boundingBox, ref hull);
                // check if the image is not in the library, create one
                if (mOriginalImageReference == null)
                {
                    // add a default image in the library and ask it again
                    BrickLibrary.Instance.AddUnknownBrick(mPartNumber, (int)(mDisplayArea.Width), (int)(mDisplayArea.Height));
                    mOriginalImageReference = BrickLibrary.Instance.getImage(mPartNumber, ref boundingBox, ref hull);
                }
                // normally now, we should have an image
                // transform the bounding box of the part
                PointF[] boundingPoints = boundingBox.ToArray();
                Matrix rotation = new Matrix();
                rotation.Rotate(mOrientation);
                rotation.TransformVectors(boundingPoints);

                // get the min, max and the size of the bounding box
                PointF boundingMin = new PointF();
                PointF boundingMax = new PointF();
                PointF boundingSize = sGetMinMaxAndSize(boundingPoints, ref boundingMin, ref boundingMax);

                // store computationnal variable for optimization
                const float PIXEL_TO_STUD_RATIO = 1.0f / NUM_PIXEL_PER_STUD_FOR_BRICKS;

                // transform the hull to get the selection area
                PointF[] hullArray = hull.ToArray();
                rotation.TransformVectors(hullArray);

                // check if this picture has a specific hull
                if (hull != boundingBox)
                {
                    // get the bounding size from the hull
                    PointF hullMin = new PointF();
                    PointF hullMax = new PointF();
                    PointF hullSize = sGetMinMaxAndSize(hullArray, ref hullMin, ref hullMax);

                    // compute the offset between the hull and the normal bounding box
                    PointF deltaMin = new PointF(boundingMin.X - hullMin.X, boundingMin.Y - hullMin.Y);
                    PointF deltaMax = new PointF(boundingMax.X - hullMax.X, boundingMax.Y - hullMax.Y);
                    mOffsetFromOriginalImage = new PointF((deltaMax.X + deltaMin.X) * PIXEL_TO_STUD_RATIO * 0.5f,
                                                          (deltaMax.Y + deltaMin.Y) * PIXEL_TO_STUD_RATIO * 0.5f);

                    // overwrite the bounding size and min with the hull ones which are more precise
                    boundingSize = hullSize;
                    boundingMin = hullMin;
                }
                else
                {
                    mOffsetFromOriginalImage = new PointF(0, 0);
                }

                // set the size of the display area with the new computed bounding size, and recompute the snap to grid offset
                mDisplayArea.Width = boundingSize.X * PIXEL_TO_STUD_RATIO;
                mDisplayArea.Height = boundingSize.Y * PIXEL_TO_STUD_RATIO;
                mTopLeftCornerInPixel = new PointF(-boundingMin.X, -boundingMin.Y);

                // adjust the selection area after computing the new display area size to have a correct center
                // first we add the translation of the top left corner in pixel to the hull point already in pixel
                // then convert the pixel to studs, and finally add the top left corner in stud
                Matrix translation = new Matrix();
                translation.Translate(mTopLeftCornerInPixel.X, mTopLeftCornerInPixel.Y);
                translation.Scale(PIXEL_TO_STUD_RATIO, PIXEL_TO_STUD_RATIO, MatrixOrder.Append);
                translation.Translate(Center.X - (mDisplayArea.Width * 0.5f), Center.Y - (mDisplayArea.Height * 0.5f), MatrixOrder.Append);
                translation.TransformPoints(hullArray);

                // create the new selection area from the rotated hull
                mSelectionArea = new Tools.Polygon(hullArray);

                // clear the new images array for all the levels
                clearMipmapImages(0, mMipmapImages.Length - 1);
            }