public bool PointInUpperHalfPlane(GLPoint P) { var n = NormalVector; var testInEq = -n.X * P.X - n.Y * P.Y - n.Z * P.Z - D; return(testInEq > 0); }
public GLPolygon NearestPolygon(GLPoint P) { GLPolygon nearestPolygon = null; var minDistance = double.MaxValue; var i = 0; foreach (var obj in Objects) { if (obj is GLObject) { var d = obj.DistanceToPoint(P); if (d == -1) { // some error continue; } if (d < minDistance) { minDistance = d; nearestPolygon = (obj as GLObject).NearestPolygon(P); } } i++; } return(nearestPolygon); }
public GLPolygon NearestPolygon(GLPoint P) { //Logger.WriteToLog("Detecting nearest polygon to point: " + P.ToString()); GLPolygon nearestPolygon = null; var minDistance = double.MaxValue; var i = 0; foreach (var pol in Polygons) { var d = pol.DistanceToPoint(P); if (d < minDistance) { minDistance = d; nearestPolygon = pol; } //Logger.WriteToLog(String.Format("Distance to polygon {0}: {1} ",i,d.ToString("#0.00"))); i++; } return(nearestPolygon); }
public GLPoint(GLPoint p) { Name = ""; X = p.X; Y = p.Y; Z = p.Z; }
public static GLPlane CreateFromPoints(GLPoint A, GLPoint B, GLPoint C) { var u = new GLVector(A, B); var v = new GLVector(B, C); return(CreateFromVectorsAndPoint(u, v, A)); }
public static GLPoint GetMovedPointByAngle(GLPoint P, double stepSize, double angle, bool forward) { var rotatedPoint = new GLPoint(0, P.Y, 0); rotatedPoint.X = P.X + stepSize * Math.Cos((angle - 90) * Math.PI / 180.0); rotatedPoint.Z = P.Z + stepSize * Math.Sin((angle - 90) * Math.PI / 180.0); var viewVec = new GLVector(rotatedPoint, P); var movedPoint = new GLPoint(P.X, P.Y, P.Z); if (forward) { movedPoint.X += 1 * viewVec.X; movedPoint.Y += 1 * viewVec.Y; movedPoint.Z += 1 * viewVec.Z; } else { movedPoint.X -= 1 * viewVec.X; movedPoint.Y -= 1 * viewVec.Y; movedPoint.Z -= 1 * viewVec.Z; } return(movedPoint); }
public GLPoint RotatedByAxis(GLAxisEnum axis, double radius, double angle) { var rotatedPoint = new GLPoint(this); var angleRad = DegToRad(angle); switch (axis) { case GLAxisEnum.X: rotatedPoint.Y = Y * Math.Cos(angleRad) - Z * Math.Sin(angleRad); rotatedPoint.Z = Y * Math.Sin(angleRad) + Z * Math.Cos(angleRad); break; case GLAxisEnum.Y: rotatedPoint.X = X * Math.Cos(angleRad) - Z * Math.Sin(angleRad); rotatedPoint.Z = X * Math.Sin(angleRad) + Z * Math.Cos(angleRad); break; case GLAxisEnum.Z: rotatedPoint.X = X * Math.Cos(angleRad) - Y * Math.Sin(angleRad); rotatedPoint.Y = X * Math.Sin(angleRad) + Y * Math.Cos(angleRad); break; } return(rotatedPoint); }
public GLPolygon(GLPoint A, GLPoint B, GLPoint C, GLPoint D) : this() { Points.Add(A); Points.Add(B); Points.Add(C); Points.Add(D); }
public static GLLine CrateFromPoints(GLPoint A, GLPoint B) { var line = new GLLine(); line.Position = A; line.LineVector = new GLVector(A, B); return(line); }
public double DistanceToPoint(GLPoint P) { // √( x2 + y2 + z2) var denominator = Math.Pow((P.X - X), 2) + Math.Pow((P.Y - Y), 2) + Math.Pow((P.Z - Z), 2); if (denominator == 0) { return(0); // zero vector -the same point } return(Math.Sqrt(denominator)); }
public override double DistanceToPoint(GLPoint point) { if (Polygons == null || Polygons.Count == 0) { return(base.DistanceToPoint(point)); } var pol = NearestPolygon(point); var dist = pol.DistanceToPoint(point); return(dist); }
public override void Render() { base.BeforeRender(); GL.Disable(All.Texture2D); GL.Color4(FillColor.R, FillColor.G, FillColor.B, FillColor.A); GL.EnableClientState(All.VertexArray); GL.Color4(FillColor.R, FillColor.G, FillColor.B, FillColor.A); GLPoint lastPoint = new GLPoint(); var vertexCoords = new float[216]; // 36 lines, 2 points for every line, 3 floats for every point for (var i = 0; i <= 36; i++) { var p = GetPositionOfAngleFocused(i * 10); if (i != 0) { var vIndex = (i - 1) * 6; vertexCoords[vIndex + 0] = (float)p.X; vertexCoords[vIndex + 1] = (float)p.Y; vertexCoords[vIndex + 2] = (float)p.Z; vertexCoords[vIndex + 3] = (float)lastPoint.X; vertexCoords[vIndex + 4] = (float)lastPoint.Y; vertexCoords[vIndex + 5] = (float)lastPoint.Z; } lastPoint = p; } unsafe { fixed(float *pv = vertexCoords) { GL.VertexPointer(3, All.Float, 0, new IntPtr(pv)); GL.DrawArrays(All.Lines, 0, 72); GL.Finish(); } } GL.Enable(All.Texture2D); GL.DisableClientState(All.VertexArray); base.AfterRender(); }
// https://www.codeproject.com/Articles/18160/Spherical-Coordinates-in-C private GLPoint Spherical(double r, double theta, double phi) { var pt = new GLPoint(); double snt = (double)Math.Sin(theta * Math.PI / 180.0); double cnt = (double)Math.Cos(theta * Math.PI / 180.0); double snp = (double)Math.Sin(phi * Math.PI / 180.0); double cnp = (double)Math.Cos(phi * Math.PI / 180.0); pt.X = r * snt * cnp; pt.Y = r * cnt; pt.Z = -r * snt * snp; //pt.W = 1; return(pt); }
public GLPoint GetNewRandomStar(Random r = null) { if (r == null) { r = new Random(); } var star = new GLPoint(); star.X = r.NextDouble() * Math.Abs(SizeVec.X) - Math.Abs(SizeVec.X) / 2; star.Y = r.NextDouble() * Math.Abs(SizeVec.Y) - Math.Abs(SizeVec.Y) / 2; star.Z = r.NextDouble() * Math.Abs(SizeVec.Z) - Math.Abs(SizeVec.Z) / 2; return(star); }
public static GLPlane CreateFromVectorsAndPoint(GLVector u, GLVector v, GLPoint P) { var plane = new GLPlane(); plane.Name = "plane"; plane.Position = P; var n = GLVector.CrossProduct(u, v); plane.NormalVector = n; plane.D = -n.X * P.X - n.Y * P.Y - n.Z * P.Z; return(plane); }
public double IntersectionWithPerpendicularThroughPointParamTValue(GLPoint P) { var U = LineVector; var A = Position; var denominator = U.X * U.X + U.Y * U.Y + U.Z * U.Z; if (denominator == 0) { return(double.MinValue); } var t = (U.X * (P.X - A.X) + U.Y * (P.Y - A.Y) + U.Z * (P.Z - A.Z)) / denominator; return(t); }
public GLPoint CrossWithLine(GLLine line) { var n = NormalVector; var P = line.Position; var denominator = Math.Pow(n.X, 2) + Math.Pow(n.Y, 2) + Math.Pow(n.Z, 2); if (denominator == 0) { return(null); } var numerator = (-n.X * P.X - n.Y * P.Y - n.Z * P.Z - D); var t = numerator / denominator; var resPoint = new GLPoint(P.X + t * n.X, P.Y + t * n.Y, P.Z + t * n.Z); return(resPoint); }
public void GenerateRingPolygon() { Ring = new GLObject(); GLTexture ringTexture = null; if (RingTextureName != null) { ringTexture = GLTextureAdmin.GetTextureByName(RingTextureName); } var angleStep = 360.0 / (double)Slices; var c = new GLPoint(0, 0, 0); for (double i = 0; i <= 360; i += angleStep) { double ax = (Radius + 1) * Math.Cos(i * Math.PI / 180.0) + c.X; double az = (Radius + 1) * Math.Sin(i * Math.PI / 180.0) + c.Z; double bx = (Radius + 1 + RingSize) * Math.Cos(i * Math.PI / 180.0) + c.X; double bz = (Radius + 1 + RingSize) * Math.Sin(i * Math.PI / 180.0) + c.Z; double cx = (Radius + 1 + RingSize) * Math.Cos((i + angleStep) * Math.PI / 180.0) + c.X; double cz = (Radius + 1 + RingSize) * Math.Sin((i + angleStep) * Math.PI / 180.0) + c.Z; double dx = (Radius + 1) * Math.Cos((i + angleStep) * Math.PI / 180.0) + c.X; double dz = (Radius + 1) * Math.Sin((i + angleStep) * Math.PI / 180.0) + c.Z; var polygon = new GLPolygon(); polygon.FillColor = RingFillColor; polygon.Texture = ringTexture; polygon.Points.Add(new GLPoint(ax, c.Y, az)); polygon.Points.Add(new GLPoint(bx, c.Y, bz)); polygon.Points.Add(new GLPoint(cx, c.Y, cz)); polygon.Points.Add(new GLPoint(dx, c.Y, dz)); Ring.Polygons.Add(polygon); } }
public void LoadFromXmlElement(XmlElement element) { Points = new List <GLPoint>(); var allPoints = element.SelectNodes("point"); if (allPoints != null) { foreach (XmlElement pointElement in allPoints) { var p = new GLPoint(); p.LoadFromXmlElement(pointElement); Points.Add(p); } } if (element.HasAttribute("texture")) { Name = element.GetAttribute("texture"); Texture = GLTextureAdmin.GetTextureByName(Name); } }
public GLObj() { Rotation = new GLVector(0, 0, 0); Position = new GLPoint(0, 0, 0); }
public static GLPoint CopyFrom(GLPoint point) { return(new GLPoint(point.X, point.Y, point.Z)); }
public GLPoint PointAdded(GLPoint P) { return(new GLPoint(X + P.X, Y + P.Y, Z + P.Z)); }
public GLPoint PointSubtracted(GLPoint P) { return(new GLPoint(X - P.X, Y - P.Y, Z - P.Z)); }
public GLVector(GLPoint A, GLPoint B) { X = A.X - B.X; Y = A.Y - B.Y; Z = A.Z - B.Z; }
/// A t in <0;1> B /// -------------------------------- /// ^ I /// | /// | s in <0;1> /// | /// | /// |P /// /// Line: Point A,B; Vec U = B - A /// X = Ax + t*Ux /// Y = Ay + t*Uy /// Z = Az + t*Uz /// /// Perpendicular: Point P,I; Vec V = I - P /// X = Px + s*Vx /// Y = Py + s*Vy /// Z = Pz + s*Vz /// /// U and V are perpendicular (U.V = 0) /// /// UxVx+UyVy+UzVz = 0 /// ------------------- /// /// Param s = 1 at intersection I /// public GLPoint IntersectionWithPerpendicularThroughPoint(GLPoint P) { var t = IntersectionWithPerpendicularThroughPointParamTValue(P); return(this.PointByParam(t)); }
/// <summary> /// Go the specified direction. /// </summary> /// <param name="direction">Direction. /// 0 .. forward (angle 0) /// 1 .. backward (angle 0) /// 2 .. left (angle -90) /// 3 .. right</param> (angle +90) public void Go(DirectionEnum direction, double stepSize = 2) { GLPoint movedPoint = new GLPoint(0, 0, 0); switch (direction) { case DirectionEnum.Forward: movedPoint = GLPoint.GetMovedPointByAngle(Observer.Position, stepSize, Observer.Rotation.Y, true); break; case DirectionEnum.Backward: movedPoint = GLPoint.GetMovedPointByAngle(Observer.Position, stepSize, Observer.Rotation.Y, false); break; case DirectionEnum.Left: movedPoint = GLPoint.GetMovedPointByAngle(Observer.Position, stepSize, Observer.Rotation.Y - 90, true); break; case DirectionEnum.Right: movedPoint = GLPoint.GetMovedPointByAngle(Observer.Position, stepSize, Observer.Rotation.Y + 90, true); break; } var nearestPolygon = NearestPolygon(movedPoint); var dist = nearestPolygon.DistanceToPoint(movedPoint); //L/ogger.Debug("Distance to labyrinth:" + dist); if (dist > DefaultDistance) { Observer.Position = movedPoint; } else { // collision var angle = nearestPolygon.AngleToVec(new GLVector(Observer.Position, movedPoint)); if ((angle < 65) && ((int)direction < 2)) { // sliding left GLPoint leftRotatedMovedPoint = new GLPoint(0, 0, 0); switch (direction) { case DirectionEnum.Forward: leftRotatedMovedPoint = GLPoint.GetMovedPointByAngle(Observer.Position, 3, Observer.Rotation.Y - angle, true); break; case DirectionEnum.Backward: leftRotatedMovedPoint = GLPoint.GetMovedPointByAngle(Observer.Position, 3, Observer.Rotation.Y - angle, false); break; } var nearestPolygonToLeft = NearestPolygon(leftRotatedMovedPoint); var distLeft = nearestPolygonToLeft.DistanceToPoint(leftRotatedMovedPoint); if (distLeft > DefaultDistance) { Observer.Position = leftRotatedMovedPoint; } else { // sliding right GLPoint rightRotatedMovedPoint = new GLPoint(0, 0, 0); switch (direction) { case DirectionEnum.Forward: rightRotatedMovedPoint = GLPoint.GetMovedPointByAngle(Observer.Position, 3, Observer.Rotation.Y + angle, true); break; case DirectionEnum.Backward: rightRotatedMovedPoint = GLPoint.GetMovedPointByAngle(Observer.Position, 3, Observer.Rotation.Y + angle, false); break; } var nearestPolygonToRight = NearestPolygon(rightRotatedMovedPoint); var distRight = nearestPolygonToRight.DistanceToPoint(rightRotatedMovedPoint); if (distRight > DefaultDistance) { Observer.Position = rightRotatedMovedPoint; } } } } }
public double DistanceToPoint(GLPoint P) { // using first three points for creating plane vectors: if (Points.Count < 3) { return(-1); } var plane = GLPlane.CreateFromPoints(Points[0], Points[1], Points[2]); // computing line (made by observer view) - plane cross var viewLine = new GLLine(); viewLine.Position = P; viewLine.LineVector = plane.NormalVector; var cross = plane.CrossWithLine(viewLine); // geting polygon center to determine right half-plane var center = new GLPoint( (Points[0].X + Points[1].X + Points[2].X) / 3, (Points[0].Y + Points[1].Y + Points[2].Y) / 3, (Points[0].Z + Points[1].Z + Points[2].Z) / 3); // creating polygon-edge planes: //Logger.WriteToLog("Generating edge planes and lines"); var edgeLines = new List <GLLine>(); var pointInsideEdgePlanes = true; for (var i = 0; i < Points.Count; i++) { var A = Points[i]; var B = i + 1 <= Points.Count - 1 ? Points[i + 1] : Points[0]; var u = new GLVector(A, B); var edgePlane = GLPlane.CreateFromVectorsAndPoint(u, plane.NormalVector, A); // testing center half-plane position var centerInUpperHalfPlane = edgePlane.PointInUpperHalfPlane(center); var crossInUpperHalfPlane = edgePlane.PointInUpperHalfPlane(cross); edgeLines.Add(GLLine.CrateFromPoints(A, B)); if (centerInUpperHalfPlane != crossInUpperHalfPlane) { pointInsideEdgePlanes = false; break; } } //Logger.WriteToLog(" cross: " + cross.ToString()); if (pointInsideEdgePlanes) { // point inside edge planes //Logger.WriteToLog(" point inside edge planes"); return(cross.DistanceToPoint(P)); } else { //Logger.WriteToLog("detecting minimal distance to all edge lines"); var minDistance = double.MaxValue; foreach (var line in edgeLines) { if (line.LineVector.IsZero) { continue; } var intersectionT = line.IntersectionWithPerpendicularThroughPointParamTValue(P); //Logger.WriteToLog(" intersectionT param value: " + intersectionT.ToString()); if (intersectionT == double.MinValue) { return(-1); } if (intersectionT < 0) { // distance to A var distanceToA = P.DistanceToPoint(line.Position); if (distanceToA < minDistance) { minDistance = distanceToA; } } else if (intersectionT > 1) { // distance to B var B = line.PointByParam(1); var distanceToB = P.DistanceToPoint(B); if (distanceToB < minDistance) { minDistance = distanceToB; } } else { // distance to perpendicular line intersection var intersection = line.PointByParam(intersectionT); var distanceToLine = P.DistanceToPoint(intersection); if (distanceToLine < minDistance) { minDistance = distanceToLine; } } } if (minDistance == double.MaxValue) { return(-1); } return(minDistance); } }
public virtual double DistanceToPoint(GLPoint point) { var dist = Position.DistanceToPoint(point); return(dist); }
} // vector of rotation in all axis public GLObj(string name) { Name = name; Rotation = new GLVector(0, 0, 0); Position = new GLPoint(0, 0, 0); }
public static GLPoint GetMovedPoint(GLPoint P, GLVector moveVector) { return(new GLPoint(P.X + moveVector.X, P.X + moveVector.Y, P.X + moveVector.Z)); }