Math 基于半径计算从正方形中心到边的矢量
给定一个正方形(由x,y,宽度,高度描述)和一个角度(以弧度为单位),我需要计算一个向量,该向量从正方形中心开始,终止于与正方形边缘以给定角度碰撞的点 我真的最感兴趣的是它的碰撞点,所以如果这能使计算更有效,请告诉我Math 基于半径计算从正方形中心到边的矢量,math,vector,2d,Math,Vector,2d,给定一个正方形(由x,y,宽度,高度描述)和一个角度(以弧度为单位),我需要计算一个向量,该向量从正方形中心开始,终止于与正方形边缘以给定角度碰撞的点 我真的最感兴趣的是它的碰撞点,所以如果这能使计算更有效,请告诉我 这可以推广到矩形吗?一般来说,多边形如何?一般化为矩形,如果a=向量与水平递增计数器cloclkwise的角度,则可以通过以下公式计算点坐标: let dx = distance from center horizontally, and dy = distance fo
这可以推广到矩形吗?一般来说,多边形如何?一般化为矩形,如果a=向量与水平递增计数器cloclkwise的角度,则可以通过以下公式计算点坐标:
let dx = distance from center horizontally, and
dy = distance form the center vertically, then
dx = if (tan(a) == 0, then width/2, else Min( height / (2 * tan(a)), width/2)
dy = if ABS(a) == Pi/2 then height/2 else Min( (width/2) * tan(a)), height/2)
那么点的坐标是:
px = (x+width/2) + dx for right quadrants (Pi/2 >= a >= - Pi/2);
= (x+width/2) - dx for left quadrants (Pi/2 <= a <= 3Pi/2)
py = (y+height/2) + dy for lower quadrants (Pi <= a <= 2Pi);
= (y+height/2) - dy for upper quadrants (0 <= a <= Pi);
右象限的px=(x+width/2)+dx(Pi/2>=a>=-Pi/2);
=(x+width/2)-dx表示左象限(Pi/2给定正方形的宽度和高度,然后可以确定正方形的中心(x+.5w,y+.5h) 从这里,您可以使用一些三角学来确定矢量线的长度:
tan(角度)=0.5x/a
式中,a=正方形中心与正方形边缘之间的距离。点为x=a,y=(高度)
请温柔一点,因为我已经用了一段时间了!:-)编辑:矩形的正确解。如果宽度或高度为零,它甚至不会崩溃! 语言:C++ .< /P> tan(89.99999)感谢James Fassett测试我的代码
#include <cstdio>
#include <math.h>
// declare nonstandard signum function
double sign(double x);
//define pi because I forgot where it's declared
double const pi = 3.14159;
//declare non-standard contangent function
double cot(double x);
int main()
{
for (double angle = 0.0 ; angle<2*pi; angle += 0.1){
//angle should be within [0, 2*pi) range
//x and y point to the _middle_ of the rectangle
double x = 0; double y = 0 ;
double width = 1, height = 4;
double base_angle = atan(height/width);
// the angle between rectangle diagonal and Ox axis
double px,py;
// Which side we're on?
bool left = (fabs(angle - pi) < base_angle);
bool right = (angle> 2*pi-base_angle || angle < base_angle);
bool top = (fabs(angle - pi/2) <= fabs(pi/2 - base_angle));
bool bottom = (fabs(angle - 3*pi/2) <= fabs(pi/2 - base_angle));
// The helper values used to adjust sides
int lr = (left?-1:0) + (right?1:0);
int tb = (bottom?-1:0) + (top?1:0);
if (lr) {
// we're on vertical edge of rectangle
px = x+width/2*lr;
py = y+width/2*tan(angle)*lr;
} else {
// we're on the horizontal edge or in the corner
px = x+height/2*cot(angle)*tb;
py = y+height/2*tb;
}
printf(" a = %d deg: x = %lf; y = %lf\n",(int)(angle/pi*180),px,py);
}
return 0;
}
// define nonstandard signum function
double sign(double x)
{
if (x<0) return -1;
if (x>0) return 1;
return 0;
}
//define non-standard contangent function
double cot(double x)
{
return tan(pi/2 - x);
}
#包括
#包括
//声明非标准符号函数
双符号(双x);
//定义pi,因为我忘了它在哪里声明
双常数pi=3.14159;
//声明非标准连续函数
双胶辊(双x);
int main()
{
对于(双角度=0.0;角度向量将是center+(cos(角度),sin(角度))*magnity
。如果要将其与正方形相交,则需要确定大小。可以使用以下正方形获得:
float abs_cos_angle= fabs(cos(angle));
float abs_sin_angle= fabs(sin(angle));
if (width/2/abs_cos_angle <= height/2/abs_sin_angle)
{
magnitude= fabs(width/2/abs_cos_angle);
}
else
{
magnitude= height/2/abs_sin_angle;
}
float abs_cos_angle=fabs(cos(angle));
浮动绝对值sin角度=fabs(sin(角度));
如果(width/2/abs\u cos\u angle编辑:Pavel现在有另一个工作实现(他很好地致力于调试他的解决方案),但我将把它作为另一个仅适用于正方形的替代方案(Pavel的矩形工作)
专用函数CalculateInTransquare(宽度:数字,角度:数字):点
{
//单角缠绕
角度=(数学PI*2+角度)%(数学PI*2);
//从中心计算归一化向量
//将一个正方形的边缘考虑在内
//八个可能的象限
var-myX:数字;
var-myY:数字;
如果(角度<数学PI/4)
{
myX=1;
myY=数学tan(角度);
}
否则如果(角度<数学PI/2)
{
myX=Math.tan(Math.PI/2-角度);
myY=1;
}
否则如果(角度<3*数学PI/4)
{
myX=-Math.tan(angle-Math.PI/2);
myY=1;
}
else if(角度<数学PI)
{
myX=-1;
myY=Math.tan(Math.PI-角度);
}
否则如果(角度<5*数学PI/4)
{
myX=-1;
myY=-Math.tan(angle-Math.PI);
}
否则如果(角度<3*数学PI/2)
{
myX=-Math.tan((3*Math.PI/2)-角度);
myY=-1;
}
否则如果(角度<7*数学PI/4)
{
myX=Math.tan(角度-(3*Math.PI/2));
myY=-1;
}
其他的
{
myX=1;
myY=-Math.tan(Math.PI*2-角度);
}
//缩放并平移向量
返回新点(
(myX*宽度/2)+宽度/2,
(myY*宽度/2)+宽度/2);
}
在大多数语言中,如果角度为+/-pi/2弧度,则无论是否在Min()范围内,tan(角度)都会放大所有值。这并不适用于[0,2*pi]范围内的所有值。例如,当a=6.201503898186251时,则dx=-305.38621689379323,这显然是不正确的。将dx的计算更改为包含Max(-width/2)正确限定值,但在许多范围内(包括[0,pi/2]内)答案仍然不正确你的问题不够精确,无法确定答案是什么。从一个矩形的中心开始,对于足够大的角度值,我可以从中心画8条线,与该角度的矩形边相交-导致8个向量。你想要哪一个?一般来说,关于plygons,你应该首先定义你的概念多边形的中心。@Vinay:角度在0-2*pi范围内@Pavel:别介意多边形-我想的是正多边形,但除了理论上的Corry Pavel,我对它没有什么兴趣,但“符号”是不是意味着“正弦”?cot是余弦还是余切?当我做出这些假设时,并非所有计算点都位于矩形的周长上。哦,符号表示“符号”,或“符号”。+1表示正数,-1表示负数,0表示零。cot表示余切。查看维基百科,了解这些函数在英语中的表示方式。[[主题外]顺便说一句,重新检查一下学校所有的数学题:例如“直角三角形”对我来说是个惊喜。]我已经测试过了,虽然对某些角度范围正确,但对大多数人来说都是错误的。看我的答案,它更详细,但更正确。我修正了我的帖子。它包含了几个拼写错误(宽度没有乘以2,我忘记了矩形的左侧),但数学上没有错误!请用绿色标记我的解决方案,并免费使用代码:)最难的一点是确定a——从中心到矩形边缘的距离。如果我能做到这一点,那么sohcahtoa就是我所需要的。上面的方程在求解时提供了这一点。你有角度(因此有切线),你有x。你所需要的就是解a,
float abs_cos_angle= fabs(cos(angle));
float abs_sin_angle= fabs(sin(angle));
if (width/2*abs_sin_angle <= height/2*abs_cos_angle)
{
magnitude= width/2/abs_cos_angle;
}
else
{
magnitude= height/2/abs_sin_angle;
}
double magnitude;
double abs_cos_angle= fabs(cos(angle));
double abs_sin_angle= fabs(sin(angle));
if (width/2*abs_sin_angle <= height/2*abs_cos_angle)
{
magnitude= width/2/abs_cos_angle;
}
else
{
magnitude= height/2/abs_sin_angle;
}
double check_x= x + cos(angle)*magnitude;
double check_y= y + sin(angle)*magnitude;
printf(" a = %d deg: x = %lf; y = %lf\n",(int)(angle/pi*180),check_x,check_y);
private function calculatePointOnSquare(width:Number, angle:Number):Point
{
// simple angle wrapping
angle = (Math.PI*2 + angle) % (Math.PI*2);
// calculate a normalized vector from the centre
// of a square to the edge taking into account
// the eight possible quadrants
var myX:Number;
var myY:Number;
if(angle < Math.PI/4)
{
myX = 1;
myY = Math.tan(angle);
}
else if(angle < Math.PI/2)
{
myX = Math.tan(Math.PI/2 - angle);
myY = 1;
}
else if(angle < 3*Math.PI/4)
{
myX = -Math.tan(angle - Math.PI/2);
myY = 1;
}
else if(angle < Math.PI)
{
myX = -1;
myY = Math.tan(Math.PI - angle);
}
else if(angle < 5*Math.PI/4)
{
myX = -1;
myY = -Math.tan(angle - Math.PI);
}
else if(angle < 3*Math.PI/2)
{
myX = -Math.tan((3*Math.PI/2) - angle);
myY = -1;
}
else if(angle < 7*Math.PI/4)
{
myX = Math.tan(angle - (3*Math.PI/2));
myY = -1;
}
else
{
myX = 1;
myY = -Math.tan(Math.PI*2 - angle);
}
// scale and translate the vector
return new Point(
(myX * width/2) + width/2,
(myY * width/2) + width/2);
}