public void MultiplicativeOperations() { var result = CalcSimpleExpression("2 * 2"); Assert.AreEqual(result, 4M); // as decimal result = CalcSimpleExpression("2 * '2'"); Assert.AreEqual(result, 4M); // as decimal result = CalcSimpleExpression("'3'* 2"); Assert.AreEqual(result, 6M); // as decimal result = CalcSimpleExpression("2 * true"); Assert.AreEqual(result, 2M); // as decimal result = CalcSimpleExpression("4 / 2"); Assert.AreEqual(result, 2M); // as decimal result = CalcSimpleExpression("4 / 0"); Assert.IsTrue(Infinity.IsInfinity(result)); result = CalcSimpleExpression("4 / false"); Assert.IsTrue(Infinity.IsInfinity(result)); result = CalcSimpleExpression("2 / true"); Assert.AreEqual(2M, result); // as decimal }
private H3.Cell.Edge[] GenEdgesInternal(Vector3D v1, Vector3D v2, Vector3D v3, Vector3D v4) { int div = 5; List <H3.Cell.Edge> result = new List <H3.Cell.Edge>(); for (int i = 0; i <= div; i++) { Vector3D start = v1 + (v2 - v1) * i / div; Vector3D end = v3 + (v4 - v3) * i / div; start.Normalize(); end.Normalize(); start = Sterographic.S3toR3(start); end = Sterographic.S3toR3(end); if (Infinity.IsInfinite(start)) { start = end * 10; } if (Infinity.IsInfinite(end)) { end = start * 10; } result.Add(new H3.Cell.Edge(start, end)); } return(result.ToArray()); }
private static void ReflectGeodesicsRecursive(Sphere[] simplex, Circle3D[] geodesics, HashSet <Circle3D> completed) { if (0 == geodesics.Length) { return; } HashSet <Circle3D> newGeodesics = new HashSet <Circle3D>(new GyrationPlaneEqualityComparer()); foreach (Circle3D geodesic in geodesics) { for (int m = 0; m < simplex.Length; m++) { Sphere mirror = simplex[m]; Vector3D[] points = Infinity.IsInfinite(geodesic.Radius) ? new Vector3D[] { -geodesic.Normal, new Vector3D(), geodesic.Normal } : geodesic.RepresentativePoints; Vector3D[] reflected = points.Select(p => mirror.ReflectPoint(p)).ToArray(); Circle3D newCirc = new Circle3D(reflected[0], reflected[1], reflected[2]); if (completed.Add(newCirc)) { newGeodesics.Add(newCirc); } } } ReflectGeodesicsRecursive(simplex, newGeodesics.ToArray(), completed); }
/// <summary> /// This transform will map z1 to Zero, z2 to One, and z3 to Infinity. /// http://en.wikipedia.org/wiki/Mobius_transformation#Mapping_first_to_0.2C_1.2C_.E2.88.9E /// If one of the zi is ∞, then the proper formula is obtained by first /// dividing all entries by zi and then taking the limit zi → ∞ /// </summary> public void MapPoints(Complex z1, Complex z2, Complex z3) { if (Infinity.IsInfinite(z1)) { A = 0; B = -1 * (z2 - z3); C = -1; D = z3; } else if (Infinity.IsInfinite(z2)) { A = 1; B = -z1; C = 1; D = -z3; } else if (Infinity.IsInfinite(z3)) { A = -1; B = z1; C = 0; D = -1 * (z2 - z1); } else { A = z2 - z3; B = -z1 * (z2 - z3); C = z2 - z1; D = -z3 * (z2 - z1); } Normalize(); }
// Rotates a dodec about a vertex or edge to get a dual dodec. private static Dodec GetDual(Dodec dodec, Vector3D rotationPoint) { //double rot = System.Math.PI / 2; // Edge-centered double rot = 4 * (-Math.Atan((2 + Math.Sqrt(5) - 2 * Math.Sqrt(3 + Math.Sqrt(5))) / Math.Sqrt(3))); // Vertex-centered Mobius m = new Mobius(); if (Infinity.IsInfinite(rotationPoint)) { m.Elliptic(Geometry.Spherical, new Vector3D(), -rot); } else { m.Elliptic(Geometry.Spherical, rotationPoint, rot); } Dodec dual = new Dodec(); foreach (Vector3D v in dodec.Verts) { Vector3D rotated = m.ApplyInfiniteSafe(v); dual.Verts.Add(rotated); } foreach (Vector3D v in dodec.Midpoints) { Vector3D rotated = m.ApplyInfiniteSafe(v); dual.Midpoints.Add(rotated); } return(dual); }
/// <summary> /// Generate a catenoid, then move it to a point on the hemisphere in S^3. /// </summary> private static Mesh Catenoid(double scale, Vector3D loc, double rld_height, double waist) { double h = waist * 3.5; //Mesh mesh = StandardCatenoid( waist, h ); Mesh mesh = CatenoidSquared(waist, h); mesh.Scale(scale * rld_height * 2 / h); // To make the catenoid meet up with the RLD solution. // First move to north pole, then rotate down to the location. Func <Vector3D, Vector3D> transform = v => { v = H3Models.BallToUHS(v); Vector3D northPole = new Vector3D(0, 0, 1); Vector3D axis = loc.Cross(northPole); if (!axis.Normalize()) // North or south pole? { return(v); } double anglXY = Euclidean2D.AngleToCounterClock(new Vector3D(1, 0), new Vector3D(loc.X, loc.Y)); v.RotateXY(anglXY); double angleDown = loc.AngleTo(northPole); v.RotateAboutAxis(axis, angleDown); if (v.DNE || Infinity.IsInfinite(v)) { throw new System.Exception(); } return(v); }; mesh.Transform(transform); return(mesh); }
public static Infinity operator /(Infinity inf1, double n) { Infinity result = inf1; result.Number /= n; result.RecaculateIndex(); return(result); }
public static void Remove(GameObject target) { Infinity behaviour = target.GetComponent <Infinity>(); if (behaviour != null) { Destroy(behaviour); } }
public static Infinity operator /(Infinity inf1, Infinity inf2) { Infinity result = inf1; result.Number /= inf2.Number; result.Index -= inf2.Index; result.RecaculateIndex(); return(result); }
public static Infinity operator -(Infinity inf1, Infinity inf2) { Infinity result = inf1; var subIndex = result.Index - inf2.Index; var t = Math.Pow(1000.0, subIndex); result.Number -= inf2.Number / t; return(result); }
public bool Equals(double d1, double d2) { if (Infinity.IsInfinite(d1) && Infinity.IsInfinite(d2)) { return(true); } return(Tolerance.Equal(d1, d2)); }
public static Infinity Apply(GameObject target, float width, float height, float speed) { Infinity behaviour = target.AddComponent <Infinity>(); behaviour.width = width; behaviour.height = height; behaviour.speed = speed; return(behaviour); }
private void Invoke() { if (IsCoroutine) { Infinity.DOEditorCoroutine((IEnumerator)method.Invoke(declaringObject, arguments)); } else { method.Invoke(declaringObject, arguments); } }
void DisplayInfiniteAmmo() { Ammo t_ammo = LoadNewAmmo(); t_ammo.m_NewLocalPosition = new Vector2(t_ammo.GetComponent <SpriteRenderer>().bounds.size.x * 1.5f, 0); m_infinitysign = Instantiate(AssetManager.m_Instance.GetPrefab("InfinitySign")).GetComponent <Infinity>(); m_infinitysign.transform.SetParent(m_ammunition[0].transform); m_infinitysign.transform.localScale = new Vector3(1, 1); m_infinitysign.transform.localScale *= m_ammunition[0].GetComponent <SpriteRenderer>().bounds.size.y / m_infinitysign.GetComponent <SpriteRenderer>().bounds.size.y; m_infinitysign.transform.localPosition = new Vector2(t_ammo.GetComponent <SpriteRenderer>().bounds.size.x + m_infinitysign.GetComponent <SpriteRenderer>().bounds.size.x / 2f, 0); }
public int GetHashCode(double d) { if (Infinity.IsInfinite(d)) { return(double.PositiveInfinity.GetHashCode()); } double inverse = 1 / m_tolerance; int decimals = (int)Math.Log10(inverse); return(Math.Round(d, decimals).GetHashCode()); }
public void addWeaponAmmo(int num) { if (currentWeapon.AmmoCount != Infinity.InfinityValue()) { currentWeapon.AmmoCount += num; if (parentGame != null) { parentGame.PlayerUpdateAmmoCount(playerNumber, currentWeapon.AmmoCount); } } }
// https://plus.google.com/u/0/117663015413546257905/posts/BnCEkdNiTZ2 public static void TwinDodecs() { Tiling tiling = new Tiling(); TilingConfig config = new TilingConfig(5, 3); tiling.GenerateInternal(config, Polytope.Projection.VertexCentered); // Vertex-centered makes infinities tricky Dodec dodec = new Dodec(); foreach (Tile tile in tiling.Tiles) { foreach (Segment seg in tile.Boundary.Segments) { Vector3D p1 = seg.P1, p2 = seg.P2; if (Infinity.IsInfinite(p1)) { p1 = Infinity.InfinityVector; } if (Infinity.IsInfinite(p2)) { p2 = Infinity.InfinityVector; } dodec.Verts.Add(p1); dodec.Verts.Add(p2); dodec.Midpoints.Add(Halfway(p1, p2)); } } // Now recursively add more vertices. HashSet <Vector3D> allVerts = new HashSet <Vector3D>(); foreach (Vector3D v in dodec.Verts) { allVerts.Add(v); } RecurseTwins(allVerts, dodec, 0); using (StreamWriter sw = File.CreateText("dual_dodecs_points_sphere.pov")) { foreach (Vector3D vert in allVerts) { Vector3D onSphere = Sterographic.PlaneToSphereSafe(vert); sw.WriteLine(PovRay.Sphere(new Sphere() { Center = onSphere, Radius = 0.01 })); //if( !Infinity.IsInfinite( vert ) ) // sw.WriteLine( PovRay.Sphere( new Sphere() { Center = vert, Radius = 0.01 } ) ); } } }
/// <summary> /// Applies a Mobius transformation to a quaternion with a zero k component (handled as a vector). /// The complex Mobius coefficients are treated as quaternions with zero j,k values. /// This is also infinity safe. /// </summary> public Vector3D ApplyToQuaternion(Vector3D q) { if (Infinity.IsInfinite(q)) { return(ApplyToInfinite()); // Is this ok? } Vector3D a = Vector3D.FromComplex(A); Vector3D b = Vector3D.FromComplex(B); Vector3D c = Vector3D.FromComplex(C); Vector3D d = Vector3D.FromComplex(D); return(DivideQuat(MultQuat(a, q) + b, MultQuat(c, q) + d)); }
/*Functions To Alter ammo count */ public void removeWeaponAmmo(int num) { if (photonView.isMine) { if (currentWeapon.AmmoCount != Infinity.InfinityValue()) { currentWeapon.AmmoCount -= num; if (parentGame != null) { parentGame.PlayerUpdateAmmoCount(playerNumber, currentWeapon.AmmoCount); } } } }
/*Functions To Alter ammo count */ public void removeWeaponAmmo(int num) { if (currentWeapon.AmmoCount != Infinity.InfinityValue()) { currentWeapon.AmmoCount -= num; if (currentWeapon.AmmoCount == 0) { currentWeapon = new Weapon(); } if (parentGame != null) { parentGame.PlayerUpdateAmmoCount(playerNumber, currentWeapon.AmmoCount); } } }
public Vector3D ApplyInfiniteSafe(Vector3D z) { if (Infinity.IsInfinite(z)) { return(ApplyToInfinite()); } Vector3D result = Apply(z); if (Infinity.IsInfinite(result)) { return(Infinity.InfinityVector); } return(result); }
void ClearAmmo() { int t_ammocount = m_ammunition.Count; for (int i = 0; i < t_ammocount; i++) { Destroy(m_ammunition[0].gameObject); m_ammunition.RemoveAt(0); } if (m_infinitysign != null) { Destroy(m_infinitysign.gameObject); m_infinitysign = null; } }
public static void Run() { Zero.Check("Zero == 0.", value => value == 0); One.Check("One == 1.", value => value == 1); Letter.Check("Letter is letter.", char.IsLetter); Digit.Check("Digit is digit.", char.IsDigit); ASCII.Check("ASCII is ascii.", value => value < 128); Letter.String(Range(100)).Check("String(Letter) is letter.", value => value.Length <= 100 && value.All(char.IsLetter)); Digit.String(Range(100)).Check("String(Digit) is digit.", value => value.Length <= 100 && value.All(char.IsDigit)); ASCII.String(Range(100)).Check("String(ASCII) is ascii.", value => value.Length <= 100 && value.All(value => value < 128)); Infinity.Check("Infinity is infinity.", float.IsInfinity); String(Range(100)).Bind(value => Constant(value).Map(constant => (value, constant))).Check("Constant is constant.", pair => pair.value == pair.constant); Enumeration().Check("Enumeration is enum.", value => value is Enum); All(Zero).Check("All(1) produces arrays of length 1.", values => values.Length == 1 && values.All(value => value == 0)); All(Zero, Zero).Check("All(2) produces arrays of length 2.", values => values.Length == 2 && values.All(value => value == 0)); All(Zero, Zero, Zero).Check("All(3) produces arrays of length 3.", values => values.Length == 3 && values.All(value => value == 0)); Zero.Map(Constant).Repeat(Range(100)).Bind(constants => All(constants).Map(values => (values, constants))) .Check("All(x) produces arrays of length x.", pair => pair.values.Length == pair.constants.Length); Any(Zero, One).Check("Any(Zero, One) chooses from its inputs.", value => value == 0 || value == 1); Any(0, 1).Repeat(100).Check("Any(0, 1).Repeat produces both values.", values => values.Contains(0) && values.Contains(1)); Range(-10, 10).Check("Range(-10, 10) is in range.", value => value >= -10 && value <= 10); Range('a', 'z').Check("Range('a', 'z') is in range.", value => value >= 'a' && value <= 'z'); Range(-1f, 1f).Check("Range(-1f, 1f) is in range.", value => value >= -1f && value <= 1f); Zero.Repeat(Range(100)).Check("Repeat(100) is in range.", values => values.Length <= 100); Integer.Filter(value => value % 2 == 0).Check("Filter filters for even numbers.", value => value % 2 == 0); Rational.Filter(value => value >= 0f).Check("Filter filters for positive numbers.", value => value >= 0f); Types.Concrete.Factory().Check("Factory produces non-null values.", value => value is not null); Types.Abstract.Check("Types.Abstract is abstract.", type => type.IsAbstract); Types.Interface.Check("Types.Interface is interface.", type => type.IsInterface); Types.Reference.Check("Types.Reference is class.", type => type.IsClass); Types.Value.Check("Types.Value is value type.", type => type.IsValueType); Types.Array.Check("Types.Array is array.", type => type.IsArray); Types.Pointer.Check("Types.Pointer is pointer.", type => type.IsPointer); Types.Primitive.Check("Types.Primitive is primitive.", type => type.IsPrimitive); Types.Enumeration.Check("Types.Enumeration is enum.", type => type.IsEnum); Types.Flags.Check("Types.Flags is flags.", type => type.IsEnum && type.IsDefined(typeof(FlagsAttribute), true)); Types.Default.Check("Types.Default has default constructor.", type => Activator.CreateInstance(type)?.GetType() == type); Types.Definition.Check("Types.Definition is generic type definition.", type => type.IsGenericTypeDefinition); Types.Definition.Make().Check("Types.Definition is constructed generic type.", type => type.IsConstructedGenericType); Types.Enumeration.Bind(type => Enumeration(type).Map(value => (type, value))) .Check("Enumeration(type) produces values of the same type.", pair => pair.type == pair.value.GetType()); Types.Type.Bind(type => Types.Derived(type).Map(derived => (derived, type))) .Check("Types.Derived is derived.", pair => pair.derived.Is(pair.type)); }
public void ChangeAmmoCount(int number, int textNumber) { if (!(textNumber == Infinity.InfinityValue())) { if (number < 100) { playersInfoUI[number].ChangeAmmoCount(textNumber.ToString(), defaultTextFontSize); } else { Debug.Log("Ammo text is too large"); } } else { playersInfoUI[number].ChangeAmmoCount("∞", largerTextFontSize); } }
void Start() { FindComponent(); if (ISILocalization.LoadIfNotInScene()) { Infinity.When(() => ISILocalization.IsInitialized, _OnLanguageChanged); } if (LocalizedStrings == null) { LocalizedStrings = new List <LocalizedString>(); } if (!LocalizedStrings.Contains(this)) { LocalizedStrings.Add(this); } }
private static void ProjectAndSave(List <Circle3D> circlesOnUnitSphere) { List <Circle3D> projected = new List <Circle3D>(); foreach (Circle3D c in circlesOnUnitSphere) { Vector3D[] pp = c.RepresentativePoints.Select(p => Sterographic.SphereToPlane(p)).ToArray(); Circle3D cProj = new Circle3D(pp[0], pp[1], pp[2]); if (Infinity.IsInfinite(cProj.Radius)) { continue; } cProj.Color = c.Color; projected.Add(cProj); } SaveToBmp(projected); }
void Start() { if (type == SpriteComponentType.Image) { image = GetComponent <Image>(); if (image == null) { Debugger.LogError("There is no Image component attached to this GameObject", gameObject); return; } } else { spriteRenderer = GetComponent <SpriteRenderer>(); if (spriteRenderer == null) { Debugger.LogError("There is no SpriteRenderer component attached to this GameObject", gameObject); return; } } if (ISILocalization.LoadIfNotInScene()) { Infinity.When(() => ISILocalization.IsInitialized, _OnLanguageChanged); } if (LocalizedSprites == null) { LocalizedSprites = new List <LocalizedSprite>(); } if (!LocalizedSprites.Contains(this)) { LocalizedSprites.Add(this); } }
private IEnumerator ScenarioExecution() { switch (step) { case Step.Attraction: { if (OrbitController.Instance != null) { OrbitController.Instance.Apply(p.camView); } yield return(null); break; } case Step.AttractionUpDown: { m_AttractionUpDownCoroutine = StartCoroutine(AttractionUpDownCoroutine()); step = Step.Idle; parallel = Parallel.LerpToSeparation; break; } case Step.SettleCohesion: { Tween.DestroyAll(flock.originTarget.gameObject); //Scene_Camera.Instance.SmoothLookAt ( flock.originTarget, 2f, false ); flock.TransitionToPreset(p.fishSchool1Preset, p.fishSchool1TransitionDuration); ConvertBoidsToTemplate(p.fish1Template, p.fishSchool1TransitionDuration); float transitionDuration = p.fishSchool1TransitionDuration * .5f; IEnumerator transition = GenericPresetsUtil.TransitionFromToCoroutine( null, p.underwaterOn, p.underwaterMaterial, transitionDuration, null, null ); StartCoroutine(transition); IEnumerator transitionBkg = GenericPresetsUtil.TransitionFromToCoroutine( null, p.backgroundWater, p.backgroundMaterial, transitionDuration, null, null ); StartCoroutine(transitionBkg); step = Step.Idle; parallel = Parallel.Idle; break; } case Step.School2: { if (m_AttractionUpDownCoroutine != null) { StopCoroutine(m_AttractionUpDownCoroutine); } flock.TransitionToPreset(p.fishSchool2Preset, p.fishSchool2TransitionDuration); flock.CreateBoidsOverDuration(p.additionalSchool2Pattern, p.fishSchool2TransitionDuration); Infinity.Apply(flock.originTarget.gameObject, 10f, 6f, .01f); step = Step.Idle; break; } case Step.Birds: { Infinity.Remove(flock.originTarget.gameObject); StartCoroutine(flock.RandomOriginFromBoidsCoroutine(1f)); OrbitController.Instance.orbitTarget = flock.originTarget; OrbitController.Instance.rotationalDamping *= .2f; flock.TransitionToPreset(p.birdsFlock1Preset, p.birdsFlock1TransitionDuration); ConvertBoidsToTemplate(p.birds1Template, p.birdsFlock1TransitionDuration); flock.CreateBoidsOverDuration(p.additionalSchool2Pattern, p.birdsFlock1TransitionDuration); float transitionDuration = p.birdsFlock1TransitionDuration * .5f; IEnumerator transition = GenericPresetsUtil.TransitionFromToCoroutine( null, p.skySunset, p.underwaterMaterial, transitionDuration, null, null ); StartCoroutine(transition); IEnumerator transitionBkg = GenericPresetsUtil.TransitionFromToCoroutine( null, p.backgroundSkySunset, p.backgroundMaterial, transitionDuration, null, null ); StartCoroutine(transitionBkg); step = Step.Idle; break; } case Step.Exit: { Director.Instance.LoadNextScene(); break; } } }
// CHEAT! (would be better to do a geometrical construction) // We are going to iterate to the starting point that will make all edge lengths the same. public static Vector3D IterateToStartingPoint(HoneycombDef?def, int[] activeMirrors, Simplex simplex) { if (activeMirrors.Length == 1) { return(simplex.Verts[activeMirrors[0]]); } // We are minimizing the output of this function, // because we want all edge lengths to be as close as possible. // Input vector should be in the Ball Model. Func <Vector3D, double> diffFunc = v => { List <double> lengths = new List <double>(); for (int i = 0; i < activeMirrors.Length; i++) { Vector3D reflected = simplex.ReflectInFacet(v, activeMirrors[i]); lengths.Add(H3Models.Ball.HDist(v, reflected)); } double result = 0; double average = lengths.Average(); foreach (double length in lengths) { result += Math.Abs(length - average); } if (Infinity.IsInfinite(result)) { result = double.PositiveInfinity; } return(result); }; // So that we can leverage Euclidean barycentric coordinates, we will first convert our simplex to the Klein model. // We will need to take care to properly convert back to the Ball as needed. Vector3D[] kleinVerts = simplex.Verts.Select(v => HyperbolicModels.PoincareToKlein(v)).ToArray(); if (def != null) { HoneycombDef d = def.Value; Geometry vertexGeometry = Geometry2D.GetGeometry(d.Q, d.R); if (vertexGeometry == Geometry.Hyperbolic) { kleinVerts[3] = SimplexCalcs.VertexPointKlein(d.P, d.Q, d.R); } } // Normalizing barycentric coords amounts to making sure the 4 coords add to 1. Func <Vector3D, Vector3D> baryNormalize = b => { return(b / (b.X + b.Y + b.Z + b.W)); }; // Bary Coords to Euclidean Func <Vector3D[], Vector3D, Vector3D> baryToEuclidean = (kv, b) => { Vector3D result = kv[0] * b.X + kv[1] * b.Y + kv[2] * b.Z + kv[3] * b.W; return(result); }; // Our starting barycentric coords (halfway between all active mirrors). Vector3D bary = new Vector3D(); foreach (int a in activeMirrors) { bary[a] = 0.5; } bary = baryNormalize(bary); // For each iteration, we'll shrink this search offset. // NOTE: The starting offset and decrease factor I'm using don't guarantee convergence, // but it seems to be working pretty well (even when varying these parameters). //double searchOffset = 1.0 - bary[activeMirrors[0]]; //double searchOffset = bary[activeMirrors[0]]; double factor = 1.5; // Adjusting this helps get some to converge, e.g. 4353-1111 double searchOffset = bary[activeMirrors[0]] / factor; double min = double.MaxValue; int iterations = 1000; for (int i = 0; i < iterations; i++) { min = diffFunc(HyperbolicModels.KleinToPoincare(baryToEuclidean(kleinVerts, bary))); foreach (int a in activeMirrors) { Vector3D baryTest1 = bary, baryTest2 = bary; baryTest1[a] += searchOffset; baryTest2[a] -= searchOffset; baryTest1 = baryNormalize(baryTest1); baryTest2 = baryNormalize(baryTest2); double t1 = diffFunc(HyperbolicModels.KleinToPoincare(baryToEuclidean(kleinVerts, baryTest1))); double t2 = diffFunc(HyperbolicModels.KleinToPoincare(baryToEuclidean(kleinVerts, baryTest2))); if (t1 < min) { min = t1; bary = baryTest1; } if (t2 < min) { min = t2; bary = baryTest2; } } if (Tolerance.Equal(min, 0.0, 1e-14)) { System.Console.WriteLine(string.Format("Converged in {0} iterations.", i)); break; } searchOffset /= factor; } if (!Tolerance.Equal(min, 0.0, 1e-14)) { System.Console.WriteLine("Did not converge: " + min); // Be a little looser before thrown an exception. if (!Tolerance.Equal(min, 0.0, 1e-12)) { System.Console.ReadKey(true); //throw new System.Exception( "Boo. We did not converge." ); return(Vector3D.DneVector()); } } Vector3D euclidean = baryToEuclidean(kleinVerts, bary); return(HyperbolicModels.KleinToPoincare(euclidean)); }
public static Texture2D ColorToTex(string hexcol, int width, int height) { return(ColorToTex(Infinity.HexToColor(hexcol), width, height)); }