2013-01-05 25 views
0

我正在做一个项目,您应该可以在Windows窗体环境中创建形状。我目前有两种不同的形状,称为Circle1和Rectangle1,它们正是它们所称的具有类似的属性。将图形带到前面F#

type Rectangle1(x:int, y:int,brush1)= 
    let mutable thisx = x 
    let mutable thisy = y 
    let mutable thiswidth = 50 
    let mutable thisheight = 20 
    let mutable brush = brush1 
    member obj.x with get() = thisx and set x = thisx <- x 
    member oby.y with get() = thisy and set y = thisy <- y 
    member obj.brush1 with get() = brush and set brush1 = brush <- brush1 
    member obj.width with get() = thiswidth and set width = thiswidth <- width 
    member obj.height with get() = thisheight and set height = thisheight <- height 
    member obj.draw(g:Graphics) = g.FillRectangle(brush,thisx,thisy,thiswidth,thisheight) 

这个矩形是可点击和移动的,但我遇到了一个问题。我需要一些类似于c#bringToFront()方法的方法。所以当我点击一个形状时,我的形状就会转到所有其他形状的前面。

我的存储列表如下:

let mutable RectangleList:List<Rectangle1> = [] 

我用一则hitTest来确定用户是否击中的形状或不:

let rec VilketObjRec (e:MouseEventArgs) (inputlist:List<Rectangle1>) = 
match inputlist with 
    |[] -> None 
    |head::tail -> if (((e.X >= head.x) && (e.X <= (head.x + head.width))) && (e.Y >= head.y) && (e.Y <= (head.y+head.height))) 
         then Some(head) else VilketObjRec e tail 

任何人有什么样的想法,如何解决这个问题?坦率地说,我迷路了。

回答

1

基本思路:您可以添加一个z坐标到Rectangle1类。当一个矩形被击中时,确保它获得最高值z值。绘制矩形之前,请确保按照升序z的值排序。

3

基于命中测试功能,看来你RectangleList商店比它们出现在屏幕上的顺序颠倒顺序的矩形(在开始的矩形被击中首先测试,因此这将是一个在图的顶部)。

在这种情况下,如果要将矩形放在顶部,只需将其移至列表的开头。您可以创建一个新的列表与年初指定的值,然后从列表的其余部分删除值使用filter

let BringToFront value list = 
    value :: (List.filter (fun v -> v <> value) list) 

功能的工作原理ANLY名单上,所以这里使用整数的例子:

BringToFront 3 [ 1;2;3;4 ] = [3;1;2;4] 
2

Wmeyer's和Tomas的答案很好地满足您对相对较小的一组矩形的要求。如果您将使用10^3或更多的矩形,并且在GUI启动之前知道它们的坐标,则有简单的静态结构enter link description here。在更复杂的情况下,Hanan Samet的“空间数据结构的设计和分析”第3章是您最好的朋友。