/// <summary> /// Pass mouse move to appropriate item /// </summary> /// <param name="e"></param> public override bool OnMouseMove(VCItem sender, ItemMouseEventArgs e) { var pt = e.Location; if (resizing) { var rect = CalcResizedBounds(startBounds, startMousePt, LimitMoveToPosition(pt), startSide); Resize(activePlacement, rect); container.Invalidate(); return(true); } else if (e.Button == MouseButtons.None) { VCItemPlacement placement = Find(pt, null); // Can placement be resized? if ((placement != null) && (placement != activePlacement) && !CanResize(placement)) { // No, it cannot be resized placement = null; } HitSide hitSide = HitSide.None; if ((placement != null) || (activePlacement != null)) { hitSide = CalcHitSide(placement, pt); if (hitSide != HitSide.None) { e.Cursor = GetCursor(hitSide); } } if (activePlacement != placement) { activePlacement = placement; container.Invalidate(); } if (hitSide != HitSide.None) { return(true); } } return(base.OnMouseMove(sender, e)); }
public override TradingOperationResult PlaceOrder(PlaceOrderRequestParameters parameters) { var result = new TradingOperationResult(); string symbol = parameters.Symbol.Id; HitSide side = parameters.Side == Side.Buy ? HitSide.Buy : HitSide.Sell; decimal quantity = (decimal)parameters.Quantity; decimal price = -1; decimal stopPrice = -1; if (parameters.OrderTypeId == OrderType.Limit || parameters.OrderTypeId == OrderType.StopLimit) { price = (decimal)parameters.Price; } if (parameters.OrderTypeId == OrderType.Stop || parameters.OrderTypeId == OrderType.StopLimit) { stopPrice = (decimal)parameters.TriggerPrice; } HitTimeInForce timeInForce = this.ConvertTimeInForce(parameters.TimeInForce); DateTime expireTime = default; if (timeInForce == HitTimeInForce.GTD) { expireTime = parameters.ExpirationTime; } var response = this.CheckHitResponse(this.socketApi.PlaceNewOrderAsync(symbol, side, quantity, price, stopPrice, timeInForce, expireTime, cancellationToken: parameters.CancellationToken).Result, out var error, true); if (response != null) { result.Status = TradingOperationResultStatus.Success; result.OrderId = response.ClientOrderId; } else { result.Status = TradingOperationResultStatus.Failure; result.Message = error?.ToString() ?? "Unknown error"; } return(result); }
/// <summary> /// Pass mouse down to appropriate item /// </summary> /// <param name="e"></param> public override bool OnMouseDown(VCItem sender, ItemMouseEventArgs e) { var pt = e.Location; var placement = Find(pt, null); // Can placement be resized? if ((placement != null) && (placement != activePlacement) && !CanResize(placement)) { // No, it cannot be resized placement = null; } HitSide side = HitSide.None; if (placement != null) { side = CalcHitSide(placement, pt); if (side == HitSide.None) { placement = null; } } if (placement != null) { activePlacement = placement; startBounds = placement.Bounds; startMousePt = pt; startSide = side; resizing = true; container.Invalidate(); return(true); } else { // Pass event on return(base.OnMouseDown(sender, e)); } }
/// <summary> /// Gets the cursor for a given side. /// </summary> /// <param name="side"></param> /// <returns></returns> private static Cursor GetCursor(HitSide side) { switch (side) { case HitSide.Top: case HitSide.Bottom: return(Cursors.SizeNS); case HitSide.Left: case HitSide.Right: return(Cursors.SizeWE); case (HitSide.Top | HitSide.Left): case HitSide.Bottom | HitSide.Right: return(Cursors.SizeNWSE); case HitSide.Top | HitSide.Right: case HitSide.Bottom | HitSide.Left: return(Cursors.SizeNESW); default: return(Cursors.Default); } }
/// <summary> /// Place new order /// </summary> /// <param name="symbol">Trading symbol</param> /// <param name="side">sell buy</param> /// <param name="quantity">Order quantity</param> /// <param name="price">Order price. Required for limit types.</param> /// <param name="stopPrice">Required for stop types.</param> /// <param name="timeInForce">Optional. Default - GDC. One of: GTC, IOC, FOK, Day, GTD</param> /// <param name="expireTime">Required for GTD timeInForce.</param> /// <param name="clientOrderId">Optional parameter, if skipped - will be generated by server. Uniqueness must be guaranteed within a single trading day, including all active orders.</param> /// <param name="strictValidate">Price and quantity will be checked that they increment within tick size and quantity step. See symbol tickSize and quantityIncrement</param> /// <param name="cancellationToken">Token for cancel operation</param> /// <returns></returns> public async Task <HitResponse <HitOrder> > CreateNewOrderAsync(string symbol, HitSide side, decimal quantity, decimal price = -1, decimal stopPrice = -1, HitTimeInForce timeInForce = HitTimeInForce.Day, DateTime expireTime = default, string clientOrderId = null, bool strictValidate = true, CancellationToken cancellationToken = default) { HitOrderType orderType = HitOrderType.Market; if (price != -1 && stopPrice == -1) { orderType = HitOrderType.Limit; } else if (price == -1 && stopPrice != -1) { orderType = HitOrderType.StopMarket; } else if (price != -1 && stopPrice != -1) { orderType = HitOrderType.StopLimit; } var parameters = new HitNewOrderParameters { ClientOrderId = clientOrderId, Symbol = symbol, Side = side, OrderType = orderType, TimeInForce = timeInForce, Quantity = quantity, Price = price, StopPrice = stopPrice, ExpireTime = expireTime, StrictValidate = strictValidate }; return(await this.MakeRequestAuthorizedAsync <HitOrder>(HttpMethod.Post, cancellationToken, "order", postParameters : parameters)); }
public void SetHitSide(HitSide side) { hitSide = side; }
public override bool FindIntersection(Ray ray, out Intersection intersect) { intersect = new Intersection(); float maxFrontDist = float.NegativeInfinity; float minBackDist = float.PositiveInfinity; HitSide frontType = HitSide.None, backType = HitSide.None; // 0, 1 = base, side float viewPosdotCtr = ray.Origin * this.centralAxis; float udotuCtr = ray.Direction * this.centralAxis; if (viewPosdotCtr > (this.apexDotCenterAxis) && udotuCtr >= 0.0f) { return(false); // Above the cone's apex } // Start with the bounding base plane float pdotnCap = this.baseNormal * ray.Origin; float udotnCap = this.baseNormal * ray.Direction; if (pdotnCap > this.coefBasePlane) { if (udotnCap >= 0.0f) { return(false); // Above (=outside) base plane, pointing away } maxFrontDist = (this.coefBasePlane - pdotnCap) / udotnCap; frontType = HitSide.BottomPlane; } else if (pdotnCap < this.coefBasePlane) { if (udotnCap > 0.0f) { // Below (=inside) base plane, pointing towards the plane minBackDist = (this.coefBasePlane - pdotnCap) / udotnCap; backType = HitSide.BottomPlane; } } // Now handle the cone's sides Vector3D v = ray.Origin - this.apex; float pdotuCtr = v * this.centralAxis; float pdotuA = v * this.axisA; float pdotuB = v * this.axisB; // udotuCtr already defined above float udotuA = ray.Direction * this.axisA; float udotuB = ray.Direction * this.axisB; float C = pdotuA * pdotuA + pdotuB * pdotuB - pdotuCtr * pdotuCtr; float B = (pdotuA * udotuA + pdotuB * udotuB - pdotuCtr * udotuCtr); B += B; float A = udotuA * udotuA + udotuB * udotuB - udotuCtr * udotuCtr; float alpha1, alpha2; // The roots, in order int numRoots = EquationSolver.SolveQuadric(A, B, C, out alpha1, out alpha2); if (numRoots == 0) { return(false); // No intersection } bool viewMoreVertical = (A < 0.0f); if (viewMoreVertical) { // View line leaves and then enters the cone if (alpha1 < minBackDist && pdotuCtr + alpha1 * udotuCtr <= 0.0f) { if (alpha1 < maxFrontDist) { return(false); } minBackDist = alpha1; backType = HitSide.Cone; } else if (numRoots == 2 && alpha2 > maxFrontDist && pdotuCtr + alpha2 * udotuCtr <= 0.0f) { if (alpha2 > minBackDist) { return(false); } maxFrontDist = alpha2; frontType = HitSide.Cone; } } else { // view line enters and then leaves if (alpha1 > maxFrontDist) { if (pdotuCtr + alpha1 * udotuCtr > 0.0f) { return(false); // Enters dual cone instead } if (alpha1 > minBackDist) { return(false); } maxFrontDist = alpha1; frontType = HitSide.Cone; } if (numRoots == 2 && alpha2 < minBackDist) { if (pdotuCtr + alpha2 * udotuCtr > 0.0f) { return(false); // Is leaving dual cone instead } if (alpha2 < maxFrontDist) { return(false); } minBackDist = alpha2; backType = HitSide.Cone; } } // Put it all together: float alpha; HitSide hitSurface = HitSide.None; if (maxFrontDist > 0.0f) { alpha = maxFrontDist; hitSurface = frontType; } else { alpha = minBackDist; hitSurface = backType; } if (alpha < 0.0) { return(false); } intersect.TMin = alpha; // Set v to the intersection point intersect.HitPoint = ray.Origin + intersect.TMin * ray.Direction; intersect.HitPrimitive = this; // Now set v equal to returned position relative to the apex v = intersect.HitPoint - this.apex; float vdotuA = v * this.axisA; float vdotuB = v * this.axisB; float vdotuCtr = v * this.centralAxis; switch (hitSurface) { case HitSide.BottomPlane: // Base face intersect.Normal = this.baseNormal; if (this.material != null && this.material.IsTexturized) { // Calculate U-V values for texture coordinates vdotuA /= vdotuCtr; // vdotuCtr is negative vdotuB /= vdotuCtr; vdotuA = 0.5f * (1.0f - vdotuA); vdotuB = 0.5f * (1.0f - vdotuB); //int widthTex = this.material.Texture.Width - 1; //int heightTex = this.material.Texture.Height - 1; //this.material.Color = // this.material.Texture.GetPixel((int)(vdotuB * widthTex), (int)(vdotuA * heightTex)); intersect.CurrentTextureCoordinate.U = vdotuB; intersect.CurrentTextureCoordinate.V = vdotuA; } break; case HitSide.Cone: // Cone's side intersect.Normal = vdotuA * this.axisA; intersect.Normal += vdotuB * this.axisB; intersect.Normal -= vdotuCtr * this.centralAxis; intersect.Normal.Normalize(); if (this.material != null && this.material.IsTexturized) { // Calculate u-v coordinates for texture mapping (in range[0,1]x[0,1]) float uCoord = (float)(Math.Atan2(vdotuB, vdotuA) / (Math.PI + Math.PI) + 0.5); float vCoord = (vdotuCtr + this.height) / this.height; //int widthTex = this.material.Texture.Width - 1; //int heightTex = this.material.Texture.Height - 1; //this.material.Color = // this.material.Texture.GetPixel((int)(uCoord * widthTex), (int)(vCoord * heightTex)); intersect.CurrentTextureCoordinate.U = uCoord; intersect.CurrentTextureCoordinate.V = vCoord; } break; } return(true); }
/// <summary> /// Calculate a resized bounds /// </summary> /// <param name="startBounds">Start bounds of the placement</param> /// <param name="startPt">Start mouse point</param> /// <param name="curPt">Current mouse point</param> /// <param name="side">Starting hit side</param> /// <returns></returns> private Rectangle CalcResizedBounds(Rectangle startBounds, PointF startPt, PointF curPt, HitSide side) { var dx = (int)(curPt.X - startPt.X); var dy = (int)(curPt.Y - startPt.Y); var x = startBounds.X; var y = startBounds.Y; var width = startBounds.Width; var height = startBounds.Height; var origDy = dy; if ((side & HitSide.Top) != 0) { Point pt = SnapPoint(new Point(x, y + Math.Min(dy, height))); dy = Math.Min(pt.Y - y, height); y += dy; height -= dy; } if ((side & HitSide.Bottom) != 0) { Point pt = SnapPoint(new Point(x, y + height + Math.Max(dy, -height))); dy = Math.Max(pt.Y - (y + height), -height); height += dy; } if ((side & HitSide.Left) != 0) { Point pt = SnapPoint(new Point(x + Math.Min(dx, width), y)); dx = Math.Min(pt.X - x, width); x += dx; width -= dx; } if ((side & HitSide.Right) != 0) { Point pt = SnapPoint(new Point(x + width + Math.Max(dx, -width), y)); dx = Math.Max(pt.X - (x + width), -width); width += dx; } return(new Rectangle(x, y, width, height)); }
public void DDA() { lineRenderer.SetPosition(0, new Vector3(startLaserPoint.x, startLaserPoint.y, -1)); Vector2 vRayStart = startDDAPoint; Vector2 vRayDir = startDirection.normalized; Vector2 vRayUnitStepSize = new Vector2(Mathf.Sqrt(1 + (vRayDir.y / vRayDir.x) * (vRayDir.y / vRayDir.x)), Mathf.Sqrt(1 + (vRayDir.x / vRayDir.y) * (vRayDir.x / vRayDir.y))); Vector2Int vMapCheck = new Vector2Int((int)(vRayStart.x + GridManager.v3TowerOffset.x), (int)(vRayStart.y + GridManager.v3TowerOffset.y)); Vector2 vRayLength1D; Vector2Int vStep = new Vector2Int(); Vector2Int vPrevMapCheck = vMapCheck; if (vRayDir.x < 0) { vStep.x = -1; vRayLength1D.x = (vRayStart.x - (float)vMapCheck.x) * vRayUnitStepSize.x; } else { vStep.x = 1; vRayLength1D.x = ((float)(vMapCheck.x + 1) - vRayStart.x) * vRayUnitStepSize.x; } if (vRayDir.y < 0) { vStep.y = -1; vRayLength1D.y = (vRayStart.y - (float)vMapCheck.y) * vRayUnitStepSize.y; } else { vStep.y = 1; vRayLength1D.y = ((float)(vMapCheck.y + 1) - vRayStart.y) * vRayUnitStepSize.y; } bool bTileFound = false; float fMaxDistance = 10000.0f; float fDistance = 0.0f; while (!bTileFound && fDistance < fMaxDistance) { if (debugColor != Color.white) { GameManager.instance.GetGridManager().GetGridTile(vPrevMapCheck).background.GetComponent <MeshRenderer>().material.color = debugColor; GameManager.instance.GetGridManager().GetGridTile(vMapCheck).background.GetComponent <MeshRenderer>().material.color = Color.red; } else { GameManager.instance.GetGridManager().GetGridTile(vPrevMapCheck).background.GetComponent <MeshRenderer>().material.color = debugColor; GameManager.instance.GetGridManager().GetGridTile(vMapCheck).background.GetComponent <MeshRenderer>().material.color = Color.red; } if (vMapCheck.x >= 0 && vMapCheck.x < GameManager.instance.GetGridManager().GetGridDimensions().x&& vMapCheck.y >= 0 && vMapCheck.y < GameManager.instance.GetGridManager().GetGridDimensions().y) { if (!GameManager.instance.GetGridManager().IsTileAvailable(vMapCheck.x, vMapCheck.y)) { bTileFound = true; } } Vector2 vIntersection; if (bTileFound) { vIntersection = vRayStart + vRayDir * fDistance; HitSide hitSide = GameManager.instance.GetGridManager().GetTower(vMapCheck.x, vMapCheck.y).FindHitSide(vMapCheck, vPrevMapCheck); ELocalHitSide localHitSide = GameManager.instance.GetGridManager().GetTower(vMapCheck.x, vMapCheck.y).FindLocalHitSide(hitSide, vMapCheck); switch (hitSide) { case HitSide.TOP: lineRenderer.SetPosition(1, GameManager.instance.GetGridManager().GetGridTile(vMapCheck).currentTowerMesh.transform.position + Vector3.up * 0.5f); break; case HitSide.RIGHT: lineRenderer.SetPosition(1, GameManager.instance.GetGridManager().GetGridTile(vMapCheck).currentTowerMesh.transform.position + Vector3.right * 0.5f); break; case HitSide.BOTTOM: lineRenderer.SetPosition(1, GameManager.instance.GetGridManager().GetGridTile(vMapCheck).currentTowerMesh.transform.position + Vector3.down * 0.5f); break; case HitSide.LEFT: lineRenderer.SetPosition(1, GameManager.instance.GetGridManager().GetGridTile(vMapCheck).currentTowerMesh.transform.position + Vector3.left * 0.5f); break; default: break; } if (GameManager.instance.GetGridManager().GetTower(vMapCheck.x, vMapCheck.y)) { if (GameManager.instance.GetGridManager().GetGridTile(vMapCheck).currentTowerMesh.transform != transform.parent) { if (GameManager.instance.GetGridManager().GetTower(vMapCheck.x, vMapCheck.y).GetBehaviours().Length > 0) { foreach (TowerBehaviour behaviour in GameManager.instance.GetGridManager().GetGridTile(vMapCheck.x, vMapCheck.y).currentTowerMesh.GetComponents <TowerBehaviour>()) { behaviour.SetInLaser(this); behaviour.SetHitSide(hitSide); behaviour.SetLocalHitSide(localHitSide); behaviour.OnLaserHit(vRayDir, vMapCheck); } } } else { bTileFound = false; } } } vPrevMapCheck = vMapCheck; if (vRayLength1D.x < vRayLength1D.y) { vMapCheck.x += vStep.x; fDistance = vRayLength1D.x; vRayLength1D.x += vRayUnitStepSize.x; } else { vMapCheck.y += vStep.y; fDistance = vRayLength1D.y; vRayLength1D.y += vRayUnitStepSize.y; } } }
public ELocalHitSide FindLocalHitSide(HitSide hitSide, Vector2 position) { float dot_vert = Vector3.Dot(GameManager.instance.GetGridManager().GetGridTile(position).currentTowerMesh.transform.forward, Vector3.up); float dot_horz = Vector3.Dot(GameManager.instance.GetGridManager().GetGridTile(position).currentTowerMesh.transform.forward, Vector3.right); //Debug.Log("dot_vert : " + dot_vert); //Debug.Log("dot_horz : " + dot_horz); //Debug.Log(hitSide); if (dot_vert > 0) { switch (hitSide) { case HitSide.TOP: return(ELocalHitSide.TOP); case HitSide.RIGHT: return(ELocalHitSide.RIGHT); case HitSide.BOTTOM: return(ELocalHitSide.BOTTOM); case HitSide.LEFT: return(ELocalHitSide.LEFT); default: break; } } else { if (dot_vert < 0) { switch (hitSide) { case HitSide.TOP: return(ELocalHitSide.BOTTOM); case HitSide.RIGHT: return(ELocalHitSide.LEFT); case HitSide.BOTTOM: return(ELocalHitSide.TOP); case HitSide.LEFT: return(ELocalHitSide.RIGHT); default: break; } } else { if (dot_horz > 0) { switch (hitSide) { case HitSide.TOP: return(ELocalHitSide.LEFT); case HitSide.RIGHT: return(ELocalHitSide.TOP); case HitSide.BOTTOM: return(ELocalHitSide.RIGHT); case HitSide.LEFT: return(ELocalHitSide.BOTTOM); default: break; } } else { switch (hitSide) { case HitSide.TOP: return(ELocalHitSide.RIGHT); case HitSide.RIGHT: return(ELocalHitSide.BOTTOM); case HitSide.BOTTOM: return(ELocalHitSide.LEFT); case HitSide.LEFT: return(ELocalHitSide.TOP); default: break; } } } } return(ELocalHitSide.BOTTOM); }