2014-03-04 69 views
2

我打破我的脖子试图解决这个问题... 该点应该位于鼠标指向的地方的边界上。换句话说,在矩形边界线和矩形中心与鼠标指针之间的一条线之间交叉。不知何故,我需要使用三角形,因为矩形可能会旋转。下面的代码(在处理)让我画点,但仅在南边界...如何在矩形的边框上绘制点?

int size = 200; 

void setup() { 
    size(1200,500); 
    smooth(); 
    ellipseMode(CENTER); 
    rectMode(CENTER); 

} 

void draw() { 
    background(255); 
    noFill(); 

    PVector center = new PVector(width/2,height/2); 
    PVector mouse = new PVector(mouseX, mouseY); 

    float mouseDistance = PVector.dist(center,mouse); 

    mouse.sub(center); // mouse coordinates relative to center point 

    float t = atan2(mouse.y, mouse.x); 

    float borderDistance = (size/2)/sin(t); 
    float bx = cos(t) * borderDistance; 
    float by = sin(t) * borderDistance; 

    pushMatrix(); 
    translate(center.x, center.y); 
    strokeWeight(5); 
    stroke(255,0,0); 
    point(0,0); 
    point(mouse.x, mouse.y); 
    point(cos(t)*size/2, sin(t)*size/2); 
    point(bx,by); 
    strokeWeight(1); 
    stroke(0); 
    ellipse(0, 0, size, size); 
    rect(0,0, size, size); 
    stroke(0,255,0); 
    line(0, 0, mouse.x, mouse.y); 
    popMatrix(); 
} 

回答

5

好这里是将要涉及到给你想要的点的位置的数学。

图以供参考:

Problem Diagram

为了找到Green点,我们需要做的是找到找到的高度和假想矩形(参见图像)的宽度,其标记为AdjOpp,并将这些值添加到Center点。


如果你还记得SOH CAH TOA,我们将利用TOA

Tan(Theta) = Opposite/Adjacent 

可以重新安排:

Opposite = Tan(Theta) * Adjacent 

所以我们需要先找到Adjacent (Adj)Theta。图


咨询,Adj显然是OrangeCenter之间y的区别:

Adj = Orange.y - Center.y 

但我们不知道Orange?那么,Orange将等于Center加上矩形高度的一半:

Orange = (Center.x, Center.y + Rect.Height/2) 

底涂的Orange回值到我们Adj计算:

Adj = Center.y + Rect.Height/2 - Center.y 
Adj = Rect.Height/2 

接下来我们需要找到Theta

​​

Rerfering回SOH CAH TOACAH

Cos(Theta) = Adjacent/Hypotenuse 
Theta = acos(Adjacent/Hypotenuse) //Inverse cosine 

我们已经知道,Adj = Rect.Height/2从早期的,所以我们只需要找到Hyp。为了找到Hyp我们可以使用distance formula它说:

d = sqrt((x2 - x1)^2 + (y2 - y1)^2) 

在我们的例子:

Hyp = sqrt((Center.x - Mouse.x)^2 + (Center.y - Mouse.y)^2) 

所以现在我们有我们需要为Theta一切:

Theta = acos(Adj/Hyp) //Inverse cosine 

最后,我们有我们需要的Opp

Opp = Tan(Theta) * Adjacent 

,这意味着我们有我们需要回答你的问题的一切:

Green = (Center.x + Opp, Center.y + Adj) 

注:

  • 这是 “纸上谈兵数学” 使用度。很多编程语言处理弧度而不是度数,所以你可能需要做一些转换。

  • 由于@Jerry安德鲁斯指出,将有四个不同的情况下这个问题,这对应于矩形的四个不同的侧面,你的绘图点可能落在:

要确定象限,他首先需要矩形的中心 与任何角落之间的角度 - 因此,atan(高度/宽度)。这将使 给出半角(如果绿色位于角上,则为中心至绿色)。然后 atan(mouse.y/mouse.x)将提供从 矩形中心到鼠标光标的线的角度(因为在他的代码中,鼠标 位于相对于矩形中心的位置)。

+1

+1令人敬畏的图表。请注意,如果鼠标位于矩形的左侧,则响应可能会有所不同,因此该分段与西墙而不是南墙相交......他将不得不弄清楚他正在为完全一般回答。 –

+0

是的,这是一个很好的观点。同样对于OP:我现在只是测试了这个,希望我能记得HighSchool的所有东西:) – Tyler

+1

要确定象限,他首先需要矩形中心与任何角落之间的角度 - 因此,atan(height /宽度)。这将产生半角(如果绿色位于角落,则为中心至绿色)。然后atan(mouse.y/mouse.x)将提供从矩形中心到鼠标光标的线的角度(因为在他的代码中,鼠标相对于矩形的中心而定位)。最后,您的解决方案有四种变体,每个象限一个变体。 –

0

OK!我设法解决了边界问题。 this link

下处理草图和可用的代码我用ATAN2()函数来计算mouseTheta然后在需要用象限玩:

// north 
     borderPoint = new PVector(tan(mouseTheta-HALF_PI)*r, -r); 
// east 
     if(mouseTheta > TWO_PI-QUARTER_PI || mouseTheta < QUARTER_PI) 
     borderPoint = new PVector(r, tan(mouseTheta)*r); 
// south 
     if(mouseTheta >= QUARTER_PI && mouseTheta < QUARTER_PI+HALF_PI) 
     borderPoint = new PVector(-tan(mouseTheta-HALF_PI)*r, r); 
// west 
     if(mouseTheta >= HALF_PI+QUARTER_PI && mouseTheta < PI+QUARTER_PI) 
     borderPoint = new PVector(-r,-tan(mouseTheta)*r); 

相貌丑陋,但工程...谢谢!