/// <summary> /// Calculates the distance to a Point, if this distance is smaller than MaxDist. Otherwise <see cref="Utils.big"/> will be returned. /// </summary> /// <param name="Point">A Point</param> /// <param name="MaxDist">Maximal distance</param> /// <param name="LineLam">A value for which the nearest point in the array can evaluated with <see cref="Value"/></param> /// <returns>Distance.</returns> public double Distance(xyz Point, double MaxDist, out double LineLam) { double result = Utils.big; xyz Dummy; int i; double di, _lam; LineType L2; LineLam = -1; for (i = 1; i < Count; i++) { L2 = new LineType(this[i - 1], this[i].sub(this[i - 1])); di = L2.Distance(Point, out _lam, out Dummy); if (!Utils.Less(_lam, 0) && !Utils.Less(1, _lam)) { if (!Utils.Less(MaxDist, di) && (Utils.Less(di, result))) { result = di; if (Utils.Equals(_lam, 1)) { LineLam = i; } else { LineLam = i - 1 + _lam; } } } else { double _di = Point.dist(this[i]); if (!Utils.Less(MaxDist, _di) && (Utils.Less(_di, result))) { result = _di; LineLam = i; } if (i == 1) { _di = Point.dist(this[0]); if (!Utils.Less(MaxDist, _di) && (Utils.Less(_di, result))) { result = _di; LineLam = 0; } } } } return(result); }
/// <summary> /// Returns true if the array is convex. /// <remarks>The Array must be flat.</remarks> /// </summary> /// <returns>True if the array is convex.</returns> public bool IsConvex() { if (Count < 3) { return(true); } xyz A = this[0]; int j = 1; while ((j < Count) && (A.dist(this[j]) < 0.0000001)) { j++; } if (j == Count) { return(true); } xyz B = this[j]; j++; while ((j < Count) && ((A.dist(this[j]) < 0.0000001) || (B.dist(this[j]) < 0.0000001))) { j++; } if (j == Count) { return(true); } xyz C = this[j]; xyz V = (A - B) & (C - B); for (int i = 0; i < Count; i++) { int v = i - 1; if (v < 0) { v = Count - 1; } int n = i + 1; if (n >= Count) { n = 0; } A = this[v]; C = this[n]; B = this[i]; if (Utils.Less(((A - B) & (C - B)) * V, 0)) { return(false); } } return(true); }
/// <summary> /// This method calculates the distance to a Line L /// The parameter Lam1 can be taken to calculate the point, which has the lowest distance to /// the other Line L . Nearest1 = Value(Lam1). /// The parameter Lam2 can be taken to calculate the point of L , which has the lowest distance to /// the Linetype this. Nearest2 = L.Value(Lam2). /// </summary> /// <param name="L">The other LineType</param> /// <param name="Lam1">Paramter which belongs to this line : Nearest1 = Value(Lam1)</param> /// <param name="Lam2">Paramter which belongs to the Line L: Nearest2 = L.Value(Lam2)</param> /// <param name="Nearest1">The point on the Line, which has the smallest distance to the Line L</param> /// <param name="Nearest2">The point on the Line L, which has the smallest distance </param> /// <returns>Returns the distance to the line L</returns> public double Distance(LineType L, out double Lam1, out double Lam2, out xyz Nearest1, out xyz Nearest2) { xyz PQ = L.P.sub(P); double PQV = PQ.Scalarproduct(Direction); double PQW = PQ.Scalarproduct(L.Direction); double vv = Direction.Scalarproduct(Direction); double ww = L.Direction.Scalarproduct(L.Direction); double vw = L.Direction.Scalarproduct(Direction); double Det = vv * ww - vw * vw; if (Det == 0)// parallele { xyz n = PQ.cross(Direction).cross(Direction).normalized(); double result = PQ.Scalarproduct(n); Nearest2 = P.add(n.mul(result)); Nearest1 = P; Lam1 = 0; Lam2 = L.Direction.normalized().Scalarproduct(Nearest2.sub(L.P)); return(System.Math.Abs(result)); } else { Lam1 = (PQV * ww - PQW * vw) / Det; Lam2 = -(PQW * vv - PQV * vw) / Det; Nearest1 = P.add(Direction.mul(Lam1)); Nearest2 = L.P.add(L.Direction.mul(Lam2)); return(Nearest1.dist(Nearest2)); } }
/// <summary> /// sets the position of the shaft and of the top. /// </summary> /// <param name="Shaft">the shaft</param> /// <param name="Top">the top</param> public void SetShaftAndTop(xyz Shaft, xyz Top) { Base B = Base.DoComplete(Shaft, Top - Shaft); this._Transformation = B.ToMatrix(); Size = Top.dist(Shaft); }
private double getZoomFactor() { //Matrix PrInv = Device.ProjectionMatrix.invert(); //double z = Device.ViewPort.Width/Device.PixelsPerUnit/((PrInv * new xyz(1, 0,0)).x - (PrInv * new xyz(-1, 0, 0)).x); xyz P1 = Device.ProjectionMatrix.multaffin(new xyz(0, 1, 0)); xyz P0 = Device.ProjectionMatrix.multaffin(new xyz(0, 0, 0)); return(P1.dist(P0) / DefZoom); }
/// <summary> /// internal /// </summary> internal void setDefZoom() { xyz P1 = Device.ProjectionMatrix.multaffin(new xyz(0, 1, 0)); xyz P0 = Device.ProjectionMatrix.multaffin(new xyz(0, 0, 0)); DefZoom = P1.dist(P0); //Matrix PrInv = Device.ProjectionMatrix.invert(); //DefZoom = ((PrInv * new xyz(1, 0, -1)).x - (PrInv * new xyz(-1, 0, -1)).x) ; }
/// <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> /// overrides this method and calculates a point on the cone in u, v parameters. This point is /// nearest to the given <b>Point</b>. /// </summary> /// <param name="Point"> specifies a 3D-Points, for which a near point on the cone will be calculated and /// whose u and v value will be returned.</param> /// <returns>Resturns the u and v parameter of a near point on the Cone</returns> public override xy ProjectPoint(xyz Point) { xyz p = Base.Relativ(Point); double u1 = System.Math.Atan2(p.y, p.x); Double v = p.z; xyz Test = Value(u1 / UFactor, v / VFactor); if (Test.dist(Point) > 0.05) { } return(new xy(u1 / UFactor, v / VFactor)); }
/// <summary> /// overrides the <see cref="ProjectPoint(xyz)"/> method of <see cref="Surface"/>. /// </summary> /// <param name="Point">Point, wich will be projected th the surface</param> /// <returns>u amd v parameter. A call <b>Point</b></returns> public override xy ProjectPoint(xyz Point) { xyz p = Base.Relativ(Point); xyz PD = new xyz(0, 0, 0); xyz PU = new xyz(0, 0, 0); double Lam = -1; double Param = -1; DownPlane.Cross(new LineType(p, Direction), out Lam, out PD); UpPlane.Cross(new LineType(p, Direction), out Lam, out PU); xyzArray A = CurveArray; xyz R = StandardBase.Relativ(p); double u = Curve.Arcus(new xy(R.X, R.y)); xy PP11 = Curve.Value(u); if (PP11.dist(new xy(R.X, R.Y)) > 0.5) { } else { } A.Distance(new LineType(p, Direction), 1e10, out Param, out Lam); if (Height < 0) { double v = p.dist(PD) / PU.dist(PD); xyz PP = Value(u, v); return(new xy(u, v)); } else { xy pt = Curve.Value(u); xyz K = StandardBase.BaseX * pt.x + StandardBase.BaseY * pt.y; Plane P = new Plane(Base.BaseO, Base.BaseZ); LineType L = new LineType(K, Direction); xyz pkt = new xyz(0, 0, 0); P.Cross(L, out Lam, out pkt); double v = pkt.dist(p) / Height; xyz PP1 = Value(u, v); return(new xy(u, v)); } }
/// <summary> /// gives the height of the screen in world coordinates. /// <param name="ReferencePoint">when the projection is perspectivly, the referencepoint gives the depth, for which the height will be calcluated. /// When the projection is orthogonal this point is not used. See also <see cref="FieldOfView"/>. /// </param> /// </summary> /// <returns>the width of the screen in world coordinates.</returns> public double getWorldHeight(xyz ReferencePoint) { if (FieldOfView <= 0.01) { return((double)this.ViewPort.Height / PixelsPerUnit); } else { if (ProjectMatrixInvalid) { ProjectMatrixInvert = ProjectionMatrix.invert(); } ProjectMatrixInvalid = false; xyz P = ProjectionMatrix * ReferencePoint; xyz A = ProjectMatrixInvert * new xyz(0, 1, P.z); xyz B = ProjectMatrixInvert * new xyz(0, -1, P.z); return(A.dist(B)); } }
/// <summary> /// Gets the distance to a line. /// </summary> /// <param name="L">A line</param> /// <param name="MaxDist">maximal distance</param> /// <param name="param">Parameter relative to this curve</param> /// <param name="lam">Prameter relative to L</param> /// <returns>The distance</returns> public double Distance(LineType L, double MaxDist, out double param, out double lam) { double result = Utils.big; xyArray a = new xyArray(Resolution + 1); this.ToArray(a, 0); double di = a.Distance(L, MaxDist, out param, out lam); xyz P = L.Value(lam); xyz Q = Value(param).toXYZ(); double T = P.dist(Q); if (!Utils.Less(MaxDist, di)) { param = this.fromParam + param * toParam / Resolution; result = di; } return(result); }
/// <summary> /// calculate a pixels to world lenght. /// </summary> /// <param name="P">a refrence point, which is needed in case of perspective representation.</param> /// <param name="Pixels">Number of pixels</param> /// <returns></returns> public double PixelToWorld(Drawing3d.xyz P, int Pixels) { if (ProjectMatrixInvalid) { ProjectMatrixInvert = ProjectionMatrix.invert(); } ProjectMatrixInvalid = false; if (FieldOfView > 0.01) { xyz q = ProjectionMatrix * P; xyz A = ProjectMatrixInvert * (new xyz(0, 0, q.z)); xyz B = ProjectMatrixInvert * (new xyz(1, 0, q.z)); double d = A.dist(B); return(Pixels * d / (ViewPort.Width / 2)); } else { return((ProjectMatrixInvert.multaffin(new xyz((float)Pixels / (float)(ViewPort.Width / 2), 0, 0))).length()); } }
bool schnittkegel(LineType L, out xyz Pt, out xy uv) { uv = new xy(0, 0); Pt = new xyz(0, 0, 0); double Rdh = Radius / Height; xyz U = L.P + L.Direction; L.P.z = Height - L.P.z; U.z = Height - U.z; L.Direction = U - L.P; double A = (L.Direction.x * L.Direction.x) + (L.Direction.y * L.Direction.y) - Rdh * Rdh * L.Direction.z * L.Direction.z; double B = 2 * L.P.x * L.Direction.x + 2 * L.P.y * L.Direction.y - 2 * Rdh * Rdh * L.P.z * L.Direction.z; double C = L.P.x * L.P.x + L.P.y * L.P.y - Rdh * Rdh * L.P.z * L.P.z; double Diskriminante = Math.Sqrt(B * B - 4 * A * C); if (Diskriminante < 0) { return(false); } double t1 = (-B + Diskriminante) / (2 * A); double t2 = (-B - Diskriminante) / (2 * A); xyz P1 = L.P + L.Direction * t1; P1.z = Height - P1.z; xyz P2 = L.P + L.Direction * t2; P2.z = Height - P2.z; if (P1.dist(L.P) < P2.dist(L.P)) { Pt = P1; uv = ProjectPoint(Pt); } else { Pt = P2; uv = ProjectPoint(Pt); } return(true); }
/// <summary> /// gets the nearest point on the torus and return this as (u,v) parameters. /// </summary> /// <param name="Point">Specifies the point for which a nearst point shold be calculated.</param> /// <returns>Returns the (u,v) parameters of the nearest point.</returns> public override xy ProjectPoint(xyz Point) { xyz p = Base.Relativ(Point); double u = System.Math.Atan2(p.y, p.x); double v = System.Math.Atan2(p.z, p.x * System.Math.Cos(u) + p.y * System.Math.Sin(u) - OuterRadius); if (OuterRadius < InnerRadius) { double u1 = u + Math.PI; double v1 = System.Math.Atan2(p.z, p.x * System.Math.Cos(u1) + p.y * System.Math.Sin(u1) - OuterRadius); xyz Q = Value(u / UFactor, v / VFactor); xyz Q1 = Value(u1 / UFactor, v1 / VFactor); if (Q1.dist(p) < Q.dist(p)) { return(new xy(u1 / UFactor, v1 / VFactor)); } } return(new xy(u / UFactor, v / VFactor)); }
bool Check() { int FC = FaceList.Count; int KC = EdgeCurveList.Count; int EC = VertexList.Count; int CT = EC - KC + FC - 2; // Euler if (CT == 0) { int ED = EdgeList.Count; if (ED == 2 * KC) { /* Ok*/ } else {// return false; } } else { // return false; for (int i = 0; i < EdgeCurveList.Count; i++) { Edge[] Edges = EdgeCurveList[i].Tag as Edge[]; if (Edges != null) { if ((Edges[0] == null) || (Edges[1] == null)) { } else { if (EdgeList.IndexOf(Edges[0]) == -1) { } if (EdgeList.IndexOf(Edges[1]) == -1) { } } } if (EdgeCurveList[i].A.dist(EdgeCurveList[i].B) < 0.0001) { } } } if (!CheckEdges()) { } ; // return false; for (int i = 0; i < FaceList.Count; i++) { Face F = FaceList[i]; for (int j = 0; j < F.Bounds.Count; j++) { EdgeLoop EL = F.Bounds[j]; for (int k = 0; k < EL.Count; k++) { Edge E = EL[k]; int OutLoop = -1; if ((E.SameSense) && ( (E.EdgeCurve.A.dist(E.EdgeStart.Value) > 0.0001) || (E.EdgeCurve.B.dist(E.EdgeEnd.Value) > 0.0001))) { return(false); } if ((!E.SameSense) && ( (E.EdgeCurve.B.dist(E.EdgeStart.Value) > 0.0001) || (E.EdgeCurve.A.dist(E.EdgeEnd.Value) > 0.0001))) { return(false); } Face FF = null; if (E.EdgeCurve.Neighbors[0] == null) { return(false); } if (E.EdgeCurve is Line3D) { Line3D Curve3d = E.EdgeCurve as Line3D; xyz _A = F.Surface.Base.Relativ(Curve3d.A); xyz _B = F.Surface.Base.Relativ(Curve3d.B); if (System.Math.Abs(_A.z) > 0.001) { return(false); } double g = F.Surface.Base.BaseX.length(); double h = F.Surface.Base.BaseY.length(); xyz AA = F.Surface.Base.Absolut(_A); xyz BB = F.Surface.Base.Absolut(_B); if (AA.dist(Curve3d.A) > 0.001) { return(false); } } if (E.EdgeCurve.Neighbors[0] == E.EdgeCurve.Neighbors[1]) { return(false); } if (!FaceList.Contains(E.EdgeCurve.Neighbors[0])) { } if (!FaceList.Contains(E.EdgeCurve.Neighbors[1])) { return(false); } double d = Face.GetDualEdge(F, j, k + 0.01, ref OutLoop, ref FF); } } } return(true); }
/// <summary> /// Calculates a point of a Curve, which is nearest to "Point" /// </summary> /// <param name="Point">Point, which will be projected</param> /// <param name="Lambda">Evaluation parameter for <see cref="Value"/> to get the nearest point on the curve.</param> /// <returns></returns> public virtual bool NormalCross(xyz Point, ref double Lambda) { // Find first with Normal* (Point-Curve) <0 Lambda = -1; int Start = -1; for (int i = 0; i <= Resolution; i++) { double t = (float)i / (float)Resolution; xyz p = Point - Value(t); xyz d = Derivation(t); if (System.Math.Abs(d * p) < 0.001) { Lambda = t; return(true); } if ((d * p) >= 0) { Start = i; break; } } // Find next with tangent* (Point-Curve) >0 if (Start == -1) { return(false); } int End = -1; for (int i = Start; i <= Resolution; i++) { double t = (float)i / (float)Resolution; xyz p = Point - Value(t); xyz d = Derivation(t); if (System.Math.Abs(d * p) < 0.001) { Lambda = t; return(true); } if ((d * p) <= 0) { End = i; break; } } if (End == -1) { return(false); } double _End = (float)End / (float)Resolution; double _Start = _End - 1f / (float)Resolution; double x = Derivation(_Start) * (Point - Value(_Start)); double y = Derivation(_End) * (Point - Value(_End)); int IterateCount = 0; double Iterate = (_End + _Start) / 2; while (((_End - _Start) != 0) && (IterateCount < 40) && (System.Math.Abs ((Derivation(Iterate)) * (Point - Value(Iterate))) > 0.00001)) { if (Point.dist(Value(Iterate)) > 1) { } IterateCount++; if ((Derivation(Iterate) * (Point - Value(Iterate)) > 0)) { _Start = Iterate; Iterate = (_Start + _End) / 2; } else { _End = Iterate; Iterate = (_Start + _End) / 2; } } Lambda = Iterate; return(true); }