Hi guys,

I'm having a bit of trouble with a bit of trig in C#. I've written code similar to this in actionscript3 (flash), but it is giving me issues in C#. I am not receiving errors, but all the shapes I rotate are somewhat screwed up.

Here is the points array I am using:

static private Point[] drawingPoints = new Point[13]{new Point(14,0),new Point(19,9),new Point(19,18),new Point(25,30),new Point(19,26),new Point(19,18),new Point(19,26),new Point(8,26),new Point(8,18),new Point(0,30),new Point(8,26),new Point(8,9),new Point(14,0)};

Here is the rotation code + the code to draw this.

public void draw (Graphics g)
        {
            Point[] rotatedPoints = new Point[13];

            
            for (short index = 0; index < rotatedPoints.Length; index++)
            {
                //Finding the location of the points relative to the upper left of the ship.
                Point curPoint = drawingPoints[index];
                Point newPoint = new Point(curPoint.X,curPoint.Y);

                double distToPoint = Form1.distTo(curPoint.X,curPoint.Y,centerPoint.X,centerPoint.Y);//we treat this as the hypotenuse.
                
                decimal degToPoint = (decimal)Math.Atan(centerPoint.Y - curPoint.Y / centerPoint.X - curPoint.X)/Form1.rad;//Gets the degrees from the center point to the current drawing point without any rotation yet.
                decimal degToNewPoint = degToPoint + rotation;//Add the rotation

                decimal cosToNewPoint = (decimal)Math.Cos((double)(degToNewPoint*Form1.rad));//From the center the cosine.

                //Since cos is adj/hyp to get adj multiply by the hyp.
                newPoint.X = (int)(cosToNewPoint * (decimal)distToPoint);
                
                decimal sinToNewPoint = (decimal)Math.Sin((double)(degToNewPoint * Form1.rad));//From the center the cosine.

                Debug.Fail(sinToNewPoint.ToString());

                //Same idea as with the cosine
                newPoint.Y = (int)(sinToNewPoint * (decimal)distToPoint);

                //Adding points to drawing array
                rotatedPoints[index] = newPoint;
            }
            //Adding the screen x y location to the points:

            for (short i = 0; i < rotatedPoints.Length; i++)
            {
                rotatedPoints[i].X += this._x;
                rotatedPoints[i].Y += this._y;
            }
            Pen shipPen = new Pen(shipColor, 2);
            g.DrawLines(shipPen, rotatedPoints);
        }

I know that the drawing code works correctly. If you comment out the rotation parts of the code, it displays my drawing just fine. What is annoying, is that if the rotation is something other than zero, the rotation works, but the shape is still flattened/scewed on one side.


This problem is driving me up the wall, please help :).

I like your ship.
There is a native matrix transform that you can use in the System.Drawing.Drawing2D namespace.
Below is an example of how I might do it using a GraphicsPath.
The draw method could be adapted to plot any GraphicsPath with rotation and location parameters.

// GraphicPath to hold basic ship shape
        System.Drawing.Drawing2D.GraphicsPath shipShape;
        // My ship color
        Color shipColor = Color.Blue;
        // basic ship point array
        static private Point[] drawingPoints = new Point[] { new Point(13, 0), new Point(19, 9), new Point(19, 18), new Point(25, 30), new Point(19, 26), new Point(19, 18), new Point(19, 26), new Point(8, 26), new Point(8, 18), new Point(0, 30), new Point(8, 26), new Point(8, 9), new Point(13, 0) };
        // rotation angle to apply to ship when drawn.
        float shipAngle = 90f;
        // offset of ship center point from drawing origin.
        Point shipLocation = new Point(20,20);

        // creates the ship GraphicsPath
        private void createShipShape()
        {
            shipShape = new System.Drawing.Drawing2D.GraphicsPath();
            shipShape.AddLines(drawingPoints);
            shipShape.CloseAllFigures();
            // offset to make origin at ship center
            // this would be better done directly by adjusting drawingPoints using -ve numbers
            System.Drawing.Drawing2D.Matrix offsetMatrix = new System.Drawing.Drawing2D.Matrix();
            offsetMatrix.Translate(-13, -15);
            shipShape.Transform(offsetMatrix);
        }

        private void draw(Graphics g)
        {
            // set up ship graphic if not alread done (this could/should be done elsewhere)
            if (shipShape == null)
            {
                createShipShape();
            }

            // use local temp GraphicsPath to preserve original path
            // required because Tranform later changes path
            System.Drawing.Drawing2D.GraphicsPath shipDrawPath = 
                new System.Drawing.Drawing2D.GraphicsPath();
            shipDrawPath.AddPath(shipShape, true);

            // define rotation (and offset) matrix
            System.Drawing.Drawing2D.Matrix rotateMatrix = new System.Drawing.Drawing2D.Matrix();
            // add rotation to adjust ship angle (from vertical)
            rotateMatrix.Rotate(shipAngle);
            // add offset to adjust ship position (origin is ship center point)
            // Note: must use MatrixOrder.Append otherwise the rotate origin is wrong
            rotateMatrix.Translate(shipLocation.X, shipLocation.Y, System.Drawing.Drawing2D.MatrixOrder.Append);
            
            // apply matrix and draw ship
            shipDrawPath.Transform(rotateMatrix);
            Pen shipPen = new Pen(shipColor, 2);
            g.DrawPath(shipPen, shipDrawPath);
        }
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.