Javascript 返回优化的x坐标,以规范化/最大化具有定义y位置的矩形阵列的面积

Javascript 返回优化的x坐标,以规范化/最大化具有定义y位置的矩形阵列的面积,javascript,algorithm,math,tessellation,Javascript,Algorithm,Math,Tessellation,我已经包含了一个代码片段,希望它能很好地总结事情,并以一种“填空”的状态表示 如果从更大的角度来看问题有助于理解问题的根源,那么我最终要做的就是在手机日历上显示每日查看时间表,这可能与手机日历的工作原理类似。当事件开始在时间上重叠时,这里用垂直y轴表示,我希望能够优化这些事件的宽度和位置,不要重叠它们,也不要隐藏比我必须隐藏的内容更多的内容-但是当有太多的事件能够指示隐藏的东西时 我不想寻找任何基于CSS/HTML的解决方案,尽管示例是JavaScript——DOM结构或多或少是石头,只是寻找一

我已经包含了一个代码片段,希望它能很好地总结事情,并以一种“填空”的状态表示

如果从更大的角度来看问题有助于理解问题的根源,那么我最终要做的就是在手机日历上显示每日查看时间表,这可能与手机日历的工作原理类似。当事件开始在时间上重叠时,这里用垂直y轴表示,我希望能够优化这些事件的宽度和位置,不要重叠它们,也不要隐藏比我必须隐藏的内容更多的内容-但是当有太多的事件能够指示隐藏的东西时

我不想寻找任何基于CSS/HTML的解决方案,尽管示例是JavaScript——DOM结构或多或少是石头,只是寻找一种算法,它可以做我正在寻找的,如果它在C++、TurboPascal、汇编、java中,什么都不重要。在我的示例中,预期结果场景越复杂,结果就越像是粗略的估计,在演示中呈现预期结果时也会遇到这种情况-一旦事情开始变得奇怪,我甚至没有一个非常好的方法来进行计算

目标是填充函数
OptimizeLeftandRightXStartPointsFornormalizedRectangleArea而不重叠=(矩形、最小面积、最小宽度、xMin、xMax)=>{}

//假设我有一个这样的矩形数组,其中设置了y坐标
//关于这个数组如何生成的一些限制:它将由如下所示的yTop属性进行排序,但没有辅助排序条件。
//yBottom和yTop之间的矩形差始终至少为15,换句话说,此数组不包含任何高度小于15的矩形
常数矩形坐标NlyExample1=[
{“rectangle_id”:“b22d”,“yTop”:0,“yBottom”:60},
{“rectangle_id”:“8938”,“yTop”:60,“yBottom”:120},
{“rectangle_id”:“e78a”,“yTop”:60,“yBottom”:120},
{“rectangle_id”:“81ed”,“yTop”:207,“yBottom”:222},
{“rectangle_id”:“b446”,“yTop”:207,“yBottom”:222},
{“rectangle_id”:“ebd3”,“yTop”:207,“yBottom”:222},
{“rectangle_id”:“2caf”,“yTop”:208,“yBottom”:223},
{“rectangle_id”:“e623”,“yTop”:227,“yBottom”:242},
{“rectangle_id”:“e6a3”,“yTop”:270,“yBottom”:320},
{“rectangle_id”:“e613”,“yTop”:272,“yBottom”:460},
{“rectangle_id”:“c2d1”,“yTop”:272,“yBottom”:290},
{“rectangle_id”:“e64d”,“yTop”:274,“yBottom”:300},
{“rectangle_id”:“b653”,“yTop”:276,“yBottom”:310},
{“rectangle_id”:“e323”,“yTop”:276,“yBottom”:310},
{“rectangle_id”:“fca3”,“yTop”:300,“yBottom”:315}
]
//我想得到这样一个结果,提供了解释,尽管我不确定我头脑中的内部计算是否是100%的。
//我想运行这样一个函数:
//优化左、右X起点,使之成为无重叠的标准化矩形区域(矩形坐标示例1,(33.3*15),10,0100);
//稍后我将进行此调用,但我需要在这里提升我的预期结果,以使模拟在我的示例的函数定义点暂时起作用。(见下文)
//就像这样,我会得到这样的结果,但我开始越来越不确定正确的结果应该是什么,我越是深入边缘的东西。
常量ExpectedResultMore或LessExample1=[
{“rectangle_id”:“b22d”,“leftX”:0,“rightX”:100,“yTop”:0,“yBottom”:60},
{“rectangle_id”:“8938”,“leftX”:0,“rightX”:50,“yTop”:60,“yBottom”:120},
{“rectangle_id”:“e78a”,“leftX”:50,“rightX”:100,“yTop”:60,“yBottom”:120},
{“rectangle_id”:“81ed”,“leftX”:0,“rightX”:33.3,“yTop”:207,“yBottom”:222},//从这一点开始,三个矩形并排排列,具有最小面积[“81ed”,“b446”,“ebd3”]
{“rectangle_id”:“b446”,“leftX”:33.3,“rightX”:66.6,“yTop”:207,“yBottom”:222},
{“rectangle_id”:“ebd3”,“isMax”:true,“leftX”:66.7,“rightX”:100,“yTop”:207,“yBottom”:222},//具有isMax属性,因为如果它尝试下一个结果,将有重叠,并且它不能从其他矩形中去掉面积
//这个矩形会被抛出,因为在这个区域中会有3个其他的矩形,每个矩形的面积最小(33.3*15);
//{“rectangle_id”:“2caf”,“yTop”:208,“yBottom”:223},由于在垂直空间的一个区域中有太多的矩形,所以暂时从结果中抛出这个矩形。
{“rectangle_id”:“e623”,“yTop”:227,“yBottom”:242,“leftX”:0,“rightX”:100},
{“rectangle_id”:“e6a3”,“leftX”:0,“rightX”:25,“yTop”:270,“yBottom”:320},
{“rectangle_id”:“e613”,“leftX”:25,“rightX”:35,“yTop”:272,“yBottom”:460},
{“rectangle_id”:“c2d1”,“leftX”:71.28,“rightX”:100,“yTop”:272,“yBottom”:290},//填充剩余空间,因为优化到最大面积需要99%
{“rectangle_id”:“e64d”,“leftX”:35,“rightX”:61.28,“yTop”:274,“yBottom”:300},
{“rectangle_id”:“b653”,“yTop”:276,“yBottom”:940,“leftX”:61.28,rightX:71.28},
{“rectangle_id”:“fca3”,“leftX”:35,“rightX”:61.28,“yTop”:300,“yBottom”:315}
]
//函数名非常长,以反映我想要做的事情。通常情况下,不要让函数如此紧张
常量优化LeftandRightXStartPoints为无重叠的格式化矩形区域=(矩形、最小面积、最小宽度、xMin、xMax)=>{
//TODO:填写优化函数。
//如果您想在这里进行更改以演示,我正在寻找的代码将在这里进行交换
如果(矩形===矩形坐标NLYEXample1&&minimumArea==(33.3*15)和&minimumWidth==10&&xMin==0&&xMax==100){//仅处理示例
返回ExpectedResultMore或LessExample1;
}否则{
log('我只知道如何处理示例1,这是由一个人计算的,很糟糕。填写函数并用工作内容替换块');
返回[];
}
}
const displayResults=(completedRectangleList)=>{
常量矩形颜色=[‘青色’、‘洋红’、‘绿色’、‘黄色’、‘橙色’]
完全矩形
typedef struct
{
    int topY;       // input parameter, filled in by the caller
    int bottomY;    // input parameter, filled in by the caller
    int leftX;      // output parameter, must be initially -1
    int rightX;     // output parameter, must be initially -1
}
stRect;

typedef struct
{
    int y;          // this is the 'topY' or 'bottomY' of a rectangle
    int type;       // either EVENT_START or EVENT_STOP
    int rectID;     // the index into the input array for this rectangle
}
stEvent;

enum { EVENT_START, EVENT_STOP };

void arrangeRectangles(stRect *rectArray, int length, int overlapLimit, int containerWidth)
{
    stQueue *eventQueue  = queueCreate();
    stQueue *regionQueue = queueCreate();

    // fill the event queue with START and STOP events for each rectangle
    for (int i = 0; i < length; i++)
    {
        stEvent startEvent = {rectArray[i].topY, EVENT_START, i};
        queueAdd(eventQueue, &startEvent);
        stEvent stopEvent  = {rectArray[i].bottomY, EVENT_STOP, i};
        queueAdd(eventQueue, &stopEvent);
    }

    while (queueIsNotEmpty(eventQueue))
    {
        // search for the end of a region, while keeping track of the overlap in that region
        int overlap = 0;
        int maxOverlap = 0;
        stEvent event;
        while (queuePop(eventQueue, &event))   // take from the event queue
        {
            queueAdd(regionQueue, &event);     // save in the region queue
            if (event.type == EVENT_START)
                overlap++;
            else
                overlap--;
            if (overlap == 0)                  // reached the end of a region
                break;
            if (overlap > maxOverlap)
                maxOverlap = overlap;
        }

        // limit the overlap as specified by the function parameter
        if (maxOverlap > overlapLimit)
            maxOverlap = overlapLimit;

        // compute the width to be used for rectangles in this region
        int width = containerWidth / maxOverlap;

        // create and initialize an array to keep track of which columns are in use
        int usedColumns[maxOverlap];
        for (int i = 0; i < maxOverlap; i++)
            usedColumns[i] = -1;

        // process the region, computing left and right X values for each rectangle
        while (queuePop(regionQueue, &event))
        {
            if (event.type == EVENT_START)
            {
                // find an available column for this rectangle, and assign the X values
                for (int column = 0; column < maxOverlap; column++)
                    if (usedColumns[column] < 0)
                    {
                        usedColumns[column] = event.rectID;
                        rectArray[event.rectID].leftX = column * width;
                        rectArray[event.rectID].rightX = (column+1) * width;
                        break;
                    }
            }
            else
            {
                // free the column that's being used for this rectangle
                for (int i = 0; i < maxOverlap; i++)
                    if (usedColumns[i] == event.rectID)
                    {
                        usedColumns[i] = -1;
                        break;
                    }
            }
        }
    }

    queueDestroy(eventQueue);
    queueDestroy(regionQueue);
}

void example(void)
{
    stRect inputArray[] = {
        {  0,150,-1,-1},
        { 30,180,-1,-1},
        {180,360,-1,-1},
        {360,450,-1,-1},
        {420,540,-1,-1},
        {450,570,-1,-1},
        {480,540,-1,-1}
    };
    int length = sizeof(inputArray) / sizeof(inputArray[0]);
    arrangeRectangles(inputArray, length, 3, 100);
}