Exemple #1
0
 def _GetLineCenterPoint(self, sp1, sp2):
     x = sp1.x / 2.0 + sp2.x / 2.0
     y = sp1.y / 2.0 + sp2.y / 2.0
     z = sp1.z / 2.0 + sp2.z / 2.0
     sp = SurfacePoint(x, y, z)
     sp.SetRadius(1.0)
     return sp
def GetPickIntersectionPoint(x=None, y=None):
    """
    Returns the point on the planet at (x, y) screen coordinates. This is done
    by casting a ray based on the screen coordinates (x, y) and the viewport
    and then finally calculating the intersection of that ray and a sphere (the planet).
    Method defaults to the current mouse coordinates if x and y arguments are None
    Returns None if the planet was not clicked.
    Arguments:
    x - the x coordinates in screen space
    y - the y coordinares in screen space
    """
    if None in (x, y):
        x, y = int(uicore.uilib.x * uicore.desktop.dpiScaling), int(
            uicore.uilib.y * uicore.desktop.dpiScaling)
    device = trinity.device
    proj, view, vp = uix.GetFullscreenProjectionViewAndViewport()
    ray, start = device.GetPickRayFromViewport(x, y, vp, view.transform,
                                               proj.transform)
    lineVec = trinity.TriVector(*ray)
    lineP0 = trinity.TriVector(*start)
    sphereP0 = trinity.TriVector(0.0, 0.0, 0.0)
    sphereRad = 1000.0
    pInt = GetSphereLineIntersectionPoint(lineP0, lineVec, sphereP0, sphereRad)
    if not pInt:
        return
    ret = SurfacePoint(pInt.x, pInt.y, pInt.z)
    ret.SetRadius(1.0)
    return ret
Exemple #3
0
 def ValidateMoveExtractorHead(self, pinID, headID, latitude, longitude):
     if self.colonyData is None:
         raise RuntimeError(
             'Unable to validate extractor head movement - no colony data')
     if latitude < 0 or latitude > math.pi:
         raise RuntimeError(
             'Invalid value for latitude - must be between 0..pi')
     if longitude < 0 or longitude > 2 * math.pi:
         raise RuntimeError(
             'Invalid value for longitude - must be between 0..2pi')
     self.PreValidateMoveExtractorHead(pinID, headID, latitude, longitude)
     pin = self.GetPin(pinID)
     if not pin:
         raise UserError('PinDoesNotExist')
     if not pin.IsExtractor():
         raise UserError('PinDoesNotHaveHeads')
     if pin.FindHead(headID) is None:
         raise UserError('CannotMoveHeadNotPresent')
     spA = SurfacePoint(theta=pin.longitude, phi=pin.latitude)
     spB = SurfacePoint(theta=longitude, phi=latitude)
     angleBetween = spA.GetAngleBetween(spB)
     areaOfInfluence = pin.GetAreaOfInfluence()
     if angleBetween > areaOfInfluence:
         raise UserError(
             'CannotPlaceHeadTooFarAway',
             {'maxDist': util.FmtDist(angleBetween * self.planet.radius)})
     self.PostValidateMoveExtractorHead(pinID, headID, latitude, longitude)
Exemple #4
0
 def _GetTriangleCenterPoint(self, sp1, sp2, sp3):
     x = sp1.x / 3.0 + sp2.x / 3.0 + sp3.x / 3.0
     y = sp1.y / 3.0 + sp2.y / 3.0 + sp3.y / 3.0
     z = sp1.z / 3.0 + sp2.z / 3.0 + sp3.z / 3.0
     sp = SurfacePoint(x, y, z)
     sp.SetRadius(1.0)
     return sp
 def ValidateAddExtractorHead(self, pinID, headID, latitude, longitude):
     if self.colonyData is None:
         raise RuntimeError('Unable to validate new extractor head - no colony data')
     if latitude < 0 or latitude > math.pi:
         raise RuntimeError('Invalid value for latitude - must be between 0..pi')
     if longitude < 0 or longitude > 2 * math.pi:
         raise RuntimeError('Invalid value for longitude - must be between 0..2pi')
     self.PreValidateAddExtractorHead(pinID, latitude, longitude)
     pin = self.GetPin(pinID)
     if not pin:
         raise UserError('PinDoesNotExist')
     if not pin.IsExtractor():
         raise UserError('PinDoesNotHaveHeads')
     if pin.FindHead(headID) is not None:
         raise UserError('CannotAddHeadAlreadyExists')
     if len(pin.heads) >= ECU_MAX_HEADS:
         raise UserError('CannotPlaceHeadLimitReached')
     cpuDelta = pin.GetCpuUsage(numHeads=len(pin.heads) + 1) - pin.GetCpuUsage()
     powerDelta = pin.GetPowerUsage(numHeads=len(pin.heads) + 1) - pin.GetPowerUsage()
     if cpuDelta + self.colonyData.GetColonyCpuUsage() > self.colonyData.GetColonyCpuSupply():
         raise UserError('CannotAddToColonyCPUUsageExceeded', {'typeName': (const.UE_LOC, 'UI/PI/Common/ExtractorHead')})
     if powerDelta + self.colonyData.GetColonyPowerUsage() > self.colonyData.GetColonyPowerSupply():
         raise UserError('CannotAddToColonyPowerUsageExceeded', {'typeName': (const.UE_LOC, 'UI/PI/Common/ExtractorHead')})
     spA = SurfacePoint(radius=self.GetPlanetRadius(), theta=pin.longitude, phi=pin.latitude)
     spB = SurfacePoint(radius=self.GetPlanetRadius(), theta=longitude, phi=latitude)
     angleBetween = spA.GetAngleBetween(spB)
     areaOfInfluence = pin.GetAreaOfInfluence()
     if angleBetween > areaOfInfluence:
         raise UserError('CannotPlaceHeadTooFarAway', {'maxDist': util.FmtDist(areaOfInfluence * self.planet.radius)})
     self.PostValidateAddExtractorHead(pinID, latitude, longitude)
Exemple #6
0
def GetDistanceBetweenPins(pinA, pinB, planetRadius):
    spA = SurfacePoint(radius=planetRadius,
                       theta=pinA.longitude,
                       phi=pinA.latitude)
    spB = SurfacePoint(radius=planetRadius,
                       theta=pinB.longitude,
                       phi=pinB.latitude)
    return spA.GetDistanceToOther(spB)
Exemple #7
0
 def _GetLinkWeight(self, link, pinA, pinB):
     """
         Right now, it uses the spherical distance between two points as its
         weight metric.
     """
     spA = SurfacePoint(radius=1.0, theta=pinA.longitude, phi=pinA.latitude)
     spB = SurfacePoint(radius=1.0, theta=pinB.longitude, phi=pinB.latitude)
     return spA.GetDistanceToOther(spB)
 def RenderPin(self, pin):
     if pin.id in self.pinsByID:
         self.pinsByID[pin.id].Remove()
     surfacePoint = SurfacePoint(phi=pin.latitude, theta=pin.longitude)
     pinClass = self.GetPinGraphicsClassForType(pin.typeID)
     UIpin = pinClass(surfacePoint, pin, self.planetUISvc.pinTransform)
     self.pinsByID[pin.id] = UIpin
     return UIpin
Exemple #9
0
def GetPickIntersectionPoint(x=None, y=None):
    if None in (x, y):
        x, y = int(uicore.uilib.x * uicore.desktop.dpiScaling), int(
            uicore.uilib.y * uicore.desktop.dpiScaling)
    device = trinity.device
    proj, view, vp = uix.GetFullscreenProjectionViewAndViewport()
    ray, start = device.GetPickRayFromViewport(x, y, vp, view.transform,
                                               proj.transform)
    lineVec = trinity.TriVector(*ray)
    lineP0 = trinity.TriVector(*start)
    sphereP0 = trinity.TriVector(0.0, 0.0, 0.0)
    sphereRad = 1000.0
    pInt = GetSphereLineIntersectionPoint(lineP0, lineVec, sphereP0, sphereRad)
    if not pInt:
        return
    ret = SurfacePoint(pInt.x, pInt.y, pInt.z)
    ret.SetRadius(1.0)
    return ret
 def PlacePinOnNextClick(self, pinTypeID):
     self.eventManager.SetStateBuildPin()
     self._RemoveBuildIndicatorPin()
     self.newPinType = pinTypeID
     typeObj = cfg.invtypes.Get(pinTypeID)
     self.buildIndicatorPin = BuildIndicatorPin(
         SurfacePoint(), pinTypeID, typeObj.groupID,
         self.planetUISvc.pinOthersTransform)
     if typeObj.groupID == const.groupExtractionControlUnitPins:
         self.DisplayECUExtractionAreas(show=True)
 def OnPlanetViewOpened(self):
     self.planetUISvc = sm.GetService('planetUI')
     self.eventManager = self.planetUISvc.eventManager
     sp = SurfacePoint()
     rubberColor = (1.0, 1.0, 1.0, 1.0)
     self.rubberLink = self.planetUISvc.curveLineDrawer.DrawArc(
         'rubberLink', sp, sp, 2.0, rubberColor, rubberColor)
     self.InitRubberLinkLabels()
     self.ReRender()
     self.depletionPoints = []
     self.bracketCurveSet.Play()
 def AddLink(self, parentID, childID, linkTypeID):
     colony = self.planetUISvc.planet.GetColony(session.charid)
     if colony is None:
         log.LogError('Unable to render link for planet without a colony')
         return
     par = colony.GetPin(parentID)
     child = colony.GetPin(childID)
     if par is None or child is None:
         log.LogWarn('Trying to render link for non-existing pin', parentID,
                     childID)
         return
     p1 = SurfacePoint(theta=par.longitude, phi=par.latitude)
     p2 = SurfacePoint(theta=child.longitude, phi=child.latitude)
     planetLink = colony.colonyData.GetLink(parentID, childID)
     link = Link(p1, p2, parentID, childID, linkTypeID, planetLink)
     self.linksByPinIDs[parentID, childID] = link
     self.linksByPinIDs[childID, parentID] = link
     self.links.append(link)
     linkGraphicID1, linkGraphicID2 = link.GetGraphicIDs()
     self.linksByGraphicID[linkGraphicID1] = link
     self.linksByGraphicID[linkGraphicID2] = link
Exemple #13
0
 def _SplitTriangle(self, v0, v1, v2, lines, cLines, hLines, sps, level):
     level -= 1
     lc0 = self._GetLineCenterPoint(v0, v1)
     lc1 = self._GetLineCenterPoint(v1, v2)
     lc2 = self._GetLineCenterPoint(v2, v0)
     tc = self._GetTriangleCenterPoint(v0, v1, v2)
     if level > 0:
         self._SplitTriangle(v0, lc0, lc2, lines, cLines, hLines, sps,
                             level)
         self._SplitTriangle(v1, lc1, lc0, lines, cLines, hLines, sps,
                             level)
         self._SplitTriangle(v2, lc2, lc1, lines, cLines, hLines, sps,
                             level)
         self._SplitTriangle(lc0, lc1, lc2, lines, cLines, hLines, sps,
                             level)
     else:
         v = geo2.Vector
         vecC = v(*tc.GetAsXYZTuple())
         vec0 = v(*v0.GetAsXYZTuple())
         vec1 = v(*v0.GetAsXYZTuple())
         vec2 = v(*v0.GetAsXYZTuple())
         vec01 = v(*(v1.x - v0.x, v1.y - v0.y, v1.z - v0.z))
         n0 = v(*geo2.Vec3Cross(vecC, vec01))
         vec12 = v(*(v2.x - v1.x, v2.y - v1.y, v2.z - v1.z))
         n1 = v(*geo2.Vec3Cross(vecC, vec12))
         vec20 = v(*(v0.x - v2.x, v0.y - v2.y, v0.z - v2.z))
         n2 = v(*geo2.Vec3Cross(vecC, vec20))
         s = 0.16
         sGap = 0.1
         n0 = v(*(s * n0))
         n1 = v(*(s * n1))
         n2 = v(*(s * n2))
         lp0 = SurfacePoint(*(vecC - n0))
         lp1 = SurfacePoint(*(vecC - n1))
         lp2 = SurfacePoint(*(vecC - n2))
         lr0 = SurfacePoint(*(vecC - v(*(sGap * n0))))
         lr1 = SurfacePoint(*(vecC - v(*(sGap * n1))))
         lr2 = SurfacePoint(*(vecC - v(*(sGap * n2))))
         lp0.SetRadius(1.0)
         lp1.SetRadius(1.0)
         lp2.SetRadius(1.0)
         lr0.SetRadius(1.0)
         lr1.SetRadius(1.0)
         lr2.SetRadius(1.0)
         lines.add((lr0, lp0))
         lines.add((lr1, lp1))
         lines.add((lr2, lp2))
Exemple #14
0
    def _DrawMesh(self,
                  lsName,
                  numPhi=30,
                  numTheta=60,
                  phiSkip=0,
                  lineWidth=2.0,
                  col=(1.0, 1.0, 1.0, 0.01)):
        col = (0.8, 0.8, 1.0, 0.3)
        colAnim = (1.0, 1.0, 1.0, 1.0)
        speedAnim = 0.06
        scaleAnim = 2.0
        phi0 = math.pi / 90
        phiStep = (math.pi - 2 * phi0) / numPhi
        phiInit = phi0 + phiStep * phiSkip
        ls = self.GetLineSet(lsName)
        for p in xrange(numPhi + 1):
            if p <= phiSkip - 1 or p > numPhi - phiSkip:
                continue
            phi = phi0 + float(p) * phiStep
            for quarter in xrange(0, 4):
                th0 = math.pi / 2 * quarter
                p1 = SurfacePoint(theta=th0, phi=phi)
                p2 = SurfacePoint(theta=th0 + math.pi / 2, phi=phi)
                pC = SurfacePoint(0.0, p1.y, 0.0)
                lineID = ls.AddSpheredLineCrt(p1.GetAsXYZTuple(), col,
                                              p2.GetAsXYZTuple(), col,
                                              pC.GetAsXYZTuple(), lineWidth)
                ls.ChangeLineAnimation(lineID, colAnim, speedAnim, scaleAnim)

        for t in xrange(numTheta):
            th = float(t) / numTheta * math.pi * 2
            p1 = SurfacePoint(theta=th, phi=math.pi / 2.0)
            p2 = SurfacePoint(theta=th, phi=phiInit)
            lineID = ls.AddSpheredLineCrt(p1.GetAsXYZTuple(), col,
                                          p2.GetAsXYZTuple(), col, self.p0,
                                          lineWidth)
            ls.ChangeLineAnimation(lineID, colAnim, speedAnim, scaleAnim)
            p2 = SurfacePoint(theta=th, phi=math.pi - phiInit)
            lineID = ls.AddSpheredLineCrt(p1.GetAsXYZTuple(), col,
                                          p2.GetAsXYZTuple(), col, self.p0,
                                          lineWidth)
            ls.ChangeLineAnimation(lineID, colAnim, speedAnim, scaleAnim)

        ls.SubmitChanges()
 def CreateOrbitCircle(self, orbitem, parent, lineSet, points=256):
     orbitPos = geo2.Vector(*orbitem.translation)
     parentPos = geo2.Vector(*parent.translation)
     dirVec = orbitPos - parentPos
     radius = geo2.Vec3Length(dirVec)
     if radius == 0:
         return
     lineColor = (1, 1, 1, 0.1)
     dx, dy, dz = dirVec
     fromPoint = SurfacePoint(dx, dy, dz)
     radius, theta, phi = fromPoint.GetAsRadThPhiTuple()
     toPoint = SurfacePoint(theta=theta + math.pi * 0.5, phi=phi)
     x, y, z = toPoint.GetAsXYZTuple()
     line1 = lineSet.AddSpheredLineCrt(fromPoint.GetAsXYZTuple(), lineColor,
                                       (x, y, z), lineColor, parentPos, 3.0)
     line2 = lineSet.AddSpheredLineCrt(fromPoint.GetAsXYZTuple(), lineColor,
                                       (-x, -y, -z), lineColor, parentPos,
                                       3.0)
     fromPoint = SurfacePoint(-dx, -dy, -dz)
     radius, theta, phi = fromPoint.GetAsRadThPhiTuple()
     toPoint = SurfacePoint(theta=theta + math.pi * 0.5, phi=phi)
     x, y, z = toPoint.GetAsXYZTuple()
     line3 = lineSet.AddSpheredLineCrt(fromPoint.GetAsXYZTuple(), lineColor,
                                       (x, y, z), lineColor, parentPos, 3.0)
     line4 = lineSet.AddSpheredLineCrt(fromPoint.GetAsXYZTuple(), lineColor,
                                       (-x, -y, -z), lineColor, parentPos,
                                       3.0)
     lineSet.ChangeLineSegmentation(line1, 25)
     lineSet.ChangeLineSegmentation(line2, 25)
     lineSet.ChangeLineSegmentation(line3, 25)
     lineSet.ChangeLineSegmentation(line4, 25)
     animationColor = (0, 0, 0, 0.5)
     lineSet.ChangeLineAnimation(line1, animationColor, 0.1, 0.5)
     lineSet.ChangeLineAnimation(line2, animationColor, -0.1, 0.5)
     lineSet.ChangeLineAnimation(line3, animationColor, 0.1, 0.5)
     lineSet.ChangeLineAnimation(line4, animationColor, -0.1, 0.5)
Exemple #16
0
    def CreateProgram(self,
                      harmonic,
                      ecuPinID,
                      resourceTypeID,
                      points=None,
                      headRadius=None):
        ecuPin = self.GetPin(ecuPinID)
        if points is None:
            points = ecuPin.heads
        if headRadius is None:
            headRadius = ecuPin.GetExtractorHeadRadius()
        overlapFactor = self.GetTypeAttribute(ecuPin.typeID,
                                              const.attributeEcuOverlapFactor)
        maxVolume = self.GetTypeAttribute(ecuPin.typeID,
                                          const.attributeEcuMaxVolume)
        overlapModifiers = {}
        heads = []
        for index, longitude, latitude in points:
            heads.append((index, SurfacePoint(theta=latitude, phi=longitude)))
            overlapModifiers[index] = 1.0

        distance = {}
        valueByIndex = {}
        for index, surfacePoint in heads:
            theta = 2.0 * math.pi - surfacePoint.theta
            phi = surfacePoint.phi
            valueByIndex[index] = max(builder.GetValueAt(harmonic, theta, phi),
                                      0)
            for index2, surfacePoint2 in heads:
                if index == index2:
                    continue
                key = tuple(sorted([index, index2]))
                if key not in distance:
                    distance[key] = surfacePoint.GetDistanceToOther(
                        surfacePoint2)

        with bluepy.TimerPush('OverlapOwnHeads'):
            for (head1, head2), dist in distance.iteritems():
                if dist < headRadius * 2:
                    radiusSquared = headRadius**2
                    overlap = (
                        2 * radiusSquared * math.acos(0.5 *
                                                      (dist / headRadius)) -
                        0.5 * dist * math.sqrt(4 * radiusSquared - dist**2)
                    ) / (math.pi * radiusSquared)
                    modifier = min(1, max(0, 1 - overlap * overlapFactor))
                    valueByIndex[head1] *= modifier
                    valueByIndex[head2] *= modifier
                    overlapModifiers[head1] *= modifier
                    overlapModifiers[head2] *= modifier

        with bluepy.TimerPush('OverlapOthersHeads'):
            otherHeadsInfo = []
            for pin in self.colonyData.GetECUs(ecuPinID):
                if pin.programType != resourceTypeID:
                    continue
                otherHeadsInfo.append(
                    (pin.GetExtractorHeadRadius(), pin.heads))

            headArea = math.pi * headRadius**2
            for index, surfacePoint1 in heads:
                modifier = 1
                for otherHeadRadius, otherHeads in otherHeadsInfo:
                    if modifier == 0:
                        break
                    for index2, longitude2, latitude2 in otherHeads:
                        surfacePoint2 = SurfacePoint(theta=latitude2,
                                                     phi=longitude2)
                        d, R, r = surfacePoint1.GetDistanceToOther(
                            surfacePoint2), headRadius, otherHeadRadius
                        if d > R + r:
                            continue
                        r2, R2, d2 = r**2, R**2, d**2
                        alpha = (d2 + r2 - R2) / (2 * d * r)
                        if alpha < -1:
                            overlap = math.pi * r2 / headArea
                        elif alpha > 1:
                            overlap = 1
                        else:
                            f1 = r**2 * math.acos(alpha)
                            f2 = R**2 * math.acos(
                                (d**2 + R**2 - r**2) / (2 * d * R))
                            f3 = 0.5 * math.sqrt((-d + r + R) * (d + r - R) *
                                                 (d - r + R) * (d + r + R))
                            A = f1 + f2 - f3
                            overlap = A / headArea
                        modifier *= min(
                            1, max(0, 1 - overlap * 2 * overlapFactor))

                valueByIndex[index] *= modifier
                overlapModifiers[index] *= modifier

        for index, modifier in overlapModifiers.iteritems():
            overlapModifiers[index] = 1.0 - modifier

        maxValue = maxVolume * sum(valueByIndex.values())
        programLength = GetProgramLengthFromHeadRadius(headRadius)
        cycleTime = GetCycleTimeFromProgramLength(programLength)
        numCycles = int(programLength / cycleTime)
        cycleTime = int(cycleTime * const.HOUR)
        return (int(maxValue), cycleTime, numCycles, overlapModifiers)
Exemple #17
0
 def _GetLinkWeight(self, link, pinA, pinB):
     spA = SurfacePoint(radius=1.0, theta=pinA.longitude, phi=pinA.latitude)
     spB = SurfacePoint(radius=1.0, theta=pinB.longitude, phi=pinB.latitude)
     return spA.GetDistanceToOther(spB)