- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在研究将椭圆划分为大小相等的线段的问题。已提出这个问题,但答案建议进行数值积分,以便我可以尝试。此代码使扇区短路,因此集成本身不应覆盖超过 90 度。积分本身是通过计算中间三角形的面积来完成的。下面是我尝试过的代码,但在某些情况下它的扫描角度超过 90 度。
public class EllipseModel {
protected double r_x;
protected double r_y;
private double a,a2;
private double b,b2;
boolean flip;
double area;
double sector_area;
double radstep;
double rot;
int xp,yp;
double deviation;
public EllipseModel(double r_x, double r_y, double deviation)
{
this.r_x = r_x;
this.r_y = r_y;
this.deviation = deviation;
if (r_x < r_y) {
flip = true;
a = r_y;
b = r_x;
xp = 1;
yp = 0;
rot = Math.PI/2d;
} else {
flip = false;
xp = 0;
yp = 1;
a = r_x;
b = r_y;
rot = 0d;
}
a2 = a * a;
b2 = b * b;
area = Math.PI * r_x * r_y;
sector_area = area / 4d;
radstep = (2d * deviation) / a;
}
public double getArea() {
return area;
}
public double[] getSweep(double sweep_area)
{
System.out.println(String.format("getSweep(%f) a = %f b = %f deviation = %f",sweep_area,a,b,deviation));
double[] ret = new double[2];
double[] next = new double[2];
double t_base, t_height, swept,x_mid,y_mid;
double t_area;
sweep_area = sweep_area % area;
if (sweep_area < 0d) {
sweep_area = area + sweep_area;
}
if (sweep_area == 0d) {
ret[0] = r_x;
ret[1] = 0d;
return ret;
}
double sector = Math.floor(sweep_area/sector_area);
double theta = Math.PI * sector/2d;
double theta_last = theta;
System.out.println(String.format("- Theta start = %f",Math.toDegrees(theta)));
ret[xp] = a * Math.cos(theta + rot);
ret[yp] = (1 + (((theta / Math.PI) % 2d) * -2d)) * Math.sqrt((1 - ( (ret[xp] * ret[xp])/a2)) * b2);
next[0] = ret[0];
next[1] = ret[1];
swept = sector * sector_area;
System.out.println(String.format("- Sweeping for %f sector_area=%f",sweep_area-swept,sector_area));
int c = 0;
while(swept < sweep_area) {
c++;
ret[0] = next[0];
ret[1] = next[1];
theta_last = theta;
theta += radstep;
// calculate next point
next[xp] = a * Math.cos(theta + rot);
next[yp] = (1 + (((theta / Math.PI) % 2d) * -2d)) * // selects +/- sqrt
Math.sqrt((1 - ( (ret[xp] * ret[xp])/a2)) * b2);
// calculate midpoint
x_mid = (ret[xp] + next[xp]) / 2d;
y_mid = (ret[yp] + next[yp]) / 2d;
// calculate triangle metrics
t_base = Math.sqrt( ( (ret[0] - next[0]) * (ret[0] - next[0]) ) + ( (ret[1] - next[1]) * (ret[1] - next[1])));
t_height = Math.sqrt((x_mid * x_mid) + (y_mid * y_mid));
// add triangle area to swept
t_area = 0.5d * t_base * t_height;
swept += t_area;
}
System.out.println(String.format("- Theta end = %f (%d)",Math.toDegrees(theta_last),c));
return ret;
}
}
在输出中,我看到以下情况,它扫过 116 度。
getSweep(40840.704497) a = 325.000000 b = 200.000000 deviation = 0.166667
- Theta start = 0.000000
- Sweeping for 40840.704497 sector_area=51050.880621
- Theta end = 116.354506 (1981)
有没有办法修复积分公式以创建一个返回扫过给定区域的椭圆上的点的函数?使用此代码的应用程序将总面积除以所需的段数,然后使用此代码确定每个段开始和结束的角度。不幸的是,它没有按预期工作。
* 编辑 *我相信上述集成失败了,因为底数和高度公式不正确。
最佳答案
无需使用椭圆参数方程进行转换...
x=x0+rx*cos(a)
y=y0+ry*sin(a)
其中 a = < 0 , 2.0*M_PI >
此代码会将椭圆划分为大小均匀的 block :
double a,da,x,y,x0=0,y0=0,rx=50,ry=20; // ellipse x0,y0,rx,ry
int i,N=32; // divided to N = segments
da=2.0*M_PI/double(N);
for (a=0.0,i=0;i<N;i++,a+=da)
{
x=x0+(rx*cos(a));
y=y0+(ry*sin(a));
// draw_line(x0,y0,x,y);
}
这就是 N=5 的情况
[编辑1]
从你的评论中我不明白你现在到底想要实现什么
0.但首先需要一些全局或成员的东西
double x0,y0,rx,ry; // ellipse parameters
// [Edit2] sorry forgot to add these constants but they are I thin straight forward
const double pi=M_PI;
const double pi2=2.0*M_PI;
// [/Edit2]
double atanxy(double x,double y) // atan2 return < 0 , 2.0*M_PI >
{
int sx,sy;
double a;
const double _zero=1.0e-30;
sx=0; if (x<-_zero) sx=-1; if (x>+_zero) sx=+1;
sy=0; if (y<-_zero) sy=-1; if (y>+_zero) sy=+1;
if ((sy==0)&&(sx==0)) return 0;
if ((sx==0)&&(sy> 0)) return 0.5*pi;
if ((sx==0)&&(sy< 0)) return 1.5*pi;
if ((sy==0)&&(sx> 0)) return 0;
if ((sy==0)&&(sx< 0)) return pi;
a=y/x; if (a<0) a=-a;
a=atan(a);
if ((x>0)&&(y>0)) a=a;
if ((x<0)&&(y>0)) a=pi-a;
if ((x<0)&&(y<0)) a=pi+a;
if ((x>0)&&(y<0)) a=pi2-a;
return a;
}
1.点在线段内吗?
bool is_pnt_in_segment(double x,double y,int segment,int segments)
{
double a;
a=atanxy(x-x0,y-y0); // get sweep angle
a/=2.0*M_PI; // convert angle to a = <0,1>
if (a>=1.0) a=0.0; // handle extreme case where a was = 2 Pi
a*=segments; // convert to segment index a = <0,segments)
a-=double(segment );
// return floor(a); // this is how to change this function to return points segment id
// of course header should be slightly different: int get_pnt_segment_id(double x,double y,int segments)
if (a< 0.0) return false; // is lower then segment
if (a>=1.0) return false; // is higher then segment
return true;
}
2.获取线段区域的边缘点
void get_edge_pnt(double &x,double &y,int segment,int segments)
{
double a;
a=2.0*M_PI/double(segments);
a*=double(segment); // this is segments start edge point
//a*=double(segment+1); // this is segments end edge point
x=x0+(rx*cos(a));
y=y0+(ry*sin(a));
}
展位:
关于java - 如何找到椭圆上扫过给定区域的点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21277355/
例如,我有一个父类Author: class Author { String name static hasMany = [ fiction: Book,
代码如下: dojo.query(subNav.navClass).forEach(function(node, index, arr){ if(dojo.style(node, 'd
我有一个带有 Id 和姓名的学生表和一个带有 Id 和 friend Id 的 Friends 表。我想加入这两个表并找到学生的 friend 。 例如,Ashley 的 friend 是 Saman
我通过互联网浏览,但仍未找到问题的答案。应该很容易: class Parent { String name Child child } 当我有一个 child 对象时,如何获得它的 paren
我正在尝试创建一个以 Firebase 作为我的后端的社交应用。现在我正面临如何(在哪里?)找到 friend 功能的问题。 我有每个用户的邮件地址。 我可以访问用户的电话也预订。 在传统的后端中,我
我主要想澄清以下几点: 1。有人告诉我,在 iOS 5 及以下版本中,如果您使用 Game Center 设置多人游戏,则“查找 Facebook 好友”(如与好友争夺战)的功能不是内置的,因此您需要
关于redis docker镜像ENTRYPOINT脚本 docker-entrypoint.sh : #!/bin/sh set -e # first arg is `-f` or `--some-
我是一名优秀的程序员,十分优秀!