根据菱形'获取菱形边缘的X,Y坐标。宽度和角度

时间:2016-05-16 11:22:07

标签: math processing trigonometry

enter image description here

我正在开发一个Processing草图,在给定一定角度的情况下,在菱形边缘绘制一个点。

我知道菱形的宽度及其位置,但我不知道如何计算其边缘处的点的x-y坐标。

这个问题有没有优雅的解决方案?任何伪代码的帮助都会受到欢迎。

3 个答案:

答案 0 :(得分:2)

根据你的图像,你想要找到两个方程的交集,即角度θ的线的方程,以及它与之相交的方的边的方程。

假设你的方格的大小是n,则方形的方程是y=±(n*(√2/2))±x(由毕达哥拉斯定理)。您在图像中相交的边的等式为y=n*(√2/2)-x

径向线的方程式可以使用三角法计算得到y=tan(θ)*x,其中θ用弧度表示。

然后,您可以将其解析为simultaneous equation以确定交叉点。请注意,它将与正方形的两侧(上方和下方)相交,因此如果您只想要那个,则必须选择方形正确边的方程式。还要防止θ为π/ 2的情况,因为tan(π/ 2)未定义。您可以轻松地计算出这种情况,因为x = 0,因此它始终与y=±(n*(√2/2))相交。

在您的示例中,交集发生在x*(1+tan(θ))=n*(√n/n)x=(n*(√n/n))/(1+tan(θ))时。你可以计算出来,把它重新插回到y,那就是你的(x,y)交点。

答案 1 :(得分:2)

我们的正方形边长为A,半长为H = A/2。角度Theta。交点P. 所有坐标都相对于方形中心。

-Pi/4,角度Alpha = Theta - Pi/4

旋转方块
if Alpha lies in range -Pi/4..Pi/4, then intersection point P' = (H, H*Tan(Alpha))
if Alpha lies in range Pi/4..3*Pi/4, then P' = (H*Cotangent(Alpha), H)
if Alpha lies in range 3*Pi/4..5*Pi/4, then P' = (-H, -H*Tan(Alpha))
if Alpha lies in range 5*Pi/4..7*Pi/4, then P' = (-H*Cotangent(Alpha), -H)

然后将P'转回Pi/4

S = Sqrt(2)/2
P.X = S * (P'.X - P'.Y)
P.Y = S * (P'.X + P'.Y)

示例(草图等数据):

A = 200, Theta = 5*Pi/12  
H = 200/2 = 100, Alpha =Theta-Pi/4 = Pi/6
P'.X = H = 100
P'.Y = H * Tan(Alpha) = 100 * Tan(Pi/6) ~= 57.7

S = 0.707
P.X = 0.707 * (100 - 57.7) = 30
P.Y = 0.707 * (100 + 57.7) = 111

答案 2 :(得分:1)

想象一个半径较大的圆,它会在你想要的点上与你的菱形相交。在该位置绘制的一种方法是使用您平移和旋转的嵌套坐标系。您需要知道的是半径和角度。

这是一个非常基本的例子:

float angle = radians(-80.31);
float radius = 128; 

float centerX,centerY;
void setup(){
  size(320,320);
  noFill();
  rectMode(CENTER);

  centerX = width * 0.5;
  centerY = height * 0.5;
}
void draw(){
  background(255);
  noFill();
  //small circle
  strokeWeight(1);
  stroke(95,105,120);
  ellipse(centerX,centerY,210,210);
  rhombus(centerX,centerY,210);
  //large circle
  strokeWeight(3);
  stroke(95,105,120);
  ellipse(centerX,centerY,radius * 2,radius * 2);

  //line at angle
  pushMatrix();
    translate(centerX,centerY);
    rotate(angle);
    stroke(162,42,32);
    line(0,0,radius,0);
  popMatrix();

  //debug
  fill(0);
  text("angle: " + degrees(angle),10,15);
}
void rhombus(float x,float y,float size){
  pushMatrix();
  translate(x,y);
  rotate(radians(45));
  rect(0,0,size,size);
  popMatrix();
}
void mouseDragged(){
  angle = atan2(centerY-mouseY,centerX-mouseX)+PI;
}

您可以在此处尝试演示(可以拖动鼠标来改变角度):



var angle;
var radius = 128; 

var centerX,centerY;
function setup(){
  createCanvas(320,320);
  noFill();
  rectMode(CENTER);
  
  angle = radians(-80.31);
  centerX = width * 0.5;
  centerY = height * 0.5;
}
function draw(){
  background(255);
  noFill();
  //small circle
  strokeWeight(1);
  stroke(95,105,120);
  ellipse(centerX,centerY,210,210);
  rhombus(centerX,centerY,210);
  //large circle
  strokeWeight(3);
  stroke(95,105,120);
  ellipse(centerX,centerY,radius * 2,radius * 2);
  
  //line at angle
  push();
    translate(centerX,centerY);
    rotate(angle);
    stroke(162,42,32);
    line(0,0,radius,0);
  pop();
  
  //debug
  fill(0);
  noStroke();
  text("angle: " + degrees(angle),10,15);
}
function rhombus(x,y,size){
  push();
  translate(x,y);
  rotate(radians(45));
  rect(0,0,size,size);
  pop();
}
function mouseDragged(){
  angle = atan2(centerY-mouseY,centerX-mouseX)+PI;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.0/p5.min.js"></script>
&#13;
&#13;
&#13;

如果要计算位置,可以使用极坐标到笛卡尔坐标转换公式:

x = cos(angle) * radius
y = sin(angle) * radius

这是一个使用它的例子。请注意,绘图是从中心完成的,因此中心坐标将添加到上面:

float angle = radians(-80.31);
float radius = 128; 

float centerX,centerY;
void setup(){
  size(320,320);
  noFill();
  rectMode(CENTER);

  centerX = width * 0.5;
  centerY = height * 0.5;
}
void draw(){
  background(255);
  noFill();
  //small circle
  strokeWeight(1);
  stroke(95,105,120);
  ellipse(centerX,centerY,210,210);
  rhombus(centerX,centerY,210);
  //large circle
  strokeWeight(3);
  stroke(95,105,120);
  ellipse(centerX,centerY,radius * 2,radius * 2);

  //line at angle
  float x = centerX+(cos(angle) * radius);
  float y = centerX+(sin(angle) * radius);
  stroke(162,42,32);
  line(centerX,centerY,x,y);

  //debug
  fill(0);
  text("angle: " + degrees(angle),10,15);
}
void rhombus(float x,float y,float size){
  pushMatrix();
  translate(x,y);
  rotate(radians(45));
  rect(0,0,size,size);
  popMatrix();
}
void mouseDragged(){
  angle = atan2(centerY-mouseY,centerX-mouseX)+PI;
}

另一种选择是使用转换矩阵

相关问题