数字线压缩和对接控件

Number line compression and docking controls

嗨数学家们。

我有点难过,我想知道是否有任何算法可以帮助我。

首先是概念性问题,假设我有一堆沿着 X 轴的盒子。我希望能够在轴上选择一个任意点 A 并将左侧的所有内容缩放到其原始宽度和位置的 95% 并进行补偿,右侧的所有内容都必须缩放到 105%。结果框的宽度很容易计算,因为它是原始宽度乘以比例。我遇到的问题是如何计算现在在 A 点创建的间隙,以便我可以将第二部分向左移动以关闭该间隙。

此外,我不仅想select一个点A,还有一个B点和C点,等等,并且能够同样地缩小他们的差距。

--我问的真正原因--

现在解决实际问题(以防其他人遇到过这个问题。)我在 C# Winforms 应用程序中有一个控件,它是我来这里之前由某个程序员制作的。该控件可以包含任意数量的子控件,每个子控件都有自己的相对坐标作为宽度或高度的百分比(即,相对 X 坐标为 0.5 的控件将放置在父容器的中间。

我们迫切需要支持多个显示器,而我遇到的问题是,如果您将控件或工具栏停靠在我们的专有控件旁边,则 ClientRectangle 较小,因此它会像这样围绕子边框移动

我的老板不喜欢线条越过显示器边界,他希望我只在停靠 window 的同一台显示器上弄乱线条。我已经能够使用上述概念获得 90% 的方法,但我似乎无法正确计算重新间距。

这是我认为计算差距的数学模型。

假设您有一个起点 A,我们将其定义为 xA。

现在,让我们定义框

//Box{x0,x1}
Boxes = {[B1]{0,100},[B2]{100,200},[B3]{200,400},[B4]{400,450},[B5]{450,700}}

现在我们在 X 轴上有 5 个框。

让我们定义;

A = xA = 370;
TotalLength = 700;

如果将 700 除以 2,则得到 350,这就是中点,而 370 大于中点值。也就是说,在这种情况下,您需要将左侧的元素移动到右侧。差距的计算如下;

IF(Midpoint < A)
    Gap = ((A- Midpoint) * 100 ) / TotalLength //This is the gap in percent
ELSE
    Gap = ((Midpoint - A) * 100) / TotalLength 

这样你就可以找到差距了。您需要移动的轴将需要根据您选择的点来决定,如果选择的点小于中点则向右移动,如果更高则向左移动(到正轴路线)。

希望对您有所帮助。

感谢外科医生的帮助。不幸的是,我无法使用您的方法找到解决方案。从好的方面来说,我能够找到解决方案。诀窍是将 X 坐标视为客户端矩形左边缘和 X 坐标位置之间的宽度,并以类似于子宽度的方式计算它。

为了更具体,这是我为处理对接问题而提出的算法:

var clientOriginalWidth = what the width of the Client rectangle would be without docks
var clientCompressedWidth = the width of the client now

//Calculate the Compression Ratio for each screen as follows
foreach(var screen in Screens){
  var widthOfClientRectOnScreenNow = how much of the client rectangle is on this screen
  var widthOfClientRectOnScreenWithoutDocks = how much of the client rectangle was on the screen before the docks were there
  var compressionRatio = (widthOfClientRectOnScreenNow / clientCompressedWidth) / 
                     (widthOfClientRectOnScreenWithoutDocks / clientOriginalWidth);

  //Assuming control.xScale and control.widthScale are initially 0
  foreach(var control in ParentControl){
     var controlBounds = where the control was when the client was full width
     if(controlBounds.X > screen.right){
        var percentOfXPositionOnScreen = screen.right - screen.left / control.x;
        controlBounds.xScale += percentOfPositionOnScreen * compressionRatio;
     }
     else if(control.X > screen.left){
       var percentOfXPositionOnScreen = control.x - screen.left / control.x;
       controlBounds.xScale += percentOfPositionOnScreen * compressionRatio;
     }

     if(screen.intersects(controlBounds){
       var percentControlIsOnScreen = what percent of the control's width was on this screen
       control.widthScale += percentControlIsOnScreen * compressionRatio;
     }
  }
}

然后通过将原始X坐标乘以比例(宽度相同)来找到位置。卸下码头后,重新计算比例。移除所有码头后,比例应为 1.

我省略了一些细节以使其更像是一种通用算法,但人们应该能够在自己的系统上解决这个问题。