Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/114.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 在与中心点成给定角度的直线相交的UIView矩形上查找CG点_Iphone_Ios_Math_Graphics_Geometry - Fatal编程技术网

Iphone 在与中心点成给定角度的直线相交的UIView矩形上查找CG点

Iphone 在与中心点成给定角度的直线相交的UIView矩形上查找CG点,iphone,ios,math,graphics,geometry,Iphone,Ios,Math,Graphics,Geometry,在iOS中,我试图确定一个矩形上的点,该点由一条假想线以预定角度从中心点到矩形周长相交 假设我知道中心点、矩形的大小和角度(从东0度开始,逆时针到北90度,西180度,南270度,再到东360度)。我需要知道交点的坐标 这个(对我来说)数学上有点混乱但大概是准确的答案让我尝试了下面的代码,但它不能正常工作。这个问题与那个问题类似,但我正在寻找一个正确的Objective-C/iOS方法,而不是一般的数学答案 我认为代码问题的一部分与使用单个0到360度角(弧度,不可能是负数)输入有关,但可能还有

在iOS中,我试图确定一个矩形上的点,该点由一条假想线以预定角度从中心点到矩形周长相交

假设我知道中心点、矩形的大小和角度(从东0度开始,逆时针到北90度,西180度,南270度,再到东360度)。我需要知道交点的坐标

这个(对我来说)数学上有点混乱但大概是准确的答案让我尝试了下面的代码,但它不能正常工作。这个问题与那个问题类似,但我正在寻找一个正确的Objective-C/iOS方法,而不是一般的数学答案

我认为代码问题的一部分与使用单个0到360度角(弧度,不可能是负数)输入有关,但可能还有其他问题。下面的代码主要使用中定义的符号,包括我尝试为其中定义的四个区域中的每一个计算交点

此代码位于my UIImageView子类中:

- (CGPoint) startingPointGivenAngleInDegrees:(double)angle {
    double angleInRads = angle/180.0*M_PI;
    float height = self.frame.size.height;
    float width = self.frame.size.width;
    float x0 = self.center.x;
    float y0 = self.center.y;
    // region 1 
    if (angleInRads >= -atan2(height, width) && angleInRads <= atan2(height, width)) {
        return CGPointMake(x0 + width/2, y0 + width/2 * tan(angleInRads));
    }
    // region 2
    if (angleInRads >= atan2(height, width) && angleInRads <= M_PI - atan2(height, width)) {
        return CGPointMake(x0 + height / (2*tan(angleInRads)),y0+height/2);
    }
    // region 3
    if (angleInRads >= M_PI - atan2(height, width) && angleInRads <= M_PI + atan2(height, width)) {
        return CGPointMake(x0 - width/2, y0 + width/2 * tan(angleInRads));
    }
    // region 4
    return CGPointMake(x0 + height / (2*tan(angleInRads)),y0-height/2);    
}
-(CGPoint)起始点给定NangleIndegrees:(双)角度{
双角度RADS=角度/180.0*M_π;
浮动高度=self.frame.size.height;
浮动宽度=self.frame.size.width;
浮动x0=自中心x;
浮动y0=自中心y;
//区域1

如果(angleInRads>=-atan2(高度,宽度)&&angleInRads=atan2(高度,宽度)&&angleInRads=M_PI-atan2(高度,宽度)&&angleInRads而不是调试您的代码,我将解释我将如何执行此操作

首先是一些术语。让我们将
xRadius
定义为框架宽度的一半,将
yRadius
定义为框架高度的一半

现在考虑框架的四个边,并将它们作为无限线扩展。在这四条线的上面,以指定的角度画出一条穿过框架中心的线:

假设框架以原点为中心-框架的中心位于坐标(0,0)处。我们可以轻松计算对角线与框架右边缘相交的位置:坐标为(
xRadius
xRadius*tan(角度)
)我们可以很容易地计算出对角线与框架顶边相交的位置:坐标是(
-yRadius/tan(角度)
-yRadius

(为什么我们要否定上边缘交点的坐标?因为
UIView
坐标系从正常的数学坐标系翻转过来。在数学中,y坐标向页面顶部增加。在
UIView
中,y坐标向视图底部增加。)

因此,我们可以简单地计算线与框架右边缘的交点。如果该交点在框架外,那么我们知道线必须在与右边缘相交之前与上边缘相交。我们如何判断右边缘的交点是否超出边界?如果其y坐标(
xRadius*tan(angle)
)大于
yRadius
(或小于
-yRadius
),超出范围

因此,为了将所有这些放在一个方法中,我们首先计算
xRadius
yRadius

- (CGPoint)radialIntersectionWithConstrainedRadians:(CGFloat)radians {
    // This method requires 0 <= radians < 2 * π.

    CGRect frame = self.frame;
    CGFloat xRadius = frame.size.width / 2;
    CGFloat yRadius = frame.size.height / 2;
我们检查交叉点是否在框架中:

    if (fabsf(y) <= yRadius) {
下一步,我们计算出我们想要的是上边缘还是下边缘。如果角度小于π(180°),我们想要下边缘。否则,我们想要上边缘

        if (radians < (CGFloat)M_PI) {
            pointRelativeToCenter = CGPointMake(x, yRadius);
        } else {
            pointRelativeToCenter = CGPointMake(-x, -yRadius);
        }
    }
此处测试项目:

看起来像这样:


以下是Rob的答案,它是一个快速的lil复制粘贴

func findEdgePoint(angle: CGFloat) -> CGPoint {

    let intersection: CGPoint

    let xRad = frame.width / 2
    let yRad = frame.height / 2

    let tangent = tan(angle)
    let y = xRad * CGFloat(tangent)

    if fabs(y) <= yRad {

        if angle < CGFloat.pi / 2 || angle > 3 * CGFloat.pi / 2 {
            intersection = CGPoint(x: xRad, y: y)
        } else {
            intersection = CGPoint(x: -xRad, y: -y)
        }
    } else {

        let x = yRad / CGFloat(tangent)

        if angle < CGFloat.pi {
            intersection = CGPoint(x: x, y: yRad)
        } else {
            intersection = CGPoint(x: -x, y: -yRad)
        }
    }

    return intersection
}

// heck yeah rob, he's the man
// if he can't solve it, no one can
func findEdgePoint(角度:CGFloat)->CGPoint{
让交点:CGPoint
设xRad=frame.width/2
设yRad=车架高度/2
让切线=tan(角度)
设y=xRad*CGFloat(相切)
如果晶圆厂(y)3*CGFloat.pi/2{
交点=CGPoint(x:xRad,y:y)
}否则{
交点=cG点(x:-xRad,y:-y)
}
}否则{
设x=yRad/CGFloat(相切)
如果角度
太棒了!谢谢。我在这方面遇到了一些麻烦,因为在我的情况下,我没有意识到我必须在UIImageview子类中[self.superview convertPoint:thePoint to View:self]来这里的其他新手.我正在研究你的代码,它非常优秀,试图了解如果我想旋转图像并保持边缘检测,该怎么办?有什么想法吗?虽然这是一个答案,但它是@rob先前答案的“副本”。因此,用相同的解决方案保留两个答案没有任何附加值。我不同意。我已经看得够多了“我如何在Swift中执行此操作”这里的问题,我认为提供旧的Objective-C答案的快速翻译会增加价值。非常感谢这段代码和解释,Rob。需要在Swift中使用它,所以我想我在翻译后会留下它。你知道。肯定看到很多答案后的“这里就是Swift”,所以我认为这会很好。任何人都可以找到这段代码没有按预期工作:结果“交点”是一个相对于帧中心点的点,与帧不在同一坐标中。直到看到rob编写的原始代码,我才意识到这一点。
    } else {
        CGFloat x = yRadius / tangent;
        if (radians < (CGFloat)M_PI) {
            pointRelativeToCenter = CGPointMake(x, yRadius);
        } else {
            pointRelativeToCenter = CGPointMake(-x, -yRadius);
        }
    }
    return CGPointMake(pointRelativeToCenter.x + CGRectGetMidX(frame),
        pointRelativeToCenter.y + CGRectGetMidY(frame));
}
func findEdgePoint(angle: CGFloat) -> CGPoint {

    let intersection: CGPoint

    let xRad = frame.width / 2
    let yRad = frame.height / 2

    let tangent = tan(angle)
    let y = xRad * CGFloat(tangent)

    if fabs(y) <= yRad {

        if angle < CGFloat.pi / 2 || angle > 3 * CGFloat.pi / 2 {
            intersection = CGPoint(x: xRad, y: y)
        } else {
            intersection = CGPoint(x: -xRad, y: -y)
        }
    } else {

        let x = yRad / CGFloat(tangent)

        if angle < CGFloat.pi {
            intersection = CGPoint(x: x, y: yRad)
        } else {
            intersection = CGPoint(x: -x, y: -yRad)
        }
    }

    return intersection
}

// heck yeah rob, he's the man
// if he can't solve it, no one can