导航:首页 > 源码编译 > atan2算法

atan2算法

发布时间:2023-05-24 08:47:43

⑴ 三轴指南针 HMC5883L 的角度算法公式是怎样的如何使用C/C++编程序将数据处理并返回呢

HMC携迟HMC_count()
{
HMCcount;
intx,y,z;
doubleangle;

Multiple_Read_HMC5883(); //连续读出数据,存储在BUF中
x=HMC_BUF[0]<<8|HMC_BUF[1];//
z=HMC_BUF[2]<<8|HMC_BUF[3];//CombineMSBandLSBofZData唤埋outputregister
y=HMC_BUF[4]<<8|HMC_BUF[5];//
angle=atan2((double)y,(double)x)*(180/辩链李3.14159265)+180;//angleindegrees
count.x=x;
count.y=y;
count.z=z;
count.angle=angle;
returncount;
}

⑵ 加速度计和陀螺仪融合的算法

给你arino的卡尔曼滤波融合算法,非原创,我只是封装了算法。

H文件:
/*
* KalmanFilter.h
* Non-original
* Author: x2d
* Copyright (c) 2012 China
*
*/

#ifndef KalmanFilter_h
#define KalmanFilter_h

#include <WProgram.h>

class KalmanFilter
{
public:
KalmanFilter();

/*
卡尔曼融合计算
angle_m: 加速度计测量并通过atan2(ax,ay)方法计算得到的角度(弧度值)
gyro_m:陀螺仪测量的角速度值(弧度值)
dt:采样时间(s)
outAngle:卡尔曼融合计算出的角度(弧度值)
outAngleDot:卡尔曼融合计算出的角速度(弧度值)
*/
void getValue(double angle_m, double gyro_m, double dt, double &outAngle, double &outAngleDot);

private:
double C_0, Q_angle, Q_gyro, R_angle;
double q_bias, angle_err, PCt_0, PCt_1, E, K_0, K_1, t_0, t_1;
double angle, angle_dot;
double P[2][2];
double Pdot[4];
};

CPP文件:
/*
* KalmanFilter.cpp
* Non-original
* Author: x2d
* Copyright (c) 2012 China
*
*/

#include "KalmanFilter.h"

KalmanFilter::KalmanFilter()
{
C_0 = 1.0f;
Q_angle = 0.001f;
Q_gyro = 0.003f;
R_angle = 0.5f;
q_bias = angle_err = PCt_0 = PCt_1 = E = K_0 = K_1 = t_0 = t_1 = 0.0f;
angle = angle_dot = 0.0f;
P[0][0] = 1.0f;
P[0][1] = 0.0f;
P[1][0] = 0.0f;
P[1][1] = 1.0f;
Pdot[0] = 0.0f;
Pdot[1] = 0.0f;
Pdot[2] = 0.0f;
Pdot[3] = 0.0f;
}

void KalmanFilter::getValue(double angle_m, double gyro_m, double dt, double &outAngle, double &outAngleDot)
{
/*
Serial.print("angle_m = ");
Serial.print(angle_m);
Serial.print(";");
Serial.print("gyro_m = ");
Serial.print(gyro_m);
Serial.print(";");
*/

angle+=(gyro_m-q_bias) * dt;
angle_err = angle_m - angle;
Pdot[0] = Q_angle - P[0][1] - P[1][0];
Pdot[1] = -P[1][1];
Pdot[2] = -P[1][1];
Pdot[3] = Q_gyro;
P[0][0] += Pdot[0] * dt;
P[0][1] += Pdot[1] * dt;
P[1][0] += Pdot[2] * dt;
P[1][1] += Pdot[3] * dt;
PCt_0 = C_0 * P[0][0];
PCt_1 = C_0 * P[1][0];
E = R_angle + C_0 * PCt_0;
K_0 = PCt_0 / E;
K_1 = PCt_1 / E;
t_0 = PCt_0;
t_1 = C_0 * P[0][1];
P[0][0] -= K_0 * t_0;
P[0][1] -= K_0 * t_1;
P[1][0] -= K_1 * t_0;
P[1][1] -= K_1 * t_1;
angle += K_0 * angle_err;
q_bias += K_1 * angle_err;
angle_dot = gyro_m-q_bias;

outAngle = angle;
outAngleDot = angle_dot;
/*
Serial.print("angle = ");
Serial.print(angle);
Serial.print(";");
Serial.print("angle_dot = ");
Serial.print(angle_dot);
Serial.print(";");
*/
}
#endif

⑶ FLASH AS3.0算法问题

这样是可以团好蔽的,你要的功能都实现了,QQ详谈:277358315或袜旁者HI我。塌州

⑷ 求as3物体移动算法

下面是核心代码

(evt:MouseEvent):void
{
//记录目标位置
targetPosX=evt.stageX;
targetPosY=evt.stageY;

//分别记录x方向和y方向上的速度
varang:Number=Math.atan2(targetPosY-mc.y,targetPosX-mc.x);
speedX=speed*Math.cos(ang);
speedY=speed*Math.sin(ang);
芦闹喊
//设置mc运动
isMove=true;
}

上面的方法是在点击舞台的时候调用

(evt:TimerEvent):void
{
if(!isMove)
{
return;
}
if(Math.sqrt((mc.x-targetPosX)*(mc.x-targetPosX)+(mc.y-targetPosY)*(mc.y-targetPosY))<2)
{
//如果mc和目标位置的距离小于2,将设置mc不可运动,将mc位置调至目标位置
isMove=false;
mc.x=targetPosX;
弯吵陪野mc.y=targetPosY;
}
else
{
mc.x+=speedX;
mc.y+=speedY;
}
}

上面的方法是在Event.ENTER_FRAME中触发,我这里用的是Timer

详细的代码,请看附件,直接新建一个Fla(Actionscript 3.0)文档 将此类设置为文档类,测试,就会出效果了,不明白的话 Hi我

⑸ 如何应用matlab进行fft分析

FFT是离散傅立叶变换的快速算法,可以将一个信号变换
到频域。有些信号在时域上是很难看出什么特征的,但是如
果变换到频域之后,就很容易看出特征了。这就是很多信号
分析采用FFT变换的原因。另外,FFT可以将一个信号的频谱
提取出来,这在频谱分析方面也是经常用的。
虽然很多人都知道FFT是什么,可以用来做什么,怎么去
做,但是却不知道FFT之后的结果是什意思、如何决定要使用
多少点来做FFT。

现在圈圈就根据实际经验来说说FFT结果的具体物理意义。
一个模拟信号,经过ADC采样之后,就变成了数字信号。采样
定理告诉我们,采样频率要大于信号频率的两倍,这些我就
不在此罗嗦了。

采样得到的数字信号,就可以做FFT变换了。N个采样点,
经过FFT之后,就可以得到N个点的FFT结果。为了方便进行FFT
运算,通常N取2的整数次方。

假设采样频率为Fs,信号频率F,采样点数为N。那么FFT
之后结果就是一个为N点的复数。每一个点就对应着一个频率
点。这个点的模值,就是该频率值下的幅度特性。具体跟原始
信号的幅度有什么关系呢?假设原始信号的峰值为A,那么FFT
的结果的每个点(除了第一个点直流分量之外)的模值就是A
的N/2倍。而第一个点就是直流分量,它的模值就是直流分量
的N倍。而每个点的相位呢,就是在该频率下的信号的相位。
第一个点表示直流分量(即0Hz),而最后一个点N的再下一个
点(实际上这个点是不存在的,这里是假设的第N+1个点,也
可以看做是将第一个点分做两半分,另一半移到最后)则表示
采样频率Fs,这中间被N-1个点平均分成N等份,每个点的频率
依次增加。例如某点n所表示的频率为:Fn=(n-1)*Fs/N。
由上面的公式可以看出,Fn所能分辨到频率为为Fs/N,如果
采样频率Fs为1024Hz,采样点数为1024点,则可以分辨到1Hz。
1024Hz的采样率采样1024点,刚好是1秒,也就是说,采样1秒
时间的信号并做FFT,则结果可以分析到1Hz,如果采样2秒时
间的信号并做FFT,则结果可以分析到0.5Hz。如果要提高频率
分辨力,则必须增加采样点数,也即采样时间。频率分辨率和
采样时间是倒数关系。
假设FFT之后某点n用复数a+bi表示,那么这个复数的模就是
An=根号a*a+b*b,相位就是Pn=atan2(b,a)。根据以上的结果,
就可以计算出n点(n≠1,且n<=N/2)对应的信号的表达式为:
An/(N/2)*cos(2*pi*Fn*t+Pn),即2*An/N*cos(2*pi*Fn*t+Pn)。
对于n=1点的信号,是直流分量,幅度即为A1/N。
由于FFT结果的对称性,通常我们只使用前半部分的结果,
即小于采样频率一半的结果。

好了,说了半天,看着公式也晕,下面圈圈以一个实际的
信号来做说明。

假设我们有一个信号,它含有2V的直流分量,频率为50Hz、
相位为-30度、幅度为3V的交流信号,以及一个频率为75Hz、
相位为90度、幅度为1.5V的交流信号。用数学表达式就是如下:

S=2+3*cos(2*pi*50*t-pi*30/180)+1.5*cos(2*pi*75*t+pi*90/180)

式中cos参数为弧度,所以-30度和90度要分别换算成弧度。
我们以256Hz的采样率对这个信号进行采样,总共采样256点。
按照我们上面的分析,Fn=(n-1)*Fs/N,我们可以知道,每两个
点之间的间距就是1Hz,第n个点的频率就是n-1。我们的信号
有3个频率:0Hz、50Hz、75Hz,应该分别在第1个点、第51个点、
第76个点上出现峰值,其它各点应该接近0。实际情况如何呢?
我们来看看FFT的结果的模值如图所示。

图1 FFT结果
从图中我们可以看到,在第1点、第51点、和第76点附近有
比较大的值。我们分别将这三个点附近的数据拿上来细看:
1点: 512+0i
2点: -2.6195E-14 - 1.4162E-13i
3点: -2.8586E-14 - 1.1898E-13i

50点:-6.2076E-13 - 2.1713E-12i
51点:332.55 - 192i
52点:-1.6707E-12 - 1.5241E-12i

75点:-2.2199E-13 -1.0076E-12i
76点:3.4315E-12 + 192i
77点:-3.0263E-14 +7.5609E-13i

很明显,1点、51点、76点的值都比较大,它附近的点值
都很小,可以认为是0,即在那些频率点上的信号幅度为0。
接着,我们来计算各点的幅度值。分别计算这三个点的模值,
结果如下:
1点: 512
51点:384
76点:192
按照公式,可以计算出直流分量为:512/N=512/256=2;
50Hz信号的幅度为:384/(N/2)=384/(256/2)=3;75Hz信号的
幅度为192/(N/2)=192/(256/2)=1.5。可见,从频谱分析出来
的幅度是正确的。
然后再来计算相位信息。直流信号没有相位可言,不用管
它。先计算50Hz信号的相位,atan2(-192, 332.55)=-0.5236,
结果是弧度,换算为角度就是180*(-0.5236)/pi=-30.0001。再
计算75Hz信号的相位,atan2(192, 3.4315E-12)=1.5708弧度,
换算成角度就是180*1.5708/pi=90.0002。可见,相位也是对的。
根据FFT结果以及上面的分析计算,我们就可以写出信号的表达
式了,它就是我们开始提供的信号。

总结:假设采样频率为Fs,采样点数为N,做FFT之后,某
一点n(n从1开始)表示的频率为:Fn=(n-1)*Fs/N;该点的模值
除以N/2就是对应该频率下的信号的幅度(对于直流信号是除以
N);该点的相位即是对应该频率下的信号的相位。相位的计算
可用函数atan2(b,a)计算。atan2(b,a)是求坐标为(a,b)点的角
度值,范围从-pi到pi。要精确到xHz,则需要采样长度为1/x秒
的信号,并做FFT。要提高频率分辨率,就需要增加采样点数,
这在一些实际的应用中是不现实的,需要在较短的时间内完成
分析。解决这个问题的方法有频率细分法,比较简单的方法是
采样比较短时间的信号,然后在后面补充一定数量的0,使其长度
达到需要的点数,再做FFT,这在一定程度上能够提高频率分辨力。
具体的频率细分法可参考相关文献。

[附录:本测试数据使用的matlab程序]
close all; %先关闭所有图片
Adc=2; %直流分量幅度
A1=3; %频率F1信号的幅度
A2=1.5; %频率F2信号的幅度
F1=50; %信号1频率(Hz)
F2=75; %信号2频率(Hz)
Fs=256; %采样频率(Hz)
P1=-30; %信号1相位(度)
P2=90; %信号相位(度)
N=256; %采样点数
t=[0:1/Fs:N/Fs]; %采样时刻

%信号
S=Adc+A1*cos(2*pi*F1*t+pi*P1/180)+A2*cos(2*pi*F2*t+pi*P2/180);
%显示原始信号
plot(S);
title('原始信号');

figure;
Y = fft(S,N); %做FFT变换
Ayy = (abs(Y)); %取模
plot(Ayy(1:N)); %显示原始的FFT模值结果
title('FFT 模值');

figure;
Ayy=Ayy/(N/2); %换算成实际的幅度
Ayy(1)=Ayy(1)/2;
F=([1:N]-1)*Fs/N; %换算成实际的频率值
plot(F(1:N/2),Ayy(1:N/2)); %显示换算后的FFT模值结果
title('幅度-频率曲线图');

figure;
Pyy=[1:N/2];
for i="1:N/2"
Pyy(i)=phase(Y(i)); %计算相位
Pyy(i)=Pyy(i)*180/pi; %换算为角度
end;
plot(F(1:N/2),Pyy(1:N/2)); %显示相位图
title('相位-频率曲线图');

看完这个你就明白谐波分析了。

⑹ 如何使用opencv实现金字塔光流lk跟踪算法

#include <stdio.h>
#include <windows.h>
#include "cv.h"
#include "cxcore.h"
#include "highgui.h"
#include <opencv2\opencv.hpp>
using namespace cv;

static const double pi = 3.14159265358979323846;
inline static double square(int a)
{
return a * a;
}
/*该函数目的:给img分配内存空间,并设定format,如位深以及channel数*/
inline static void allocateOnDemand(IplImage **img, CvSize size, int depth, int channels)
{
if (*img != NULL) return;
*img = cvCreateImage(size, depth, channels);
if (*img == NULL)
{
fprintf(stderr, "Error: Couldn't allocate image. Out of memory?\n");
exit(-1);
}
}
/*主函数,原程序是读取avi视频文件,然后处理,我简单改成从摄像头直接读取数据*/
int main(int argc, char *argv[])
{

//读取摄像头
VideoCapture cap(0);
//读取视频文件

//VideoCapture cap; cap.open("optical_flow_input.avi");
if (!cap.isOpened())
{
return -1;
}
Mat frame;

/*
bool stop = false;
while (!stop)
{
cap >> frame;
// cvtColor(frame, edges, CV_RGB2GRAY);
// GaussianBlur(edges, edges, Size(7, 7), 1.5, 1.5);
// Canny(edges, edges, 0, 30, 3);
// imshow("当前视频", edges);
imshow("当前视频", frame);
if (waitKey(30) >= 0)
stop = true;
}
*/

//CvCapture *input_video = cvCaptureFromFile( "optical_flow_input.avi" );
//cv::VideoCapture cap = *(cv::VideoCapture *) userdata;

//if (input_video == NULL)
// {
// fprintf(stderr, "Error: Can't open video device.\n");
// return -1;
// }

/*先读取一帧,以便得到帧的属性,如长、宽等*/
//cvQueryFrame(input_video);

/*读取帧的属性*/
CvSize frame_size;
frame_size.height = cap.get(CV_CAP_PROP_FRAME_HEIGHT);
frame_size.width = cap.get(CV_CAP_PROP_FRAME_WIDTH);

/*********************************************************/

/*用于把结果写到文件中去,非必要
int frameW = frame_size.height; // 744 for firewire cameras
int frameH = frame_size.width; // 480 for firewire cameras
VideoWriter writer("VideoTest.avi", -1, 25.0, cvSize(frameW, frameH), true);

/*开始光流法*/
//VideoWriter writer("VideoTest.avi", CV_FOURCC('D', 'I', 'V', 'X'), 25.0, Size(640, 480), true);

while (true)
{
static IplImage *frame = NULL, *frame1 = NULL, *frame1_1C = NULL,
*frame2_1C = NULL, *eig_image = NULL, *temp_image = NULL,
*pyramid1 = NULL, *pyramid2 = NULL;

Mat framet;
/*获取第一帧*/
// cap >> framet;
cap.read(framet);
Mat edges;
//黑白抽象滤镜模式
// cvtColor(framet, edges, CV_RGB2GRAY);
// GaussianBlur(edges, edges, Size(7, 7), 1.5, 1.5);
// Canny(edges, edges, 0, 30, 3);

//转换mat格式到lpiimage格式
frame = &IplImage(framet);
if (frame == NULL)
{
fprintf(stderr, "Error: Hmm. The end came sooner than we thought.\n");
return -1;
}

/*由于opencv的光流函数处理的是8位的灰度图,所以需要创建一个同样格式的
IplImage的对象*/
allocateOnDemand(&frame1_1C, frame_size, IPL_DEPTH_8U, 1);

/* 把摄像头图像格式转换成OpenCV惯常处理的图像格式*/
cvConvertImage(frame, frame1_1C, 0);

/* 我们需要把具有全部颜色信息的原帧保存,以备最后在屏幕上显示用*/
allocateOnDemand(&frame1, frame_size, IPL_DEPTH_8U, 3);
cvConvertImage(frame, frame1, 0);

/* 获取第二帧 */
//cap >> framet;
cap.read(framet);
// cvtColor(framet, edges, CV_RGB2GRAY);
// GaussianBlur(edges, edges, Size(7, 7), 1.5, 1.5);
// Canny(edges, edges, 0, 30, 3);
frame = &IplImage(framet);
if (frame == NULL)
{
fprintf(stderr, "Error: Hmm. The end came sooner than we thought.\n");
return -1;
}

/*原理同上*/
allocateOnDemand(&frame2_1C, frame_size, IPL_DEPTH_8U, 1);
cvConvertImage(frame, frame2_1C, 0);

/*********************************************************
开始shi-Tomasi算法,该算法主要用于feature selection,即一张图中哪些是我
们感兴趣需要跟踪的点(interest point)
input:
* "frame1_1C" 输入图像.
* "eig_image" and "temp_image" 只是给该算法提供可操作的内存区域.
* 第一个".01" 规定了特征值的最小质量,因为该算法要得到好的特征点,哪就
需要一个选择的阈值
* 第二个".01" 规定了像素之间最小的距离,用于减少运算复杂度,当然也一定
程度降低了跟踪精度
* "NULL" 意味着处理整张图片,当然你也可以指定一块区域
output:
* "frame1_features" 将会包含fram1的特征值
* "number_of_features" 将在该函数中自动填充上所找到特征值的真实数目,
该值<= 400
**********************************************************/

/*开始准备该算法需要的输入*/

/* 给eig_image,temp_image分配空间*/
allocateOnDemand(&eig_image, frame_size, IPL_DEPTH_32F, 1);
allocateOnDemand(&temp_image, frame_size, IPL_DEPTH_32F, 1);

/* 定义存放frame1特征值的数组,400只是定义一个上限 */
CvPoint2D32f frame1_features[400];
int number_of_features = 400;

/*开始跑shi-tomasi函数*/
cvGoodFeaturesToTrack(frame1_1C, eig_image, temp_image,
frame1_features, &number_of_features, .01, .01, NULL);

/**********************************************************
开始金字塔Lucas Kanade光流法,该算法主要用于feature tracking,即是算出
光流,并跟踪目标。
input:
* "frame1_1C" 输入图像,即8位灰色的第一帧
* "frame2_1C" 第二帧,我们要在其上找出第一帧我们发现的特征点在第二帧
的什么位置
* "pyramid1" and "pyramid2" 是提供给该算法可操作的内存区域,计算中间
数据
* "frame1_features" 由shi-tomasi算法得到的第一帧的特征点.
* "number_of_features" 第一帧特征点的数目
* "optical_flow_termination_criteria" 该算法中迭代终止的判别,这里是
epsilon<0.3,epsilon是两帧中对应特征窗口的光度之差的平方,这个以后的文
章会讲
* "0" 这个我不知道啥意思,反正改成1就出不来光流了,就用作者原话解释把
means disable enhancements. (For example, the second array isn't
pre-initialized with guesses.)
output:
* "frame2_features" 根据第一帧的特征点,在第二帧上所找到的对应点
* "optical_flow_window" lucas-kanade光流算法的运算窗口,具体lucas-kanade
会在下一篇详述
* "5" 指示最大的金字塔层数,0表示只有一层,那就是没用金字塔算法
* "optical_flow_found_feature" 用于指示在第二帧中是否找到对应特征值,
若找到,其值为非零
* "optical_flow_feature_error" 用于存放光流误差
**********************************************************/

/*开始为pyramid lucas kanade光流算法输入做准备*/
CvPoint2D32f frame2_features[400];

/* 该数组相应位置的值为非零,如果frame1中的特征值在frame2中找到 */
char optical_flow_found_feature[400];

/* 数组第i个元素表对应点光流误差*/
float optical_flow_feature_error[400];

/*lucas-kanade光流法运算窗口,这里取3*3的窗口,可以尝试下5*5,区别就是5*5
出现aperture problem的几率较小,3*3运算量小,对于feature selection即shi-tomasi算法来说足够了*/
CvSize optical_flow_window = cvSize(5, 5);
// CvSize optical_flow_window = cvSize(5, 5);
/* 终止规则,当完成20次迭代或者当epsilon<=0.3,迭代终止,可以尝试下别的值*/
CvTermCriteria optical_flow_termination_criteria= cvTermCriteria(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, .3);

/*分配工作区域*/
allocateOnDemand(&pyramid1, frame_size, IPL_DEPTH_8U, 1);
allocateOnDemand(&pyramid2, frame_size, IPL_DEPTH_8U, 1);

/*开始跑该算法*/
cvCalcOpticalFlowPyrLK(frame1_1C, frame2_1C, pyramid1, pyramid2,frame1_features, frame2_features, number_of_features,
optical_flow_window, 5, optical_flow_found_feature,optical_flow_feature_error, optical_flow_termination_criteria, 0);

/*画光流场,画图是依据两帧对应的特征值,
这个特征值就是图像上我们感兴趣的点,如边缘上的点P(x,y)*/
for (int i = 0; i< number_of_features; i++)
{
/* 如果没找到对应特征点 */
if (optical_flow_found_feature[i] == 0)
continue;
int line_thickness;
line_thickness = 1;

/* CV_RGB(red, green, blue) is the red, green, and blue components
* of the color you want, each out of 255.
*/
CvScalar line_color;
line_color = CV_RGB(255, 0, 0);

/*画箭头,因为帧间的运动很小,所以需要缩放,不然看不见箭头,缩放因子为3*/
CvPoint p, q;
p.x = (int)frame1_features[i].x;
p.y = (int)frame1_features[i].y;
q.x = (int)frame2_features[i].x;
q.y = (int)frame2_features[i].y;

double angle;
angle = atan2((double)p.y - q.y, (double)p.x - q.x);
double hypotenuse;
hypotenuse = sqrt(square(p.y - q.y) + square(p.x - q.x));

/*执行缩放*/
q.x = (int)(p.x - 5 * hypotenuse * cos(angle));
q.y = (int)(p.y - 5 * hypotenuse * sin(angle));

/*画箭头主线*/
/* "frame1"要在frame1上作画.
* "p" 线的开始点.
* "q" 线的终止点.
* "CV_AA" 反锯齿.
* "0" 没有小数位.
*/
cvLine(frame1, p, q, line_color, line_thickness, CV_AA, 0);

/* 画箭的头部*/
p.x = (int)(q.x + 9 * cos(angle + pi / 4));
p.y = (int)(q.y + 9 * sin(angle + pi / 4));
cvLine(frame1, p, q, line_color, line_thickness, CV_AA, 0);
p.x = (int)(q.x + 9 * cos(angle - pi / 4));
p.y = (int)(q.y + 9 * sin(angle - pi / 4));
cvLine(frame1, p, q, line_color, line_thickness, CV_AA, 0);
}
/*显示图像*/

/*创建一个名为optical flow的窗口,大小自动改变*/
cvNamedWindow("Optical Flow", CV_WINDOW_NORMAL);
cvFlip(frame1, NULL, 2);
cvShowImage("Optical Flow", frame1);

/*延时,要不放不了*/
cvWaitKey(33);

/*写入到文件中去*/

// cv::Mat m = cv::cvarrToMat(frame1);//转换lpimgae到mat格式
// writer << m;//opencv3.0 version writer

}
cap.release();
cvWaitKey(33);
system("pause");
}

⑺ 在Flash AS3导弹跟踪算法里的,转换为360度以内的正值不是很理解。

c2是转换后的360度内的正值,则c2=(360-c1)%360-----此句有误,转换角度的方厅铅法应该是:
c2=c1%360
................................应该是这样吧?愿共饥御同商讨,扮肢好携手进步...........张志晨..............

⑻ C语言迭代算法初值问题

C语言没有默认迭代陵棚初漏运值。
会自动初始化的有:
全局变量
静态变量
在定义这两种变量时,如果未赋初值尺搜则,则系统会将其值置为0.

你这里注释部分有没有执行的结果都一样,可能是刚好你输入的数据符合而已。
你再多试几组数据看看。

⑼ 求这个碰撞算法的解释

肯定是一个公球和一个母球,呵呵

⑽ 求大神详细讲解c/c++/pascal凸包算法

实这个算法是在一年前得某场比赛中临时抱佛脚学的,今天重新的来温习了一遍
如何来理解凸包?一组平面上的点,求一个包含所有点的最小的凸多边形,这就是凸包问题了。这可以形象地想成这样:在地上放置一些不可移动的木桩,用一根绳子把他们尽量紧地圈起来,这就是凸包了,网络中的这张图很生动+活泼+形象,所以你懂的

好说完这个我们首先要来了解下极角排序和左转判定
极角排序:就是选取一个最左的点,按y最小,其次x最小来定义,接下来所有的点针对该点的射线,
按角度由小到大,若相同按距离由近到远来排序
左转判定:这个和叉积有关,对于向量p1(x1,y1),p2(x2,y2)如果x1*y2-x2*y1>0,则从p1到p2左转

我学的是Graham算法,那么接下来来介绍下该算法
(1)选取最下左的点P0
(2)计算出每个点相对于P0的角度和距离(利用这个来排序)排序
(3)设点数为n,将p[n-1]和p[0]入栈,判断点集合是否为一条直线(初始k=2表示当前凸包的大小)
(4)i从1到n-1遍历,对于p[k-1],p[k-2],p[i]若满足左转,将p[i]压入栈
否则i--,k--
(5)k--,返回k表示凸包的点数

下面是我写的模板

int Polygon::Graham(Polygon &con){//别用自己做对象
int t=0,i;
Point tmp;
//先y最小再x最小
for(i=1;i<n;i++)if(p[i]<p[t])t=i;
swap(p[t],p[0]);
for(i=0;i<n;i++){
tmp=p[i]-p[0];
p[i].dis=tmp.Len2();
p[i].angle=atan2(tmp.y,tmp.x);
}
sort(p,p+n,_cmp);
//for(int i=0;i<n;i++)p[i].out();
//cout<<"***"<<endl;
int k=0;
con.p[k++]=p[n-1];
con.p[k++]=p[0];
if(Sig(p[1].angle-p[n-1].angle)==0)con.p[k++]=p[n-1];//凸包为一线段
else{
for(i=1;i<n;i++){
//con[k-1].out();
//con[k-2].out();
//p[i].out();
if(Sig(Cross(con.p[k-1],con.p[k-2],p[i]))>0)con.p[k++]=p[i];
else {i--;k--;}
//cout<<"---"<<endl;
//for(int j=0;j<k;j++)con[j].out();
//system("pause");
}
}
return con.n=--k;
}
/*
9
1 4
3 6
5 7
2 2
3 3
5 4
8 3
9 6
7 1
*/

摘自http://blog.csdn.net/foreverlin1204/article/details/6221986

阅读全文

与atan2算法相关的资料

热点内容
传奇引擎修改在线时间命令 浏览:107
php取域名中间 浏览:896
cad命令栏太小 浏览:830
php开发环境搭建eclipse 浏览:480
qt文件夹名称大全 浏览:212
金山云服务器架构 浏览:230
安卓系统笔记本怎么切换系统 浏览:618
u盘加密快2个小时还没有搞完 浏览:93
小米有品商家版app叫什么 浏览:94
行命令调用 浏览:435
菜鸟裹裹员用什么app 浏览:273
穷查理宝典pdf下载 浏览:514
csgo您已被禁用此服务器怎么办 浏览:398
打开加密软件的方法 浏览:156
云存储服务器可靠吗 浏览:967
2核1g的云服务器能带动游戏嘛 浏览:898
逆命20解压码 浏览:146
徐州办犬证需要下载什么app 浏览:1002
百保盾是什么样的app 浏览:699
文件和文件夹的命名规格 浏览:798