我有坐标的左上角形的,以及它的宽度、高度和旋转从0到180和-0-180.

我试图那边坐标的实际框周围的矩形。

什么是一个简单的方式计算坐标的边框

  • 分y,max y,min x,max x?

这一点并不总是在分y约束,它可以在任何地方。

我可以使用矩阵变换的工具包,在as3如果需要的话。

有帮助吗?

解决方案

  • 变换的坐标的所有四个角落
  • 找到最小的所有四个x的 min_x
  • 发现的最大的所有四个x的,并呼吁它 max_x
  • 同上,与y是
  • 你的边框 (min_x,min_y), (min_x,max_y), (max_x,max_y), (max_x,min_y)

据我所知,没有任何皇室的道路,将让你有快得多。

如果你想知道如何变换的坐标,尝试:

x2 = x0+(x-x0)*cos(theta)+(y-y0)*sin(theta)
y2 = y0-(x-x0)*sin(theta)+(y-y0)*cos(theta)

在哪里(x0,y0)该中心在其周围你转动。你可能需要修补这取决于你的触发功能(他们希望度或弧度)的意识/标志你的坐标系统与你是如何指定的角度,等等。

其他提示

我知道你问的态脚但是,只是在情况下的任何人到这里寻找iOS或OS X的答案,它是这样的:

+ (CGRect) boundingRectAfterRotatingRect: (CGRect) rect toAngle: (float) radians
{
    CGAffineTransform xfrm = CGAffineTransformMakeRotation(radians);
    CGRect result = CGRectApplyAffineTransform (rect, xfrm);

    return result;
}

如果你的操作系统提供做的所有辛勤工作给你,让它!:)

斯威夫特:

func boundingRectAfterRotatingRect(rect: CGRect, toAngle radians: CGFloat) -> CGRect {
    let xfrm = CGAffineTransformMakeRotation(radians)
    return CGRectApplyAffineTransform (rect, xfrm)
}

概述的方法由MarkusQ完美的作品但是记住,你不需要转换的其他三个角落如果你有一点了。

一种替代方法,这是更有效率,是为了测试它象限你的旋转角,然后简单的计算直接回答。这是更高效的因为你只有一个最糟糕的情况下,如果两个发言(检查的角度),而其他方式具有一个最糟糕情况十二(6每个组件检查时的其他三个角,看看他们是否大于当前的最大或小于目前的分),我认为。

基本的算法,它使用没有超过一系列应用程序的毕达哥拉斯定理,如下所示。我有表示的旋转角度,通过"希塔",并表示该检查有没有在度,因为它是伪码。

ct = cos( theta );
st = sin( theta );

hct = h * ct;
wct = w * ct;
hst = h * st;
wst = w * st;

if ( theta > 0 )
{
    if ( theta < 90 )
    {
        // 0 < theta < 90
        y_min = A_y;
        y_max = A_y + hct + wst;
        x_min = A_x - hst;
        x_max = A_x + wct;
    }
    else
    {
        // 90 <= theta <= 180
        y_min = A_y + hct;
        y_max = A_y + wst;
        x_min = A_x - hst + wct;
        x_max = A_x;
    }
}
else
{
    if ( theta > -90 )
    {
        // -90 < theta <= 0
        y_min = A_y + wst;
        y_max = A_y + hct;
        x_min = A_x;
        x_max = A_x + wct - hst;
    }
    else
    {
        // -180 <= theta <= -90
        y_min = A_y + wst + hct;
        y_max = A_y;
        x_min = A_x + wct;
        x_max = A_x - hst;
    }
}

这种方法假定你有什么你说你有即点和一个价值为theta的在于在范围[-180,180].我还假设西塔增加向顺时针方向为这是矩形,已经旋转30度在你的图似乎表明正在使用的,我不知道什么是部分正确的是试图表示。如果这是错误方式则仅仅是交换对称的条款并且还签署的圣条款。

    fitRect: function( rw,rh,radians ){
            var x1 = -rw/2,
                x2 = rw/2,
                x3 = rw/2,
                x4 = -rw/2,
                y1 = rh/2,
                y2 = rh/2,
                y3 = -rh/2,
                y4 = -rh/2;

            var x11 = x1 * Math.cos(radians) + y1 * Math.sin(radians),
                y11 = -x1 * Math.sin(radians) + y1 * Math.cos(radians),
                x21 = x2 * Math.cos(radians) + y2 * Math.sin(radians),
                y21 = -x2 * Math.sin(radians) + y2 * Math.cos(radians), 
                x31 = x3 * Math.cos(radians) + y3 * Math.sin(radians),
                y31 = -x3 * Math.sin(radians) + y3 * Math.cos(radians),
                x41 = x4 * Math.cos(radians) + y4 * Math.sin(radians),
                y41 = -x4 * Math.sin(radians) + y4 * Math.cos(radians);

            var x_min = Math.min(x11,x21,x31,x41),
                x_max = Math.max(x11,x21,x31,x41);

            var y_min = Math.min(y11,y21,y31,y41);
                y_max = Math.max(y11,y21,y31,y41);

            return [x_max-x_min,y_max-y_min];
        }

如果您使用的是GDI,你可以创建一个新的GrpaphicsPath->添加任何一点或形状了->的适用旋转转化->使用GraphicsPath.GetBounds()及其将返回的一个长方形的边界你的旋转状。

(编辑)VB.Net 样本

Public Shared Sub RotateImage(ByRef img As Bitmap, degrees As Integer)
' http://stackoverflow.com/questions/622140/calculate-bounding-box-coordinates-from-a-rotated-rectangle-picture-inside#680877
'
Using gp As New GraphicsPath
  gp.AddRectangle(New Rectangle(0, 0, img.Width, img.Height))

  Dim translateMatrix As New Matrix
  translateMatrix.RotateAt(degrees, New PointF(img.Width \ 2, img.Height \ 2))
  gp.Transform(translateMatrix)

  Dim gpb = gp.GetBounds

  Dim newwidth = CInt(gpb.Width)
  Dim newheight = CInt(gpb.Height)

  ' http://www.codeproject.com/Articles/58815/C-Image-PictureBox-Rotations
  '
  Dim rotatedBmp As New Bitmap(newwidth, newheight)

  rotatedBmp.SetResolution(img.HorizontalResolution, img.VerticalResolution)

  Using g As Graphics = Graphics.FromImage(rotatedBmp)
    g.Clear(Color.White)
    translateMatrix = New Matrix
    translateMatrix.Translate(newwidth \ 2, newheight \ 2)
    translateMatrix.Rotate(degrees)
    translateMatrix.Translate(-img.Width \ 2, -img.Height \ 2)
    g.Transform = translateMatrix
    g.DrawImage(img, New PointF(0, 0))
  End Using
  img.Dispose()
  img = rotatedBmp
End Using

结束子

虽然代大师说的GetBounds()方法,我已经注意到的问题是,标记as3,弯曲,因此,这里是一个as3段说明的想法。

var box:Shape = new Shape();
box.graphics.beginFill(0,.5);
box.graphics.drawRect(0,0,100,50);
box.graphics.endFill();
box.rotation = 20;
box.x = box.y = 100;
addChild(box);

var bounds:Rectangle = box.getBounds(this);

var boundingBox:Shape = new Shape();
boundingBox.graphics.lineStyle(1);
boundingBox.graphics.drawRect(bounds.x,bounds.y,bounds.width,bounds.height);
addChild(boundingBox);

我注意到,有两种方法似乎做同样的事情:getBounds()和getRect()

/**
     * Applies the given transformation matrix to the rectangle and returns
     * a new bounding box to the transformed rectangle.
     */
    public static function getBoundsAfterTransformation(bounds:Rectangle, m:Matrix):Rectangle {
        if (m == null) return bounds;

        var topLeft:Point = m.transformPoint(bounds.topLeft);
        var topRight:Point = m.transformPoint(new Point(bounds.right, bounds.top));
        var bottomRight:Point = m.transformPoint(bounds.bottomRight);
        var bottomLeft:Point = m.transformPoint(new Point(bounds.left, bounds.bottom));

        var left:Number = Math.min(topLeft.x, topRight.x, bottomRight.x, bottomLeft.x);
        var top:Number = Math.min(topLeft.y, topRight.y, bottomRight.y, bottomLeft.y);
        var right:Number = Math.max(topLeft.x, topRight.x, bottomRight.x, bottomLeft.x);
        var bottom:Number = Math.max(topLeft.y, topRight.y, bottomRight.y, bottomLeft.y);
        return new Rectangle(left, top, right - left, bottom - top);
    }

适用转基于你的角点。然后用最低/最高分别所获得的x、y坐标来界定新的边界框。

这里有三个功能自我开放源图书馆。该职能是全面测试,在Java但该公式可以容易地翻译成任何语言。

签名的是:

公共静浮getAngleFromPoint(最后一点中心点、终点接触点)

公共静浮getTwoFingerDistance(float firstTouchX、浮动firstTouchY、浮动secondTouchX、浮动secondTouchY)

点getPointFromAngle(最后一双重角度,最终双半径)

这种解决办法假定,像素的密度均匀分布。前旋转的对象做到以下几点:

  1. 使用getAngleFromPoint计算的角度从中心向右上角(可以说这返回20度)的含义,等一级的左上角是零下20摄氏度或340度。

  2. 使用getTwoFingerDistance返回的对角线之间的距离中心点右上角(这个距离应你只在被同所有角落,这个距离将用于下一个计算)。

  3. 现在让我们转动的对象顺时针的通过30度。现在我们知道,右上角必须在50度和左上角是在10摄氏度。

  4. 你现在应该能够使用getPointFromAngle功能上左右上角。使用半径返回步骤2。X位置乘以2从右上角应该给你新的宽度和Y的位置2次是从左上角应该得到新的高度。

这些上述4个步骤应该投入条件的基础有多远,你转动你的目的的其他智慧的,你可以返回该高度的宽度和宽度作为高度。

裸露在心灵的角度的功能表示的因素为0-1而不是0-360(刚刚乘以或除以360在适当情况下):

//获得角度从两点表示作为一个因素为0-1的(0 0/360,0.25正90度等)

public float getAngleFromPoint(final Point centerPoint, final Point touchPoint) {

    float returnVal = 0;

    //+0 - 0.5
    if(touchPoint.x > centerPoint.x) {

        returnVal = (float) (Math.atan2((touchPoint.x - centerPoint.x), (centerPoint.y - touchPoint.y)) * 0.5 / Math.PI);

    }
    //+0.5
    else if(touchPoint.x < centerPoint.x) {

        returnVal = (float) (1 - (Math.atan2((centerPoint.x - touchPoint.x), (centerPoint.y - touchPoint.y)) * 0.5 / Math.PI));

    }//End if(touchPoint.x > centerPoint.x)

    return returnVal;

}

//措施的对角线两点之间的距离

public float getTwoFingerDistance(final float firstTouchX, final float firstTouchY, final float secondTouchX, final float secondTouchY) {

    float pinchDistanceX = 0;
    float pinchDistanceY = 0;

    if(firstTouchX > secondTouchX) {

        pinchDistanceX = Math.abs(secondTouchX - firstTouchX);

    }
    else if(firstTouchX < secondTouchX) {

        pinchDistanceX = Math.abs(firstTouchX - secondTouchX);

    }//End if(firstTouchX > secondTouchX)

    if(firstTouchY > secondTouchY) {

        pinchDistanceY = Math.abs(secondTouchY - firstTouchY);

    }
    else if(firstTouchY < secondTouchY) {

        pinchDistanceY = Math.abs(firstTouchY - secondTouchY);

    }//End if(firstTouchY > secondTouchY)

    if(pinchDistanceX == 0 && pinchDistanceY == 0) {

        return 0;

    }
    else {

        pinchDistanceX = (pinchDistanceX * pinchDistanceX);
        pinchDistanceY = (pinchDistanceY * pinchDistanceY);
        return (float) Math.abs(Math.sqrt(pinchDistanceX + pinchDistanceY));

    }//End if(pinchDistanceX == 0 && pinchDistanceY == 0)

}

//Get-y坐标从一个角度给出的一种半径为(角度表示的一个因素为0-1 0 0/360度和0.75被270等)

public Point getPointFromAngle(final double angle, final double radius) {

    final Point coords = new Point();
    coords.x = (int) (radius * Math.sin((angle) * 2 * Math.PI));
    coords.y = (int) -(radius * Math.cos((angle) * 2 * Math.PI));

    return coords;

}

这些代码段是从我的开放源图书馆: https://bitbucket.org/warwick/hgdialrepohttps://bitbucket.org/warwick/hacergestov2.是一个手势图书馆和其他一盘控制序。还有一个价2.0执行情况的拨控制: https://bitbucket.org/warwick/hggldial

我不确定我理解的,但一种化合物转换矩阵会给你新坐标的所有各点有关。如果你想的矩形可能蔓延的imagable区域后转换适用剪切路径。

在情况下你不熟悉精确的定义,该矩阵来看看 在这里,.

我用区域第一个旋转的矩形,然后使用那个旋转的地区,以检测是矩形

        r = new Rectangle(new Point(100, 200), new Size(200, 200));         
        Color BorderColor = Color.WhiteSmoke;
        Color FillColor = Color.FromArgb(66, 85, 67);
        int angle = 13;
        Point pt = new Point(r.X, r.Y);
        PointF rectPt = new PointF(r.Left + (r.Width / 2),
                               r.Top + (r.Height / 2));
       //declare myRegion globally 
        myRegion = new Region(r);

        // Create a transform matrix and set it to have a 13 degree

        // rotation.
        Matrix transformMatrix = new Matrix();
        transformMatrix.RotateAt(angle, pt);

        // Apply the transform to the region.
        myRegion.Transform(transformMatrix);
        g.FillRegion(Brushes.Green, myRegion);
        g.ResetTransform();

现在检测是矩形

        private void panel_MouseMove(object sender, MouseEventArgs e)
    {


        Point point = e.Location;
        if (myRegion.IsVisible(point, _graphics))
        {
            // The point is in the region. Use an opaque brush.
            this.Cursor = Cursors.Hand;
        }
        else {
            this.Cursor = Cursors.Cross;
        }

    }
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top