Java 计算两条线是否对称
我正在开发一个应用程序来检查绘图是否对称。所有用户行都存储在一个由点列表组成的ArrayList中,该列表也是结构化的:Java 计算两条线是否对称,java,android,math,geometry,symmetric,Java,Android,Math,Geometry,Symmetric,我正在开发一个应用程序来检查绘图是否对称。所有用户行都存储在一个由点列表组成的ArrayList中,该列表也是结构化的: private ArrayList<ArrayList<Pair<Float,Float>>> segments = new ArrayList<>(); 私有数组列表 黑色形状是背景的一部分,当我必须检查对称性时,我不需要考虑它。我只需要它的中心(我存储为一个坐标),因为我需要考虑检查它的对称性。由于绘制是由儿童,我也需要考
private ArrayList<ArrayList<Pair<Float,Float>>> segments = new ArrayList<>();
私有数组列表
黑色形状是背景的一部分,当我必须检查对称性时,我不需要考虑它。我只需要它的中心(我存储为一个坐标),因为我需要考虑检查它的对称性。由于绘制是由儿童,我也需要考虑一点灵活性,因为线永远不会是完全对称的。我实施了一种方法,将每个部分划分为10个部分,然后检查每个部分的坐标是否有类似的增加/减少:
private boolean checkShape (int z, ArrayList<Pair<Float,Float>> points) {
ArrayList<Pair<Float,Float>> copia = segments.get(z);
int nGroupsFirstShape = (segments.get(z).size()*10)/100;
int nValuesFirstShape[] = new int[10];
for (int j=0, j2=0; j<10; j++, j2+=nGroupsFirstShape) {
int sumValues=0;
sumValues+=copia.get(j2).first-copia.get(j2+nGroupsFirstShape-1).first;
sumValues+=copia.get(j2).second-copia.get(j2+nGroupsFirstShape-1).second;
nValuesFirstShape[j] = sumValues;
}
ArrayList<Pair<Float,Float>> copia2 = points;
int nGroupSecondShape = (copia2.size()*10)/100;
int nValuesSecondShape[] = new int[10];
for (int j=0, j2=0; j<10; j++, j2+=nGroupSecondShape) {
int sumValues=0;
sumValues+=copia2.get(j2).first-copia2.get(j2+nGroupSecondShape-1).first;
sumValues+=copia2.get(j2).second-copia2.get(j2+nGroupSecondShape-1).second;
nValuesSecondShape[j] = sumValues;
}
int differences[] = new int[10];
int numberOf = 0;
for (int index=0; index<10; index++) {
differences[index] = nValuesFirstShape[index] - nValuesSecondShape[index];
if (differences[index]<0) differences[index] = -differences[index];
if (differences[index]<nGroupsFirstShape*2.5) numberOf++;
}
if (numberOf>=6) return true; else return false;
}
private boolean checkShape(int z,ArrayList点){
ArrayList copia=segments.get(z);
int nGroupsFirstShape=(segments.get(z).size()*10)/100;
int nValuesFirstShape[]=新int[10];
对于(int j=0,j2=0;j我已经多年没有编写Java代码了,现在也没有那么多时间了。因此,这个答案不包含运行Java代码,只包含想法和一些伪代码。我希望这对您有所帮助
其中一个给出了两个曲线1
和曲线2
,以及一个反射中心c
。
您需要计算一条曲线是否是给定阈值内另一条曲线的点反射maxDist
计算该值的函数可能如下所示:
函数检查对称性(曲线曲线1、曲线2、向量c、浮点最大距离){
//反射一条曲线
曲线curve2refl=反射(曲线2,c);
//计算曲线距离
浮动d=距离(曲线1,曲线2);
//检查距离是否低于阈值
返回d
(为了更好的可读性,我引入了一些类,而不是您的ArrayList of ArrayList of Pairs of…。我建议您在代码中也这样做。)
点反射
点反射的公式可以在上找到:具有反射中心c
的点p
的反射为:2*c-p
要反射曲线,必须反射其所有顶点
距离曲线-曲线
当两条红色曲线(几乎)对称时,在其中一条反射后,它们应该(几乎)相同,即距离(几乎)为零。但两条曲线的距离是多少
在数学集合论中存在一个。这对于非数学家来说有点复杂。但它给出了定义曲线距离的想法:一条曲线的顶点到另一条曲线的最大距离:
函数距离(曲线1、曲线2){
d=0;
对于(向量p:曲线1.顶点){
d=最大值(d,距离(曲线2,p));
}
对于(向量p:曲线2.顶点){
d=最大值(d,距离(曲线1,p));
}
返回d;
}
距离点-曲线
因此,我们确实减少了计算点到曲线的距离的问题。这是点到任意曲线段的最小距离:
函数距离(曲线、向量p){
d=距离(p,curve.vertices.get(0));
对于(int i=1,n=curve.vertices.size();i
距离点-线段
对于一个点到一个段的距离,你会发现很多关于stackoverflow的问题都有很好的答案,例如…我认为这是一个很好的数学算法:
步骤1:
将每条线分成N部分。(图中的正方形)
线上的点的数量可能会有所不同,但零件的数量现在将是相同的
例如,一条线是100个点,将其分成10个部分,每个部分10个点。
第二个90分,它将得到9分中的10分
计算每个零件的中点。
步骤2:
在两条线的每个中点之间,我们找到了中间。(图中的黑点)
步骤3:
我们建立一条与这些点的偏差最小的线。(图中的红线)
步骤4:
估计中点与直线的偏差。通过平均偏差和最大偏差,可以测量直线的相似程度
祝你好运你在寻找什么样的对称?你提到了一个中心。那么这是关于一个已知中心的点反射吗?你的例子有几条曲线,但你的数据结构只存储了两个点,这意味着你只有直线。@NicoSchertler是的,我在寻找关于黑色中心的点反射ape@Code-学徒曲线逐点存储到ArrayList@Babbara所以ArrayList基本上代表了很多小线段来组成曲线?