public SlopeArcher(BaseVisualMode mode, List <IVisualEventReceiver> sectors, VisualSidedefSlope handle1, VisualSidedefSlope handle2, double theta, double offsetangle, double scale)
        {
            this.mode        = mode;
            this.sectors     = sectors;
            this.handle1     = handle1;
            this.handle2     = handle2;
            this.theta       = theta;
            this.offsetangle = offsetangle;
            this.scale       = scale;
            heightoffset     = 0.0;

            handleline = new Line2D(handle1.GetCenterPoint(), handle2.GetCenterPoint());
            length     = handleline.GetLength();

            if (handle1.Level.type == SectorLevelType.Ceiling)
            {
                baseheight = handle1.Level.extrafloor ? handle1.Level.sector.FloorHeight : handle1.Level.sector.CeilHeight;
            }
            else
            {
                baseheight = handle1.Level.extrafloor ? handle1.Level.sector.CeilHeight : handle1.Level.sector.FloorHeight;
            }

            baseheightoffset = 0.0;
        }
示例#2
0
        //mxd
        public void DrawLine3DFloor(int x1, int y1, int x2, int y2, ref PixelColor c, PixelColor c2)
        {
            Line2D line   = new Line2D(x1, y1, x2, y2);
            float  length = line.GetLength();

            if (length < DASH_INTERVAL * 2)
            {
                DrawLineSolid(x1, y1, x2, y2, ref c2);
            }
            else
            {
                float d1 = DASH_INTERVAL / length;
                float d2 = 1.0f - d1;


                Vector2D p1 = line.GetCoordinatesAt(d1);
                Vector2D p2 = line.GetCoordinatesAt(d2);

                DrawLineSolid(x1, y1, (int)p1.x, (int)p1.y, ref c2);
                DrawLineSolid((int)p1.x, (int)p1.y, (int)p2.x, (int)p2.y, ref c);
                DrawLineSolid((int)p2.x, (int)p2.y, x2, y2, ref c2);
            }
        }
示例#3
0
        //mxd
        public override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            // Anything to do?
            if ((!selectpressed && !editpressed) || closestline == null)
            {
                hintlabel.Text = string.Empty;
                return;
            }

            // Do something...
            Vector2D perpendicular = closestline.Line.GetPerpendicular().GetNormal();

            if (panel.Distance != 0)
            {
                perpendicular *= panel.Distance;                                 // Special cases...
            }
            Vector2D center         = closestline.GetCenterPoint();
            Line2D   radius         = new Line2D(center, center - perpendicular);
            float    u              = radius.GetNearestOnLine(mousemappos - mousedownoffset);
            int      dist           = (panel.Distance == 0 ? 1 : panel.Distance); // Special cases...
            int      offset         = (int)Math.Round(dist * u - dist);
            bool     updaterequired = false;

            // Clamp values?
            bool clampvalue = !General.Interface.ShiftState;

            // Change verts amount
            if (selectpressed && editpressed)
            {
                if (prevoffset != 0)
                {
                    // Set new verts count without triggering the update...
                    panel.SetValues(panel.Vertices + Math.Sign(prevoffset - offset), panel.Distance, panel.Angle, panel.FixedCurve);

                    // Update hint text
                    hintlabel.Text = "Vertices: " + panel.Vertices;
                    updaterequired = true;
                }
            }
            // Change distance
            else if (selectpressed && !panel.FixedCurve)
            {
                if (float.IsNaN(u))
                {
                    // Set new distance without triggering the update...
                    panel.SetValues(panel.Vertices, 0, panel.Angle, panel.FixedCurve);                     // Special cases...
                }
                else
                {
                    int newoffset;
                    if (clampvalue)
                    {
                        newoffset = (panel.Distance + offset) / panel.DistanceIncrement * panel.DistanceIncrement;                         // Clamp to 8 mu increments
                    }
                    else
                    {
                        newoffset = panel.Distance + offset;
                    }

                    // Set new distance without triggering the update...
                    panel.SetValues(panel.Vertices, newoffset, panel.Angle, panel.FixedCurve);
                }

                // Update hint text
                hintlabel.Text = "Distance: " + panel.Distance;
                updaterequired = true;
            }
            // Change angle
            else if (editpressed && prevoffset != 0)
            {
                int newangle = 0;
                if (panel.FixedCurve)
                {
                    // Flip required?
                    if (panel.Angle == 0 && (Math.Sign(offset - prevoffset) != Math.Sign(panel.Distance)))
                    {
                        // Set new distance without triggering the update...
                        panel.SetValues(panel.Vertices, -panel.Distance, panel.Angle, panel.FixedCurve);

                        // Recalculate affected values...
                        perpendicular *= -1;
                        radius.v2      = center - perpendicular;
                        u              = radius.GetNearestOnLine(mousemappos - mousedownoffset);
                    }

                    //TODO: there surely is a way to get new angle without iteration...
                    float targetoffset = radius.GetLength() * u;
                    float prevdiff     = float.MaxValue;
                    int   increment    = (clampvalue ? panel.AngleIncrement : 1);
                    for (int i = 1; i < panel.MaximumAngle; i += increment)
                    {
                        // Calculate diameter for current angle...
                        float ma = Angle2D.DegToRad(i);
                        float d  = (closestline.Length / (float)Math.Tan(ma / 2f)) / 2;
                        float D  = d / (float)Math.Cos(ma / 2f);
                        float h  = D - d;

                        float curdiff = Math.Abs(h - targetoffset);

                        // This one matches better...
                        if (curdiff < prevdiff)
                        {
                            newangle = i;
                        }
                        prevdiff = curdiff;
                    }

                    // Clamp to 5 deg increments
                    if (clampvalue)
                    {
                        newangle = (newangle / panel.AngleIncrement) * panel.AngleIncrement;
                    }
                }
                else
                {
                    int diff = (int)Math.Round((offset - prevoffset) * renderer.Scale);
                    if (panel.Angle + diff > 0)
                    {
                        if (clampvalue)
                        {
                            newangle = (panel.Angle / panel.AngleIncrement + Math.Sign(diff)) * panel.AngleIncrement;                                    // Clamp to 5 deg increments
                        }
                        else
                        {
                            newangle = panel.Angle + diff;
                        }
                    }
                }

                // Set new angle without triggering the update...
                panel.SetValues(panel.Vertices, panel.Distance, newangle, panel.FixedCurve);

                // Update hint text
                hintlabel.Text = "Angle: " + panel.Angle;
                updaterequired = true;
            }

            // Update UI
            if (updaterequired)
            {
                // Update label position
                float labeldistance;

                if (panel.Angle == 0)
                {
                    labeldistance = 0;                     // Special cases!
                }
                else if (panel.FixedCurve)
                {
                    float ma = Angle2D.DegToRad(panel.Angle);
                    float d  = (closestline.Length / (float)Math.Tan(ma / 2f)) / 2;
                    float D  = d / (float)Math.Cos(ma / 2f);
                    labeldistance = D - d;
                }
                else
                {
                    labeldistance = Math.Abs(panel.Distance);
                }

                labeldistance += 16 / renderer.Scale;
                Vector2D labelpos = radius.GetCoordinatesAt(labeldistance / radius.GetLength());
                hintlabel.Move(labelpos, labelpos);

                // Trigger update
                OnValuesChanged(null, EventArgs.Empty);
            }

            // Store current offset
            prevoffset = offset;
        }
示例#4
0
 public float GetLength()
 {
     return(l2d.GetLength());
 }
 public float GetLength()
 {
     return(Line2D.GetLength(v2.x - v1.x, v2.y - v1.y));
 }
示例#6
0
 private static int GetLength(int x1, int y1, int x2, int y2)
 {
     return((int)Line2D.GetLength(new Point2D(x1, y1), new Point2D(x2, y2)));
 }
		// This generates the vertices to split the line with, from start to end
		private List<Vector2D> GenerateCurve(Line2D line, int vertices, float angle, bool backwards, float distance, bool fixedcurve)
		{

			// Make list
			List<Vector2D> points = new List<Vector2D>(vertices);

			//Added by Anders Åstrand 2008-05-18
			//The formulas used are taken from http://mathworld.wolfram.com/CircularSegment.html
			//c and theta are known (length of line and angle parameter). d, R and h are
			//calculated from those two
			//If the curve is not supposed to be a circular segment it's simply deformed to fit
			//the value set for distance.

			//The vertices are generated to be evenly distributed (by angle) along the curve
			//and lastly they are rotated and moved to fit with the original line

			//calculate some identities of a circle segment (refer to the graph in the url above)
			double c = line.GetLength();
			double theta = angle;

			double d = (c / Math.Tan(theta / 2)) / 2;
			double R = d / Math.Cos(theta / 2);
			double h = R - d;

			double yDeform = fixedcurve ? 1 : distance / h;
			if (backwards)
				yDeform = -yDeform;

			double a, x, y;
			Vector2D vertex;

			for (int v = 1; v <= vertices; v++)
			{
				//calculate the angle for this vertex
				//the curve starts at PI/2 - theta/2 and is segmented into vertices+1 segments
				//this assumes the line is horisontal and on y = 0, the point is rotated and moved later

				a = (Math.PI - theta) / 2 + v * (theta / (vertices + 1));

				//calculate the coordinates of the point, and distort the y coordinate
				//using the deform factor calculated above
				x = Math.Cos(a) * R;
				y = (Math.Sin(a) * R - d) * yDeform;

				//rotate and transform to fit original line
				vertex = new Vector2D((float)x, (float)y).GetRotated(line.GetAngle() + Angle2D.PIHALF);
				vertex = vertex.GetTransformed(line.GetCoordinatesAt(0.5f).x, line.GetCoordinatesAt(0.5f).y, 1, 1);

				points.Add(vertex);
			}


			// Done
			return points;
		}