日常刷题19

题目:给定两条线段(表示为起点start = {X1, Y1}和终点end = {X2, Y2}),如果它们有交点,请计算其交点,没有交点则返回空值。
要求浮点型误差不超过10^-6。若有多个交点(线段重叠)则返回 X 值最小的点,X 坐标相同则返回 Y 值最小的点。
示例 1:
输入:
line1 = {0, 0}, {1, 0}
line2 = {1, 1}, {0, -1}
输出: {0.5, 0}
示例 2:
输入:
line1 = {0, 0}, {3, 3}
line2 = {1, 1}, {2, 2}
输出: {1, 1}
示例 3:
输入:
line1 = {0, 0}, {1, 1}
line2 = {1, 0}, {2, 1}
输出: {},两条线段没有交点
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/intersection-lcci
思路:用纯数学的方法分析,分类讨论直线的斜率存在的情况。题目中所说的是线段,是有边界的,不能简单认为求出交点,交点就一定存在。
代码:

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
double* intersection(int* start1, int start1Size, int* end1, int end1Size, int* start2, int start2Size, int* end2, int end2Size, int* returnSize)
{
    double k1,k2,b1,b2,x,y,*res,temp1x,temp1y,temp2x,temp2y;
    if(start1[0]==end1[0]&&start2[0]==end2[0])
    /*两直线斜率均不存在时,l1的x1≠l2的x1就可以判断两线段不
    重合。还有一种特殊情况,就是l2的y1刚好在l1的y2上方,这
    种情况也是没有交点的*/
    {
        if(start1[0]!=start2[0]||start2[1]>end1[1])
        {
            *returnSize=0;
            return 0;
        }
        else
        {
            *returnSize=2;
            res=(double*)malloc(2*sizeof(double));
            res[0]=start1[0];
            res[1]=start1[1]<=start2[1]?start2[1]:start1[1];
            return res;
        }
    }
    else if(start1[0]==end1[0]&&start2[0]!=end2[0])
    /*l1斜率不存在而l2斜率存在时,只要保证交点y坐标
    在l2的约束范围内,就有交点*/
    {
        k2=(double)(end2[1]-start2[1])/(end2[0]-start2[0]);
        b2=start2[1]-k2*start2[0];
        x=start1[0];
        y=k2*x+b2;
        if(y<=end1[1]&&y>=start1[1]&&y<=end2[1]&&y>=start2[1])
        {
            *returnSize=2;
            res=(double*)malloc(2*sizeof(double));
            res[0]=x;
            res[1]=y;
            return res;
        }
        else
        {
            *returnSize=0;
            return 0;
        }
    }
    else if(start1[0]!=end1[0]&&start2[0]==end2[0])
    /*l1斜率存在,l2斜率不存在*/
    {
        k1=(double)(end1[1]-start1[1])/(end1[0]-start1[0]);
        b1=start1[1]-k2*start1[0];
        x=start2[0];
        y=k1*x+b1;
        if(y<=end1[1]&&y>=start1[1]&&y<=end2[1]&&y>=start2[1])
        {
            *returnSize=2;
            res=(double*)malloc(2*sizeof(double));
            res[0]=x;
            res[1]=y;
            return res;
        }
        else
        {
            *returnSize=0;
            return 0;
        }
    }
    else//斜率都存在时
    {
        k1=(double)(end1[1]-start1[1])/(end1[0]-start1[0]);
        k2=(double)(end2[1]-start2[1])/(end2[0]-start2[0]);
        b1=start1[1]-k1*start1[0];
        b2=start2[1]-k2*start2[0];
        if(k1==k2)
        {//两直线平行时
            if(b1==b2)
            {//重合
                if(start2[0]>=start1[0]&&start2[0]<=end1[0])
                {
                    *returnSize=2;
                    res=(double*)malloc(2*sizeof(double));
                    res[0]=start2[0];
                    res[1]=start2[1];
                    return res;
                }
                else if(start1[0]>=start2[0]&&start1[0]<=end2[0])
                {
                    *returnSize=2;
                    res=(double*)malloc(2*sizeof(double));
                    res[0]=start1[0];
                    res[1]=start1[1];
                    return res;
                }
            }
            else
            {
                *returnSize=0;
                return 0;
            }
        }
        else
        {
            x=(double)(b1-b2)/(k2-k1);
            y=(double)(k2*b1-k1*b2)/(k2-k1);
            if(start1[0]>end1[0])
            {//考虑到输入的顺序,这里规定线段方向为从左到右
                temp1x=start1[0];
                start1[0]=end1[0];
                end1[0]=temp1x;
                temp1y=start1[1];
                start1[1]=end1[1];
                end1[1]=temp1y;
            }
            if(start2[0]>end2[0])
            {
                temp2x=start2[0];
                start2[0]=end2[0];
                end2[0]=temp2x;
                temp2y=start2[1];
                start2[1]=end2[1];
                end2[1]=temp2y;
            }
            if(x>=start1[0]&&x<=end1[0]&&x>=start2[0]&&x<=end2[0])
            {
                *returnSize=2;
                res=(double*)malloc(2*sizeof(double));
                res[0]=x;
                res[1]=y;
                return res;
            }
            else
            {
                *returnSize=0;
                return 0;
            }
        }
    }
    return 0;
}

你可能感兴趣的:(c语言)