def PlotDashLine(self): dashSize = 2.0 gapSize = 7.0 r, g, b = self.GetRGB() DASHCOLOR = (r, g, b, 1.0) GAPCOLOR = (r, g, b, 0.0) MARGIN = 16.0 * self.localScale vecDir = geo2.Vec2Subtract(self.toPosition, self.fromPosition) vecLength = geo2.Vec2Length(vecDir) vecDirNorm = geo2.Vec2Normalize(vecDir) p = MARGIN while p < vecLength - MARGIN: startPoint = geo2.Vec2Add(self.fromPosition, geo2.Vec2Scale(vecDirNorm, p - 0.5)) self.AddPoint(startPoint, GAPCOLOR) fromPoint = geo2.Vec2Add(self.fromPosition, geo2.Vec2Scale(vecDirNorm, p)) self.AddPoint(fromPoint, DASHCOLOR) p = min(vecLength - MARGIN, dashSize + p) toPoint = geo2.Vec2Add(self.fromPosition, geo2.Vec2Scale(vecDirNorm, p)) self.AddPoint(toPoint, DASHCOLOR) endPoint = geo2.Vec2Add(self.fromPosition, geo2.Vec2Scale(vecDirNorm, p + 0.5)) self.AddPoint(endPoint, GAPCOLOR) p += gapSize
def ConstructLines(self): for line in self.lines: line.Close() self.lines = [] usedRows = int(ceil(len(self.materialsData) / float(self.perRow))) pointsStart = self.GetLineStartingPoints() pConnect = self.GetLineConnectionPoint(pointsStart) y = self.top + self.materialsCont.top + self.materialsCont.height / 2 x = self.GetLineCirceOffset(y) width, height = self.parent.GetCurrentAbsoluteSize() self.pCircleIntersect = (width / 2 - x, pConnect[1]) pEnd = geo2.Vec2Subtract(self.pCircleIntersect, (1 * RADIUS_CONNECTOR_SMALL, 0)) if len(pointsStart) == 1: self.DrawLine((pointsStart[0], pEnd)) else: for point in pointsStart: if point[1] == pEnd[1]: self.DrawLine((point, geo2.Vec2Subtract(pConnect, (3, 0)))) else: self.DrawLine((point, (pConnect[0], point[1]), pConnect)) self.DrawLine((geo2.Vec2Add(pConnect, (3, 0)), pEnd)) if not self.connectorCircle: self.connectorCircle = MaterialGroupDashedCircle( parent=self.materialsCont, numSegments=len(self.materialsData), radius=RADIUS_CONNECTOR_SMALL, materialsByGroupID=((self.industryGroupID, self.materialsData), ), jobData=self.jobData) self.connectorCircle.left = pEnd[0] self.connectorCircle.top = pEnd[1] - RADIUS_CONNECTOR_SMALL self.UpdateState(animate=False)
def PlotLineTrace(self): self.Flush() if self.glowLine: self.glowLine.Flush() if self.lineType in (LINE_DASHED, LINE_DASHED_ACTIVE): self.PlotDashLine() elif self.lineType == LINE_SOLID: self.PlotSolidLine() else: return if self.lineType == LINE_DASHED_ACTIVE: vecDir = geo2.Vec2Subtract(self.toPosition, self.fromPosition) vecLength = geo2.Vec2Length(vecDir) vecDirNorm = geo2.Vec2Normalize(vecDir) r, g, b = self.GetRGB() GLOWCOLOR = (r, g, b, 1.0) GAPCOLOR = (r, g, b, 0.0) self.glowLine.AddPoint(self.fromPosition, GAPCOLOR) point = geo2.Vec2Add(self.fromPosition, geo2.Vec2Scale(vecDirNorm, vecLength * 0.5)) self.glowLine.AddPoint(point, GLOWCOLOR) self.glowLine.AddPoint(self.toPosition, GAPCOLOR) self.glowLine.textureWidth = vecLength uicore.animations.MorphScalar(self.glowLine, 'textureOffset', startVal=0.0, endVal=1.0, curveType=uiconst.ANIM_LINEAR, duration=2.0, loops=uiconst.ANIM_REPEAT)
def Update(self, *args): t = blue.os.GetSimTime() if t == self.lastUpdateTime: return if sm.GetService('michelle').GetBall(self.itemID) is None: self.Close() return self.UpdateBoxPosition() bracketPos = self.GetContainerPosition(self.bracket) boxPos = self.GetContainerPosition(self.floatingBox) lineTo = self.GetLineConnectionPointOnBox(bracketPos, self.floatingBox) cornerPos = geo2.Vec2Add(boxPos, lineTo) vec = geo2.Vec2Subtract(bracketPos, cornerPos) length = geo2.Vec2Length(vec) vec = geo2.Scale(vec, (length - uicore.ScaleDpi(ICON_SIZE / 2)) / length) self.line.translationTo = geo2.Vec2Add(vec, lineTo) self.line.translationFrom = lineTo
def GetInnerCircleIntersectPoint(self, y): pCenter = self.GetPointCenter() y = pCenter[1] - y th = asin(y / industryUIConst.RADIUS_CENTERCIRCLE_OUTER) + pi r = industryUIConst.RADIUS_CENTERCIRCLE_INNER p = (r * cos(th), r * sin(th)) p = geo2.Vec2Add(p, pCenter) return (p, th)
def ApplyLineMargin(self, p1, p2, radius1, radius2): v = geo2.Vec2Subtract(p1, p2) vn = geo2.Vec2Normalize(v) l = geo2.Vec2Length(v) if not l: return (None, None) s = (radius1 + radius2) / l mp1 = geo2.Vec2Subtract(p1, geo2.Vec2Scale(vn, radius1)) mp2 = geo2.Vec2Add(p2, geo2.Vec2Scale(vn, radius2)) return (mp1, mp2)
def PlotSolidLine(self): r, g, b = self.GetRGB() DASHCOLOR = (r, g, b, 1.0) GAPCOLOR = (r, g, b, 0.0) MARGIN = 16.0 * self.localScale vecDir = geo2.Vec2Subtract(self.toPosition, self.fromPosition) vecLength = geo2.Vec2Length(vecDir) vecDirNorm = geo2.Vec2Normalize(vecDir) startPoint = geo2.Vec2Add(self.fromPosition, geo2.Vec2Scale(vecDirNorm, MARGIN)) self.AddPoint(startPoint, GAPCOLOR) startPoint = geo2.Vec2Add(self.fromPosition, geo2.Vec2Scale(vecDirNorm, MARGIN + 8)) self.AddPoint(startPoint, DASHCOLOR) startPoint = geo2.Vec2Add( self.fromPosition, geo2.Vec2Scale(vecDirNorm, vecLength - MARGIN - 8)) self.AddPoint(startPoint, DASHCOLOR) startPoint = geo2.Vec2Add( self.fromPosition, geo2.Vec2Scale(vecDirNorm, vecLength - MARGIN)) self.AddPoint(startPoint, GAPCOLOR)
def seg_intersect(line1, line2): a1, a2 = line1 b1, b2 = line2 da = geo2.Vec2Subtract(a2, a1) db = geo2.Vec2Subtract(b2, b1) dp = geo2.Vec2Subtract(a1, b1) dap = (-da[1], da[0]) denom = geo2.Vec2Dot(dap, db) if not denom: return False num = geo2.Vec2Dot(dap, dp) return geo2.Vec2Scale(geo2.Vec2Add(db, b1), num / denom)
def GetInnerCircleIntersectPoint(self, y): """ Returns inner circle intersection point and angle (in radians) of line coming from a group, given y-coordinate of that line """ pCenter = self.GetPointCenter() y = pCenter[1] - y th = asin(y / industryUIConst.RADIUS_CENTERCIRCLE_OUTER) + pi r = industryUIConst.RADIUS_CENTERCIRCLE_INNER p = (r * cos(th), r * sin(th)) p = geo2.Vec2Add(p, pCenter) return (p, th)
def closest_point_on_seg(seg_a, seg_b, circ_pos): seg_v = geo2.Vec2Subtract(seg_b, seg_a) pt_v = geo2.Vec2Subtract(circ_pos, seg_a) if geo2.Vec2Length(seg_v) <= 0: raise ValueError, 'Invalid segment length' seg_v_unit = geo2.Vec2Normalize(seg_v) proj = geo2.Vec2Dot(seg_v_unit, pt_v) if proj <= 0: return seg_a if proj >= geo2.Vec2Length(seg_v): return seg_b proj_v = geo2.Vec2Scale(seg_v_unit, proj) closest = geo2.Vec2Add(proj_v, seg_a) return closest
def UpdateState(self): tileFromData = self.tileFrom.tileData tileToData = self.tileTo.tileData if not tileFromData.IsFlippable() and not tileToData.IsFlippable(): colorFrom = colorTo = hackingUIConst.COLOR_BLOCKED elif hackingConst.TYPE_NONE in (tileFromData.type, tileToData.type): colorFrom = colorTo = hackingUIConst.COLOR_UNEXPLORED else: colorFrom = colorTo = hackingUIConst.COLOR_EXPLORED self.ShowBleed() widthFrom = widthTo = hackingUIConst.WIDTH_LINE if tileFromData.blocked or tileFromData.type == hackingConst.TYPE_DEFENSESOFTWARE: colorFrom = (0.0, 0.0, 0.0, 0.5) widthFrom = 5.0 if not (tileToData.blocked or tileToData.type == hackingConst.TYPE_DEFENSESOFTWARE): widthTo = 0.0 if tileToData.blocked or tileToData.type == hackingConst.TYPE_DEFENSESOFTWARE: colorFrom = (0.0, 0.0, 0.0, 0.5) widthTo = 5.0 if not (tileFromData.blocked or tileFromData.type == hackingConst.TYPE_DEFENSESOFTWARE): widthFrom = 0.0 uicore.animations.SpColorMorphTo(self.line, self.line.colorFrom, colorFrom, attrName='colorFrom') uicore.animations.SpColorMorphTo(self.line, self.line.colorTo, colorFrom, attrName='colorTo') uicore.animations.MorphScalar(self.line, 'widthFrom', self.line.widthFrom, widthFrom) uicore.animations.MorphScalar(self.line, 'widthTo', self.line.widthTo, widthTo) offset1 = self.GetLineOffsetAmount(self.tileFrom.tileData.type) p0 = geo2.Vec2Add(self.p0, geo2.Vec2Scale(self.offset, offset1)) self.line.translationFrom = p0 offset2 = self.GetLineOffsetAmount(self.tileTo.tileData.type) p1 = geo2.Vec2Subtract(self.p1, geo2.Vec2Scale(self.offset, offset2)) self.line.translationTo = p1
def DrawLines(self): """ Draw lines connecting materialGroups to center circle """ x1, y1 = self.GetAbsolutePosition() linePoints = [] thetas = [] for materialGroup in self.materialGroups: x0, y0 = materialGroup.GetEndPoint() p = (x0, materialGroup.top + materialGroup.height / 2.0) p1, theta = self.GetInnerCircleIntersectPoint(p[1]) thetas.append(theta) p0 = self.GetOuterCirclePoint(p, p1) linePoints.append((p0, p1)) if len(linePoints) == 1: p = linePoints[0][0] self.DrawLineToCenter(p) return thetaFirst = thetas[0] thetaLast = thetas[-1] numPoints = int(fabs((thetaFirst - thetaLast) * 8)) stepSize = (thetaLast - thetaFirst) / numPoints lineStart = linePoints.pop(0) arcPoints = [lineStart[0]] r = industryUIConst.RADIUS_CENTERCIRCLE_INNER for i in xrange(numPoints): th = thetaFirst + float(i) * stepSize p = (r * cos(th), r * sin(th)) p = geo2.Vec2Add(self.GetPointCenter(), p) arcPoints.append(p) lineEnd = linePoints.pop() arcPoints.extend([lineEnd[1], lineEnd[0]]) self.DrawLine(arcPoints) for p0, p1 in linePoints: self.DrawLine((p0, p1)) self.DrawLineToCenter(self.GetPointCenterLeft())
def _GetLinePosition(self, node): vec = self._GetNodePosition(node) vec = geo2.Vec2Add(vec, (X_OFFSET, Y_OFFSET)) return (int(vec[0]), int(vec[1]))