Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 给定边长的不等边四面体的面角求法_C_Computational Geometry_Tetrahedra - Fatal编程技术网

C 给定边长的不等边四面体的面角求法

C 给定边长的不等边四面体的面角求法,c,computational-geometry,tetrahedra,C,Computational Geometry,Tetrahedra,我正在用C写一个程序,在给定所有边的长度的情况下,确定一个四面体的顶点。四面体具有等边底面和不等边。为了完成这个公式,我需要一种得到面和等边基之间的角度的方法。我知道其中一个面高度的高度,一旦我可以得到面和底部之间的角度,我就可以通过这个角度旋转高度,得到顶点的位置 我有0的想法,从哪里开始计算角度的公式(见下面的θ),以及如何将其转换为C 我知道黄色部分的长度,我正试图找到蓝色部分的角度B 以下是我目前的代码: #include <math.h> #include <std

我正在用C写一个程序,在给定所有边的长度的情况下,确定一个四面体的顶点。四面体具有等边底面和不等边。为了完成这个公式,我需要一种得到面和等边基之间的角度的方法。我知道其中一个面高度的高度,一旦我可以得到面和底部之间的角度,我就可以通过这个角度旋转高度,得到顶点的位置

我有0的想法,从哪里开始计算角度的公式(见下面的θ),以及如何将其转换为C

我知道黄色部分的长度,我正试图找到蓝色部分的角度B

以下是我目前的代码:

#include <math.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>

typedef struct {
  float x;
  float y;
  float z;
} Point;

typedef struct {
  float edgeA, edgeB, edgeC;
  float legA, legB, legC;
  Point vertexBaseA, vertexBaseB, vertexBaseC;
  Point apex;
} scaleneTetrahedron;

Point p(float x,float y) {
    Point pt; pt.x = x; pt.y = y; pt.z =0;return pt;
}

Point pZ(float x, float y, float z) {
      Point pt; pt.x = x; pt.y = y;pt.z =z; return pt;
}

void printPoint(char *identifier, Point p){
  printf("(%s: %f, %f, %f)\n",identifier, p.x,p.y,p.z);
}

void printFloat(float n) {
  printf("%f",n);
}

scaleneTetrahedron sT_Hedron(float lengthsEdges[3],float lengthsLegs[3],Point vertexBases[3]) {
  scaleneTetrahedron h;
  h.edgeA = lengthsEdges[0], h.edgeB = lengthsEdges[2], h.edgeC = lengthsEdges[2];
  h.legA = lengthsLegs[0], h.legB = lengthsLegs[1],h.legC = lengthsLegs[2];
  h.vertexBaseA = vertexBases[0], h.vertexBaseB = vertexBases[1], h.vertexBaseC = vertexBases[2];
  return h;
}

#define rt(n) (sqrt(n))
float SQUARE(float n) {return n*n;}
float PERP(float slope) { return 1/slope * -1;}
float Rad_To_Deg(float angle) {return angle*57.29577951f;}

#define ANGLE_FOR(rangX,rangY)      ( Rad_To_Deg(atan2(rangX,rangY))     )

float DISTANCE(Point v1, Point v2){
  return sqrtf(SQUARE(v1.x-v2.x) + SQUARE(v1.y-v2.y));

}

float WIDTH(float leg1,float leg2,float base){
  float ret = ((SQUARE(leg1) - SQUARE(leg2)) + SQUARE(base)) / (2 * base);
  printf("Ret is:%f\n",ret);
  return ret;
}

float HEIGHT(float width,float leg1){
  float ret = sqrtf(SQUARE(leg1) - SQUARE(width));
  return ret;
}

float slopeFor(Point A, Point B) {
  return (B.y-A.y) / (B.x - A.x);
}

float yInterceptFor(float slope, Point A) {
  return (A.y - (slope * A.x));
}

float map(float range1_A, float range1_B, float range2_A, float range2_B, float value) {
    float  inMin = range1_A;
    float  inMax = range1_B;

    float  outMin = range2_A;
    float  outMax = range2_B;

    float input = value;
    float output = outMin + (outMax - outMin) * (input - inMin) / (inMax - inMin);

    return output;
}

Point XYAltitude(float leg1, float leg2, float base) {

  float width = WIDTH(leg1,leg2,base); 
  float height = HEIGHT(width,leg1);
  return p(width, height);
}

Point APEX_OF(scaleneTetrahedron shape) {
  Point altitude1 = XYAltitude(shape.legA,shape.legB, shape.edgeA);//Getting the x position of the altitude of faceA and the height of the altitude. 
  printPoint("Altitude face:",altitude1);
  float 
  x = altitude1.x,
  baseX1 = x,
  baseX2 = x,
  baseY1 = 0,
  baseY2 = 10
  ; 

  float slopeBase = slopeFor(shape.vertexBaseC, shape.vertexBaseB), yIntBase = yInterceptFor(slopeBase,shape.vertexBaseB);
  printf("slope is:%f ,yint is:%f, point of intersection:%f\n",slopeBase,yIntBase, (slopeBase * x)+yIntBase);
  Point intersectionBase = p(x, (slopeBase * x) + yIntBase);


  printPoint("IntersectionBase:",intersectionBase);

  float zIntersectionBase = (slopeBase * x) + yIntBase;//it is "y" because we are switching from a topdown to a side view
  float zHypotenuse = (shape.edgeC* intersectionBase.y)/shape.vertexBaseC.y; //THIS IS THROWING OFF THE MEASUREMENT: sqrtf(SQUARE(zIntersectionBase) + SQUARE(altitude1.y));
  Point zAltitude   = XYAltitude(altitude1.y,zHypotenuse,zIntersectionBase);
  float theta       = Rad_To_Deg(atan2(zAltitude.x,zAltitude.y));//Here's where I am having trouble.
  float y = Rad_To_Deg(sin(theta)) * altitude1.x;
  float z = Rad_To_Deg(cos(theta)) * altitude1.x;
  printFloat(theta);
  Point rtd;
  rtd.x = x;
  rtd.z = y; //Only now did I learn that z and y are swapped in 3D. But, this is no problem due to abstraction. 
  rtd.y = z;

  return rtd;
}

int main(int argc, const char *argv[]){
  // srand(time(NULL));   

  Point vertexA  = p(0,0); 
  Point vertexB  = p(3,0.f);
  Point vertexC  = p(1.5,2.6); 
  Point apex =   pZ(1.5,0.87,2.45);

  float baseA = DISTANCE(vertexA,vertexB);
  float baseB = DISTANCE(vertexB,vertexC);
  float baseC = DISTANCE(vertexC,vertexA);
  float legA  = DISTANCE(vertexA,apex);
  float legB  = DISTANCE(vertexB,apex);
  float legC  = DISTANCE(vertexC,apex);

  scaleneTetrahedron toSend;
  toSend.edgeA = baseA;
  toSend.edgeB = baseB;
  toSend.edgeC = baseC;

  toSend.legA = legA; 
  toSend.legB = legB;
  toSend.legC = legC;

  toSend.vertexBaseA = vertexA;
  toSend.vertexBaseB = vertexB;
  toSend.vertexBaseC = vertexC;
  printPoint("APEX:",APEX_OF(toSend));

  return 0;

}
#包括
#包括
#包括
#包括
类型定义结构{
浮动x;
浮动y;
浮动z;
}点;
类型定义结构{
浮动edgeA、edgeB、edgeC;
浮动法A、法B、法C;
顶点A、顶点B、顶点C;
尖端;
}鳞片四面体;
点p(浮动x,浮动y){
点pt;pt.x=x;pt.y=y;pt.z=0;返回pt;
}
点pZ(浮动x、浮动y、浮动z){
点pt;pt.x=x;pt.y=y;pt.z=z;返回pt;
}
无效打印点(字符*标识符,点p){
printf((%s:%f,%f,%f)\n“,标识符,p.x,p.y,p.z);
}
无效打印浮点(浮点n){
printf(“%f”,n);
}
scaleneTetrahedron sT_Hedron(浮动长度sedges[3],浮动长度sedges[3],点顶点基底[3]){
鳞片四面体h;
h、 edgeA=长莎草[0],h.edgeB=长莎草[2],h.edgeC=长莎草[2];
h、 legA=长度[0],h.legB=长度[1],h.legC=长度[2];
h、 vertexBaseA=VertexBase[0],h.vertexBaseB=VertexBase[1],h.vertexBaseC=VertexBase[2];
返回h;
}
#定义rt(n)(sqrt(n))
浮点数平方(float n){返回n*n;}
浮动PERP(浮动斜率){return 1/slope*-1;}
浮动半径到度(浮动角度){返回角度*57.29577951f;}
#定义(rangX,rangY)的角度(Rad_到_Deg(atan2(rangX,rangY)))
浮动距离(点v1,点v2){
返回sqrtf(平方(v1.x-v2.x)+平方(v1.y-v2.y));
}
浮动宽度(浮动段1、浮动段2、浮动底座){
浮点数=((平方(leg1)-平方(leg2))+平方(基数))/(2*基数);
printf(“Ret是:%f\n”,Ret);
返回ret;
}
浮动高度(浮动宽度、浮动段1){
浮动ret=sqrtf(正方形(leg1)-正方形(宽度));
返回ret;
}
浮动坡度F(点A、点B){
回报率(B.y-A.y)/(B.x-A.x);
}
浮标yInterceptFor(浮标坡度,点A){
回报率(A.y-(斜率*A.x));
}
浮动贴图(浮动范围1_A、浮动范围1_B、浮动范围2_A、浮动范围2_B、浮动值){
最小浮动=范围1_A;
浮动inMax=范围1_B;
浮动输出最小值=范围2_A;
浮点输出最大值=范围2_B;
浮点输入=数值;
浮点输出=输出最小值+(输出最大值-输出最小值)*(输入-输入最小值)/(输入最大值-输入最小值);
返回输出;
}
点XY高度(浮动梯段1、浮动梯段2、浮动基座){
浮动宽度=宽度(leg1、leg2、底座);
浮动高度=高度(宽度,leg1);
返回p(宽度、高度);
}
点顶点_(四面体形状){
Point altitude1=XY高度(shape.legA,shape.legB,shape.edgeA);//获取面A高度的x位置和高度的高度。
打印点(“高度面:”,高度1);
浮动
x=高度1.x,
baseX1=x,
baseX2=x,
基数1=0,
基准2=10
; 
float slopeBase=slopeFor(shape.vertexBaseC,shape.vertexBaseB),yIntBase=yInterceptFor(slopeBase,shape.vertexBaseB);
printf(“坡度为:%f,yint为:%f,交点为:%f\n”,坡度基,yIntBase,(坡度基*x)+yIntBase);
点相交基=p(x,(斜率基*x)+yIntBase);
打印点(“IntersectionBase:”,IntersectionBase);
float zIntersectionBase=(slopeBase*x)+yIntBase;//它是“y”,因为我们正在从自顶向下切换到侧视图
float z斜边=(shape.edgeC*intersectionBase.y)/shape.vertexBaseC.y;//这是在放弃测量值:sqrtf(SQUARE(zIntersectionBase)+SQUARE(altitude1.y));
Zalitute点=XY高度(高度1.y,斜边,基准面);
float theta=Rad_To_Deg(atan2(zalitude.x,zalitude.y));//这里是我遇到麻烦的地方。
浮动y=Rad_至_Deg(sin(θ))*高度1.x;
浮动z=弧度到度(cos(θ))*高度1.x;
打印浮点(θ);
点rtd;
rtd.x=x;
rtd.z=y;//直到现在我才知道z和y在3D中是交换的。但是,由于抽象,这并没有问题。
rtd.y=z;
返回rtd;
}
int main(int argc,const char*argv[]{
//srand(时间(空));
顶点=p(0,0);
顶点b=p(3,0.f);
点vertexC=p(1.5,2.6);
顶点=pZ(1.5,0.87,2.45);
浮动基准a=距离(顶点a、顶点b);
浮动基准B=距离(顶点B、顶点C);
float baseC=距离(vertexC,vertexA);
浮动legA=距离(顶点、顶点);
float legB=距离(顶点b,顶点);
float legC=距离(顶点顶点顶点);
鳞片四面体;
toSend.edgeA=baseA;
toSend.edgeB=baseB;
toSend.edgeC=baseC;
toSend.legA=legA;
toSend.legB=legB;
toSend.legC=legC;
toSend.vertexBaseA=vertexA;
toSend.vertexBaseB=vertexB;
toSend.vertexBaseC=vertexC;
打印点(“顶点:,顶点(toSend));
返回0;
}

根据编辑的问题回答:

这个答案是基于你在照片上引用的内容。 您用蓝色标记的角度是线段AH(参考您的图片)和平面之间的角度(我看不到您的坐标系,所以我假设这是XZ平面)

如果这个答案还不够,因为它对你当前的问题是正确的,你最好问一个新问题


旧答案:

你不准确:

其中一个面的高度

两者都可能表示四面体的高度,或从顶部顶点开始将面切成一半的线的长度

如果你知道:

  • 四面体的高度(段AH)//I use Point instead of Vector3, semantically no difference here //but it is wrong conceptually. Point getUpVector(){ Point Up; Up.y = 1.0f; Up.x = Up.z = 0.0f; return Up; } Point getOrigin(){ Point O; Up.x=Up.y=Up.z=0.0f; return O; } Point getDirection(Point P1, Point P2){ Point P3; P3.x = P1.x-P2.x; P3.y = P1.y-P2.y; P3.z = P1.z-P2.z; return P3; } double dotProduct(Point A, Point B){ return A.x*B.x + A.y*B.y + A.z*B.z; } double distanceOfPoints(Point P1, Point P2){ double x = P1.x - P2.x; double y = P1.y - P2.y; double z = P1.z - P2.z; return sqrt(x*x + y*y + z*z); } Point normalize(Point A){ double L = distanceOfPoints(A,GetOrigin()); A.x/= L; A.y/=L; A.z/=L; return A; } //the function you have to call requires to know coordinates of points H and A // it is impossible to compute that angle using only distances, because distances // are indpendent of rotation while that angle requires to know the rotation..!! double angleOnThePlane(Point H, Point A){ Point D = getDirection(H,A); P = normalize(D); return asin( dotProduct(P,getUpVector())/ (distanceOfPoints(getUpVector,getOrigin()) + distanceOfPoints(P,getOrigin()) ) ); }
    //since the base is equilateral you can compute CH with:
    double computeCH(double CB){
        return CB*sqrt(3.0)/3.0
    }
    
    //the missing edge is then CA, you need pitagora this time:
    double computeCA(double CB, double AH){
        double CH = computeCH(CB);
        return sqrt(AH*AH+CH*CH);
    }
    
    //just compute the height of the triangle ABC
    double computeHeight(double CB, double AB){
        return sqrt(AB*AB - 0.25*CB*CB);
    }
    
    //then angle is trivial
    double computeAngle(double Height, double AB){
        return 2.0*acos(Height/AB);
    }
    
    double computeAB(double Height, double CB){
        return sqrt( CB*CB*0.25 + Height*Height);
    }
    
    //just need to compute the angle now
    double computeAngle(double Height, double AB){
        return 2.0*acos(Height/AB);
    }
    
    /**
    
                  A
                / |\
              /   |  \
            /     |    \
          /       |      \
        /         |    ___ \
      / _____---  | H      /
      B ---___            /
              ---___     /
            H'      ----C
    */