Parlayan ağırlıklı grafik (ağ): köşeler ve kenarlar
Aşağıdakileri yapmanın bir yolunu bulmaya çalışıyorum (tercihen basit ve daha büyük grafikler için optimize edilmiş performans / hız):
Grafik tepe noktalarını ışıma efekti ile şekillendirme ve
VertexWeight
Grafik kenarlarını ışıma efekti ile şekillendirme ve buna bağlı olarak yoğunluğu
EdgeWeight
DirectedEdge
parlama efekti şekillendirme de arzu edilir (basitlik için işler başlayabilirUndirectedEdge
)
Örneğin bunun gibi bir şey için:
RandomGraph[{20,100},
VertexWeight->RandomReal[1,20],
EdgeWeight->RandomReal[1,100],
Background->Black,
BaseStyle->White]
Aşağıdakine benzer bir görsel arıyorum, ancak kenarların da parlaması gerekiyor:

Yaşadığım sorunlar.
1. Çarpıcı bir ışıltının basit uygulaması
Çeşitli parlama efektleri gördüm ( parlayan noktalar hakkında BU da dahil ), ancak en iyi görsel ve performans fikirleri konusunda bir uzman değilim. Şaşırtıcı bir şekilde, etrafta parlayan çizgiler hakkında pek bir şey görmedim. Safça böyle bir şeyle başlardım, ancak bu muhtemelen görsel ve performans açısından iyileştirilebilir:
bsc=BSplineCurve[{{0,0},{1,1},{2,0}}];
Graphics[
Table[{White,Opacity[1/k^1.2],Thickness[.005k],CapForm["Round"],bsc},{k,20}],
Background->Black]

2. Ağırlıkları parlatmak
Ben farkındayım ederken VertexShapeFunction
ve EdgeShapeFunction
ben pek emin optimum onlara ağırlıklarını nasıl geçirileceği değilim ... ve bu özellikler doğru bir yaklaşım olup olmadığını.
Yerleşik işlevlerde parlama
Bu işlevlerin biraz parıltı ürettiğini fark ettim:
ComplexPlot[z^2+1,{z,-2-2I,2+2I},ColorFunction->"CyclicReImLogAbs"]

Ve @EC'nin aşağıdaki cevabında fark ettiği gibi
ImageAdjust[DistanceTransform[Graphics[Point[RandomReal[1,{100,2}]]]]]

Teşekkürler, yardımınız çok takdir ediliyor!
Yanıtlar
ImageAdd
Görüntü maskesinin bulanık bir kopyası ile genel bir parlaklık efekti elde edebilirsiniz . Kuşkusuz biraz basit, ancak etki çekici. Kullanarak bir 'beyin' ağı oluşturmayı AnatomyData
ve NearestNeighbourGraph
onu aşırı abartılı yapay zeka pazarlama şeyine benzetmeyi seçtim :
SeedRandom[123];
brain = AnatomyData[Entity["AnatomicalStructure", "Brain"], "MeshRegion"];
boundary = RegionBoundary[brain];
nng = NearestNeighborGraph[RandomPoint[boundary, 1000], 7];
brainnetimg = Rasterize[
GraphPlot3D[nng, ViewPoint -> Left,
VertexStyle -> Directive[AbsolutePointSize[7], White],
EdgeStyle -> Directive[AbsoluteThickness[2], White],
Background -> Black]
, ImageSize -> 1000];
ImageAdd[ImageAdjust[Blur[Binarize@brainnetimg, 7], .1],
ImageMultiply[brainnetimg,
LinearGradientImage[{Blue, Cyan, Purple},
ImageDimensions[brainnetimg]]]]
Size kızdırma boyutunu etkileyecek ağırlıkları almak için muhtemelen kullanmanız gerekir EdgeShapeFunction
ve VertexShapeFunction
. Alfa ile bir mercek efektinin ilan tahtası dokusunu oluşturdum ve bu resmi köşeler için kullandım:
Çizgileri istifleyen soruda bahsettiğiniz kenar parlama efektini de kullandım. Daha fazla ağırlığa sahip kenarların daha fazla parlaması gerekir ve daha fazla ağırlığa sahip köşelerin daha büyük bir parlaması olur:
SeedRandom[123];
G = SpatialGraphDistribution[100, 0.20];
g = RandomGraph[G];
glowtexture = Import["lensbb.png"];
edgeWeights = RandomReal[1, EdgeCount[g]];
vertexWeights = RandomReal[1, VertexCount[g]];
edgeShapeFunc =
With[{weight = AnnotationValue[{g, #2}, EdgeWeight]},
Table[{RGBColor[0.7, 1.0, 0.9], Opacity[1/k^1.3],
Thickness[.001 k*weight], CapForm["Round"], Line[#1]}, {k, 20}]] &;
vertexShapeFunc =
With[{weight = AnnotationValue[{g, #2}, VertexWeight]},
Inset[glowtexture, #1, Center, weight*0.3]] &;
g = Graph[g, EdgeWeight -> edgeWeights, VertexWeight -> vertexWeights,
VertexShapeFunction -> vertexShapeFunc, Background -> Black,
EdgeShapeFunction -> edgeShapeFunc, PlotRangePadding -> .1]
Parlayan kenarları oluşturmak için yukarıdaki satır yığınlama / opaklık numarasını kullanmak yerine, bunun yerine dokulu çokgenler de kullanabilirsiniz. Bu daha hızlıdır, ancak bir dezavantajı, kenarlar çok kalın hale geldiğinde kapakların görünür ve çirkin olmasıdır:
g = Graph[UndirectedEdge @@@ {{1, 2}, {2, 3}, {3, 1}}];
edgeWeights = {1, 2, 3}/6.;
vertexWeights = {1, 2, 3}/6.;
glowtexture = Import["lensbb.png"];
edgegradimg = LinearGradientImage[{Transparent,Cyan,Transparent}, {64,64}];
edgeShapeFunc =
Module[{weight = AnnotationValue[{g, #2}, EdgeWeight], s = 1/10.,
vec = #1[[2]] - #1[[1]], perp},
perp = Cross[vec];
{Texture[edgegradimg],
Polygon[{
#1[[1]]-perp*weight*s,
#1[[1]]+perp*weight*s,
#1[[2]]+perp*weight*s,
#1[[2]]-perp*weight*s
}, VertexTextureCoordinates -> {{0,0},{1,0},{1,1},{0,1}}]
}] &;
vertexShapeFunc =
With[{weight = AnnotationValue[{g, #2}, VertexWeight]},
Inset[glowtexture, #1, Center, weight*3]] &;
g = Graph[g, EdgeWeight -> edgeWeights, VertexWeight -> vertexWeights,
VertexShapeFunction -> vertexShapeFunc, Background -> Black,
EdgeShapeFunction -> edgeShapeFunc, PlotRangePadding -> .5]

DistanceTransform
bize ışıma için ihtiyacımız olan türde bir mesafe haritası verir.
Önce ışık kaynağını tanımlarız:
bg = ConstantImage[White, 200];
line = HighlightImage[
bg, {
Black,
Thick,
Line[{{50, 100}, {150, 100}}]
}]

Sonra, mesafe dönüşümünü hesaplıyoruz. Ortaya çıkan görüntüdeki 1 görüntünün köşegenine karşılık gelecek şekilde ölçeklendiriyoruz.
glow = ColorNegate@Image[Divide[
ImageData@DistanceTransform[line],
200 Sqrt[2]
]^0.2]

0.2 sayısı, ışımanın ne kadar çabuk söndüğünü kontrol eder.
Ardından ışıma bir renk uygulayabiliriz:
glow ConstantImage[Red, 200]

Hatta renk fonksiyonlarını da uygulayabiliriz:
ImageApply[List @@ ColorData["AvocadoColors", #] &, glow]

Güzel bir renk işlevi oluşturmak, örneğinizdeki gibi hoş bir ışıltı yaratmanın anahtarı olacaktır.
Bu tekniği kullanarak parlayan bir grafik oluşturmak oldukça basittir. Her kenar bir çizgidir ve her köşe bir nokta veya disktir. Sonunda, onları tek bir görüntüde bir araya getirebiliriz.
Bunun için sağlam bir işlev oluşturmayı okuyucuya bırakacağım. Küçük bir örnek vereceğim.
Örnek için Pappus grafiğini kullanacağız:
embedding = First@GraphData["PappusGraph", "Embeddings"];
coords = List @@@ GraphData["PappusGraph", "Edges"] /. Thread[
Range[Length[embedding]] -> embedding
];
Graphics[{
Point[embedding],
Line[coords]
}]

Bir grafik yerine bir görüntü üzerine çizmek, koordinatların yeniden ölçeklendirilmesini gerektirir:
toImageCoordinates[{x_, y_}] := {
Rescale[x, {-1, 1}, {0, 200}],
Rescale[y, {-1, 1}, {0, 200}]
}
primitives = Join[
Point@*toImageCoordinates /@ embedding,
Line@*toImageCoordinates /@ coords
];
Bu işlev, ışıma ile herhangi bir ilkel çizecektir:
draw[primitive_, size_, glow_] := Module[{bg, img},
bg = ConstantImage[White, 200];
img = HighlightImage[bg, {
Black,
PointSize[Large],
Thick,
primitive
}];
ColorNegate@Image[Divide[
ImageData@DistanceTransform[img],
size Sqrt[2]
]^glow]
]
draw[First@primitives, 200, 0.2]

Şimdi plan, bu işlevi tüm ilkellerin haritasını çıkarmaktır.
images = draw[#, 200, 0.2] & /@ primitives;
ImageAdd @@ images // ImageAdjust

Buradan, kenarların ve noktaların farklı miktarlarda parıltıya sahip olabileceği açıktır. Zaman kısıtlamaları nedeniyle, tüm bunları bir "parlayan grafik" işlevi haline getiren işlevi yapmayacağım, ancak bunu, bu sorunu çözmek için olası bir yaklaşım olarak burada bırakıyorum.