private static Matrix Rotation(xyz Point, xyz direction, double Angle) { direction = direction.normalized(); Matrix result = new Matrix(); double sin_a = System.Math.Sin(Angle); double cos_a = System.Math.Cos(Angle); result.a00 = (float)(direction.x * direction.x + (1 - direction.x * direction.x) * cos_a); result.a10 = (float)(direction.x * direction.y * (1 - cos_a) + direction.z * sin_a); result.a20 = (float)(direction.x * direction.z * (1 - cos_a) - direction.y * sin_a); result.a01 = (float)(direction.x * direction.y * (1 - cos_a) - direction.z * sin_a); result.a11 = (float)(direction.y * direction.y + (1 - direction.y * direction.y) * cos_a); result.a21 = (float)(direction.y * direction.z * (1 - cos_a) + direction.x * sin_a); result.a02 = (float)(direction.x * direction.z * (1 - cos_a) + direction.y * sin_a); result.a12 = (float)(direction.y * direction.z * (1 - cos_a) - direction.x * sin_a); result.a22 = (float)(direction.z * direction.z + (1 - direction.z * direction.z) * cos_a); result.a03 = (float)(Point.x - (result.a00 * Point.x + result.a01 * Point.y + result.a02 * Point.z)); result.a13 = (float)(Point.y - (result.a10 * Point.x + result.a11 * Point.y + result.a12 * Point.z)); result.a23 = (float)(Point.z - (result.a20 * Point.x + result.a21 * Point.y + result.a22 * Point.z)); result.a33 = 1; return(result); }
//public override void Compile(OpenGlDevice Device) //{ // bool Inverted = false; // base.Compile(Device); // if (Inverted) BoundedCurves.Invert(); //} /// <summary> /// is a constructor, which has thre points of the plane. /// </summary> /// <param name="A">the first point.</param> /// <param name="B">the second point.</param> /// <param name="C">the third point.</param> public PlaneSurface(xyz A, xyz B, xyz C) { xyz BA = B - A; xyz CA = C - A; xyz BaseZ = BA & CA; BaseZ = BaseZ.normalized(); if (BaseZ.length() < 0.000001) { Base BB = Base.UnitBase; BB.BaseO = A; Base = BB; return; } xyz BaseX = (CA & BaseZ).normalized(); xyz BaseY = BaseZ & BaseX; Base __Base = new Base(); __Base.BaseO = A; __Base.BaseX = BaseX; __Base.BaseY = BaseY; __Base.BaseZ = BaseZ; Base = __Base; }
/// <summary> /// The plane will be initialized by three float points, which are contained in the plane. /// </summary> /// <param name="A">First point</param> /// <param name="B">Second point</param> /// <param name="C">Third point</param> public Plane(xyzf A, xyzf B, xyzf C) { P = A.Toxyz(); xyz U = new xyz(B.x - A.X, B.y - A.y, B.z - A.z); xyz V = new xyz(C.x - A.X, C.y - A.y, C.z - A.z); NormalUnit = U & V; NormalUnit = NormalUnit.normalized(); }
/// <summary> /// This method calculates the distance to a point Pt. /// The parameter Lam can be used to calculate the nearest point of the LineType, which is /// also returned by the outvalue Nearest /// </summary> /// <param name="Pt">Point to calculate the distance to the LineType</param> /// <param name="Lam">Parameter to calculate the nearest point</param> /// <param name="Nearest">Point on the Line, with the lowest distance to Pt</param> /// <returns>Returns the distance from the line to the point Pt</returns> public double Distance(xyz Pt, out double Lam, out xyz Nearest) { if (Utils.Equals(Direction.length(), 0)) { Lam = 0; Nearest = P; return(Pt.dist(P)); } Lam = Direction.normalized().Scalarproduct(Pt.sub(P)) / Direction.length(); Nearest = P.add(Direction.mul(Lam)); return(Nearest.dist(Pt)); }
/// <summary> /// Calculates the relative coordinates from point. /// The base is assumed to be normalized /// The invert method is <see cref="Absolut"/>. /// </summary> /// <param name="P">Point</param> /// <returns>returns the coordinates relative to the base</returns> public xyz Relativ(xyz P) { if ((System.Math.Abs(BaseX * BaseY) < double.Epsilon) && (System.Math.Abs(BaseX * BaseZ) < double.Epsilon) && (System.Math.Abs(BaseZ * BaseY) < double.Epsilon) ) // Orthogonal { xyz d = P.sub(BaseO); return(new xyz(d.Scalarproduct(BaseX.normalized()), d.Scalarproduct(BaseY.normalized()), d.Scalarproduct(BaseZ.normalized()))); } P = P - BaseO; double Det = xyz.dot(BaseX, BaseY, BaseZ); if (System.Math.Abs(Det) < 0.0000000000000000001) { xyz d = P.sub(BaseO); return(new xyz(d.Scalarproduct(BaseX), d.Scalarproduct(BaseY), d.Scalarproduct(BaseZ))); } else { } return(new xyz(xyz.dot(P, BaseY, BaseZ) / Det, xyz.dot(BaseX, P, BaseZ) / Det, xyz.dot(BaseX, BaseY, P) / Det)); }
/// <summary> /// calculates the barycentric coordinates, which wil be returned. /// The point A*result.x +B*result.y+C*result.z is the normalprojection of P to /// the plane spanned by A,B and C. If A,B and C are in a line 0,0,0 wil be returned. /// </summary> /// <param name="A">Edge point of the triangle</param> /// <param name="B">Edge point of the triangle</param> /// <param name="C">Edge point of the triangle</param> /// <param name="P">Base point in the ABC plane </param> /// <returns></returns> public static xyz BaryCentric(xyz A, xyz B, xyz C, xyz P) { xyz F = (B - A) & (C - A); if (F.length() < 0.000000001) { return(new xyz(0, 0, 0)); } xyz N = F.normalized(); double TrABC = F * N; double TrCAP = ((C - P) & (A - P)) * N; double TrABP = ((A - P) & (B - P)) * N; double TrBCP = ((B - P) & (C - P)) * N; return(new xyz(TrBCP / TrABC, TrCAP / TrABC, TrABP / TrABC)); }
/// <summary> /// is a constructor wich has four points A, B, C, D on the plane and a normalvector N00 /// </summary> /// <param name="A">Point in the plane.</param> /// <param name="B">Point in the plane.</param> /// <param name="C">Point in the plane.</param> /// <param name="D">Point in the plane.</param> /// <param name="N00">Normalvector of the plane.</param> public SmoothPlane(xyz A, xyz B, xyz C, xyz D, xyz N00) : this() { plane = true; Base = Base.From4Points(A, B, C, D); this.N00 = N00.normalized(); this.A00 = Base.Relativ(A).toXY(); this.A10 = Base.Relativ(B).toXY(); this.A01 = Base.Relativ(C).toXY(); this.A11 = Base.Relativ(D).toXY(); this.A = A.toXYZF(); this.B = B.toXYZF(); this.C = C.toXYZF(); this.D = D.toXYZF(); }
/// <summary> /// Tries to complete the point Origin and the Zaxis to a normalized Base and returns this. /// </summary> /// <param name="Origin">The origin of the desired base</param> /// <param name="ZAxis">The z-Axis</param> /// <returns>a normalized Base</returns> public static Base DoComplete(xyz Origin, xyz ZAxis) { Base Result = new Base(); Result.BaseO = Origin; Result.BaseZ = ZAxis.normalized(); if (((Result.BaseZ & (new xyz(0, 1, 0))).length()) > 0.01) { Result.BaseX = (new xyz(0, 1, 0) & Result.BaseZ).normalized(); } else { Result.BaseX = (new xyz(1, 0, 0) & Result.BaseZ).normalized(); } Result.BaseY = Result.BaseZ & Result.BaseX; return(Result); }
/// <summary> /// Produce an orthogonal base with Origin a z-axis,the x-axis and a y-axis, which is normal to XAxis cross YVector /// </summary> /// <param name="Origin">The origin</param> /// <param name="XAxis">the x axis</param> /// <param name="YVector">the x axis is normal to XAxis cross YVector</param> /// <returns>orthogonal base</returns> public static Base DoComplete(xyz Origin, xyz XAxis, xyz YVector) { Base Result = new Base(); if (YVector.length() == 0) { YVector = XAxis & new xyz(0, 0, 1); if (YVector.length() == 0) { YVector = XAxis & new xyz(0, 1, 0); } if (YVector.length() == 0) { YVector = XAxis & new xyz(1, 0, 0); } } Result.BaseO = Origin; Result.BaseX = XAxis.normalized(); Result.BaseZ = (XAxis & YVector).normalized(); Result.BaseY = Result.BaseZ & Result.BaseX; return(Result); }
/// <summary> /// The plane will be initialized by three points, which are contained in the plane. /// </summary> /// <param name="A">First point</param> /// <param name="B">Second point</param> /// <param name="C">Third point</param> public Plane(xyz A, xyz B, xyz C) { P = A; NormalUnit = (B - A) & (C - A); NormalUnit = NormalUnit.normalized(); }
void RefreshNormals() { Normals = new Loxyz(); Normals.Count = Bounds.Count; DrawPoints = new Loxyz(); DrawPoints.Count = ParamCurves.Count; if (!DrawRelativToSurfaceBase) { for (int i = 0; i < Bounds.Count; i++) { EdgeLoop EL = Bounds[i]; for (int k = 0; k < EL.Count; k++) { Edge E = EL[k]; DrawPoints[i].Add(E.EdgeStart.Value); } } } for (int i = 0; i < ParamCurves.Count; i++) { xyArray A = ParamCurves[i].getxyArrayClosed(false); if (DrawRelativToSurfaceBase) { DrawPoints[i] = A.ToxyzArray(); } int ct = 0; for (int t = 0; t < ParamCurves[i].Count; t++) { ct = ct + ParamCurves[i][t].Resolution; } xyzArray NormalsLoop = new xyzArray(ct); Normals[i] = NormalsLoop; int id = 0; for (int j = 0; j < ParamCurves[i].Count; j++) { List <Face> L = GetFaces(this, i, j); Edge E = Bounds[i][j]; if (L == null) { Normals = null; DrawPoints = null; return; } double SmoothAngle = Parent.SmoothAngle; xyz N = Surface.Normal(0, 0).normalized(); xyz N1 = Surface.Normal(0, 0).normalized(); for (int k = 0; k < L.Count; k++) { if (System.Math.Abs((N1 * L[k].Surface.Normal(0, 0).normalized())) > System.Math.Cos(SmoothAngle)) { N = N + L[k].Surface.Normal(0, 0).normalized(); } } N = N.normalized(); if (DrawRelativToSurfaceBase) { Matrix M = Surface.Base.ToMatrix().invert(); N = M * N - M * new xyz(0, 0, 0); } NormalsLoop[id] = N; id++; } } }
/// <summary> /// creates a <see cref="Face"/> for a <see cref="Solid"/> in the <see cref="Model.Solid"/>. /// The Curves are all <see cref="Line3D"/>. The <see cref="Face"/> is plane and has as <see cref="Face.Surface"/> a <see cref="PlaneSurface"/>. /// </summary> /// <param name="Solid">is the target in which the <see cref="Face"/> will be posed.</param> /// <param name="Bounds">contains the <see cref="Vertex3d"/> for the <see cref="Line3D"/>.</param> /// <returns>a <see cref="Face"/></returns> public static Face SolidPlane(Solid Solid, Vertex3dArray_2 Bounds) { if (Bounds.Count == 0) { return(null); } xyz N = new xyz(0, 0, 0); xyz P = Bounds[0][0].Value; for (int i = 1; i < Bounds[0].Count - 1; i++) { xyz A = Bounds[0][i].Value; xyz B = Bounds[0][i + 1].Value; xyz M = N; N = N + ((A - P) & (B - P)); } N = N.normalized() * (-1); Base Base = Base.UnitBase; Base.BaseO = P; Base.BaseZ = N; if ((Base.BaseZ & new xyz(1, 0, 0)).dist(xyz.Null) > 0.01) { Base.BaseY = (Base.BaseZ & (new xyz(1, 0, 0))).normalized(); Base.BaseX = Base.BaseY & Base.BaseZ; } else { Base.BaseY = (Base.BaseZ & (new xyz(0, 1, 0))).normalized(); Base.BaseX = Base.BaseY & Base.BaseZ; } PlaneSurface Surface = new PlaneSurface(); Surface.Base = Base; //------------------------------------- //-------- Create the Face Face Result = new Face(); // ---- With Plane Surface Result.Surface = Surface; if (Solid != null) { Solid.FaceList.Add(Result); } //----- Set the Edges for (int i = 0; i < Bounds.Count; i++) { EdgeLoop Edgeloop = new EdgeLoop(); Result.Bounds.Add(Edgeloop); for (int j = 0; j < Bounds[i].Count; j++) { Vertex3d A = Bounds[i][j]; Vertex3d B = null; if (j == Bounds[i].Count - 1) { B = Bounds[i][0]; } else { B = Bounds[i][j + 1]; } Edge E = Edge.SolidEdge(Solid, Result, A, B, new Line3D(A.Value, B.Value)); Edgeloop.Add(E); } } Result.RefreshParamCurves(); return(Result); }