2016-05-16 4 views
1

enter image description hereПолучить X, Y координата на краю ромба, на основе ромба ширины и угла

Я разрабатываю Processing эскиз, который, учитывая определенный угол, рисующий точку на краю ромб.

Я знаю ширину ромба и его положение, но я не уверен, как рассчитать координаты x-y точки, покоящейся на ее краю.

Есть ли какие-либо изящные решения этой проблемы? Любая помощь в псевдокоде будет приветствоваться.

+0

Только так вы знаете, [Обработка не так же, как Java] (http://meta.stackoverflow.com/questions/321127/processing-java). – CodeMouse92

+0

Ты совершенно прав. Я упомянул Java, поскольку обработка может не быть известна всем. – Augusto

ответ

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 
+0

что обозначается P '= (H, Tan (Alpha)), P' = (котангенс (альфа), H) и т. Д.? – Augusto

+0

P '= (X, Y) - повернутая точка. Тан (Альфа) - касательная функция. Редактирование примечания - добавляется умножение на H – MBo

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

Вообразите круг с большим r радиус, который будет пересекать ваш ромб в точках, которые вы хотите. Один из способов рисования в этом месте - использовать вложенную систему координат, которую вы переводите и вращаете. Все, что вам нужно знать, это радиус и угол.

Вот очень простой пример:

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>

Если вы хотите вычислить позицию, вы можете использовать формулу преобразования полярной формы в декартовую форму:

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; 
} 

Другим вариантом было бы с помощью матриц преобразования

Смежные вопросы