Summary
Description
Dna-SNP.svg
English: A Single Nucleotide Polymorphism is a change of a nucleotide at a single base-pair location on DNA. Created using OpenSCAD v2021.01 and Inkscape v1.0.2.
Date
8 May 2021
Source
Own work
Construction process
This file was derived from a 3D model of DNA, converted to SVG and coloured using David Eccles' STL2SVG script:
type=orig; ~/scripts/stl2svg.pl ./DNA_linear_complete_helix1.stl:330 ./DNA_linear_complete_helix2.stl:200 ./DNA_linear_complete_${type}_A.stl:140 ./DNA_linear_complete_${type}_C.stl:250 ./DNA_linear_complete_${type}_G.stl:90 ./DNA_linear_complete_${type}_T.stl:30 > out_${type}.svg
type=mut; ~/scripts/stl2svg.pl ./DNA_linear_complete_helix1.stl:330 ./DNA_linear_complete_helix2.stl:200 ./DNA_linear_complete_${type}_A.stl:140 ./DNA_linear_complete_${type}_C.stl:250 ./DNA_linear_complete_${type}_G.stl:90 ./DNA_linear_complete_${type}_T.stl:30 > out_${type}.svg
The DNA models were then combined and annotated using Inkscape. The DNA backbone for the model is a pentagon extruded over a sine wave using David Eccles' guided path extrude script . The model source file (in OpenSCAD format) is shown below:
use <guided_extrude.scad>;
hl = 100; // helix length
hp = 33.2; // helix pitch [in angstroms]
hr = 10; // helix radius [in angstroms]
bbr = 1.5; // backbone radius
loops = hl / hp;
// random bases
//bases = rands(0, 4, ceil(360 * loops / 34.3),1);
// *GRINGENE* -- TAA GGN MGN ATH AAY GGN GAR AAY GAR TGA
// -- TAA GGC AGG ATC AAC GGC GAG AAC GAG TGA
// A = 0; G = 1; C = 2; T = 3
// [different from my usual order,
// to simplify the 3D model logic]
bases = [3,3,3, 1,1,2, 0,1,1, 0,3,2, 0,0,2,
1,1,2, 1,0,1, 0,0,2, 1,0,1, 3,1,0];
bAng = atan2(sin(120) - sin(0), cos(120) - cos(0));
drawMode = "all";
module lineTo(x1, x2){
hull(){
translate(x1) sphere(r=0.25, $fn=5);
translate(x2) sphere(r=0.25, $fn=5);
}
}
backbone_profile = [for(th = [0:72:359]) [bbr*cos(th),
bbr*sin(th)*1]];
inc = floor($t * 30);
thf = ($t * 30) - inc;
h1limit = (360 * loops);
h1jump = (360 * loops);
helix_1 = [for(th = [(thf*34.3):(34.3/2):h1jump])
[hr * cos(th), hr * sin(th), hl * th / (360 * loops)]];
helix_2 = [for(th = [120:(34.3/2):(360 * loops+120)])
[hr * cos(th), hr * sin(th), hl * (th-120) / (360 * loops)]];
module purine(){
linear_extrude(height=0.75, center=true){
// average hydrogen bond length in water: 1.97 A
// https://en.wikipedia.org/wiki/Hydrogen_bond#Structural_details
translate([-0.985,0])
// scale: average of C-C and C=C bond length
scale(1.435) translate([-2,0]) rotate(12) rotate(18){
rotate(-30) translate([1,0]) circle(r=1, $fn=6);
color("blue")
rotate(36) translate([-1 / (2*sin(36)),0])
circle(r=1 / (2*sin(36)), $fn=5);
}
}
}
module pyrimidine(){
linear_extrude(height=0.75, center=true){
// average hydrogen bond length in water: 1.97 A
// https://en.wikipedia.org/wiki/Hydrogen_bond#Structural_details
translate([-0.985,0])
scale(1.435) translate([-2, 0]) translate([1,0])
circle(r=1, $fn=6);
}
}
$vpt = [0, 0, 0];
//$vpr = [310, 105, 10];
$vpr = [0, 0, 0];
rotate([310, 105, 130]) translate([0,0,-hl/2]) {
if(drawMode == "all" || drawMode == "helix1") color("lightblue")
mapExtrude("vertCylinder", backbone_profile, helix_1);
if(drawMode == "all" || drawMode == "helix2") color("pink")
mapExtrude("vertCylinder", backbone_profile, helix_2);
for(thb = [inc:(360 * loops / 34.3 + inc)]) {
thi = thb-inc;
th = (thi-thf) * 34.3;
thisBase = bases[floor(thb%30)];
doPur = (thisBase < 2);
// base bond has a -1.2° angle;
// not quite sure how to implement that
baseFrac = (doPur ? 0.55 : 0.45);
baseFInv = 1 - baseFrac;
translate([0,0,hl * th / (360 * loops)]) rotate([-1.2,0,0]){
if(drawMode == "all" || drawMode == "helix2") color("pink")
lineTo([hr * cos(th)*(baseFrac-0.15) +
hr * cos(th+120) * (baseFrac+0.15),
hr * sin(th)*(baseFrac-0.15) +
hr * sin(th+120) * (baseFrac+0.15)],
[hr * cos(th+120), hr * sin(th+120)]);
if(th < (h1jump))
if(drawMode == "all" || drawMode == "helix1") color("lightblue")
lineTo([hr * cos(th), hr * sin(th)],
[hr * cos(th)*(baseFrac+0.15) +
hr * cos(th+120) * (baseFrac-0.15),
hr * sin(th)*(baseFrac+0.15) +
hr * sin(th+120) * (baseFrac-0.15)]);
if(drawMode == "all" ||
(drawMode == "A" && thisBase == 0) ||
(drawMode == "G" && thisBase == 1) ||
(drawMode == "C" && thisBase == 2) ||
(drawMode == "T" && thisBase == 3)
)
color((thisBase < 1) ? "green" :
(thisBase < 2) ? "gold" :
(thisBase < 3) ? "blue" :
"red")
translate([hr * cos(th)*baseFrac + hr * cos(th+120) * baseFInv,
hr * sin(th)*baseFrac + hr * sin(th+120) * baseFInv])
rotate(180 + bAng + th) if(doPur) {
purine(); } else { pyrimidine(); };
if(drawMode == "all" ||
(drawMode == "A" && thisBase == 3) ||
(drawMode == "G" && thisBase == 2) ||
(drawMode == "C" && thisBase == 1) ||
(drawMode == "T" && thisBase == 0)
)
if(th < (h1jump))
color((thisBase < 1) ? "red" :
(thisBase < 2) ? "blue" :
(thisBase < 3) ? "gold" :
"green")
translate([hr * cos(th)*baseFrac + hr * cos(th+120) * baseFInv,
hr * sin(th)*baseFrac + hr * sin(th+120) * baseFInv])
rotate(bAng+th) if(doPur) {
pyrimidine(); } else { purine(); };
}
}
if(drawMode == "all" || drawMode == "helix1") color("lightblue") {
translate(helix_1[len(helix_1)-1]) sphere(r=bbr, $fn=5);
translate(helix_1[0]) sphere(r=bbr, $fn=5);
}
if(drawMode == "all" || drawMode == "helix2") color("pink") {
translate(helix_2[0]) sphere(r=bbr, $fn=5);
translate(helix_2[len(helix_2)-1]) sphere(r=bbr, $fn=5);
}
}
Licensing
I, the copyright holder of this work, hereby publish it under the following licenses:
w:en:Creative Commons
attribution
Attribution:
SNP model by David Eccles (gringer)
You are free:
to share – to copy, distribute and transmit the work
to remix – to adapt the work
Under the following conditions:
attribution – You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
https://creativecommons.org/licenses/by/4.0 CC BY 4.0 Creative Commons Attribution 4.0 true true
You may select the license of your choice.
Captions English DNA sequence variation in a population. A SNP is just a single nucleotide difference in the genome. The upper DNA molecule differs from the lower DNA molecule at a single base-pair location (a G/A polymorphism)
Items portrayed in this file creator<\/a>"}},"text\/plain":{"en":{"":"creator"}}},"{\"value\":{\"entity-type\":\"property\",\"numeric-id\":2093,\"id\":\"P2093\"},\"type\":\"wikibase-entityid\"}":{"text\/html":{"en":{"":"
author name string<\/a>"}},"text\/plain":{"en":{"":"author name string"}}},"{\"value\":\"Gringer\",\"type\":\"string\"}":{"text\/html":{"en":{"P2093":"Gringer","P4174":" Gringer<\/a>"}},"text\/plain":{"en":{"P2093":"Gringer","P4174":"Gringer"}}},"{\"value\":{\"entity-type\":\"property\",\"numeric-id\":4174,\"id\":\"P4174\"},\"type\":\"wikibase-entityid\"}":{"text\/html":{"en":{"":" Wikimedia username<\/a>"}},"text\/plain":{"en":{"":"Wikimedia username"}}},"{\"value\":{\"entity-type\":\"property\",\"numeric-id\":2699,\"id\":\"P2699\"},\"type\":\"wikibase-entityid\"}":{"text\/html":{"en":{"":" URL<\/a>"}},"text\/plain":{"en":{"":"URL"}}},"{\"value\":\"http:\\\/\\\/commons.wikimedia.org\\\/wiki\\\/User:Gringer\",\"type\":\"string\"}":{"text\/html":{"en":{"P2699":" http:\/\/commons.wikimedia.org\/wiki\/User:Gringer<\/a>"}},"text\/plain":{"en":{"P2699":"http:\/\/commons.wikimedia.org\/wiki\/User:Gringer"}}}}" class="wbmi-entityview-statementsGroup wbmi-entityview-statementsGroup-P170 oo-ui-layout oo-ui-panelLayout oo-ui-panelLayout-framed"> copyright license<\/a>"}},"text\/plain":{"en":{"":"copyright license"}}},"{\"value\":{\"entity-type\":\"item\",\"numeric-id\":50829104,\"id\":\"Q50829104\"},\"type\":\"wikibase-entityid\"}":{"text\/html":{"en":{"P275":"
GNU Free Documentation License, version 1.2 or later<\/a>"}},"text\/plain":{"en":{"P275":"GNU Free Documentation License, version 1.2 or later"}}},"{\"value\":{\"entity-type\":\"item\",\"numeric-id\":20007257,\"id\":\"Q20007257\"},\"type\":\"wikibase-entityid\"}":{"text\/html":{"en":{"P275":" Creative Commons Attribution 4.0 International<\/a>"}},"text\/plain":{"en":{"P275":"Creative Commons Attribution 4.0 International"}}}}" class="wbmi-entityview-statementsGroup wbmi-entityview-statementsGroup-P275 oo-ui-layout oo-ui-panelLayout oo-ui-panelLayout-framed"> inception<\/a>"}},"text\/plain":{"en":{"":"inception"}}},"{\"value\":{\"time\":\"+2014年12月18日T00:00:00Z\",\"timezone\":0,\"before\":0,\"after\":0,\"precision\":11,\"calendarmodel\":\"http:\\\/\\\/www.wikidata.org\\\/entity\\\/Q1985727\"},\"type\":\"time\"}":{"text\/html":{"en":{"P571":"18 December 2014"}},"text\/plain":{"en":{"P571":"18 December 2014"}}}}" class="wbmi-entityview-statementsGroup wbmi-entityview-statementsGroup-P571 oo-ui-layout oo-ui-panelLayout oo-ui-panelLayout-framed">
media type<\/a>"}},"text\/plain":{"en":{"":"media type"}}},"{\"value\":\"image\\\/svg+xml\",\"type\":\"string\"}":{"text\/html":{"en":{"P1163":"image\/svg+xml"}},"text\/plain":{"en":{"P1163":"image\/svg+xml"}}}}" class="wbmi-entityview-statementsGroup wbmi-entityview-statementsGroup-P1163 oo-ui-layout oo-ui-panelLayout oo-ui-panelLayout-framed">
data size<\/a>"}},"text\/plain":{"en":{"":"data size"}}},"{\"value\":{\"amount\":\"+1203312\",\"unit\":\"http:\\\/\\\/www.wikidata.org\\\/entity\\\/Q8799\"},\"type\":\"quantity\"}":{"text\/html":{"en":{"P3575":"1,203,312
byte<\/span>"}},"text\/plain":{"en":{"P3575":"1,203,312 byte"}}}}" class="wbmi-entityview-statementsGroup wbmi-entityview-statementsGroup-P3575 oo-ui-layout oo-ui-panelLayout oo-ui-panelLayout-framed"> height<\/a>"}},"text\/plain":{"en":{"":"height"}}},"{\"value\":{\"amount\":\"+333\",\"unit\":\"http:\\\/\\\/www.wikidata.org\\\/entity\\\/Q355198\"},\"type\":\"quantity\"}":{"text\/html":{"en":{"P2048":"333
pixel<\/span>"}},"text\/plain":{"en":{"P2048":"333 pixel"}}}}" class="wbmi-entityview-statementsGroup wbmi-entityview-statementsGroup-P2048 oo-ui-layout oo-ui-panelLayout oo-ui-panelLayout-framed"> width<\/a>"}},"text\/plain":{"en":{"":"width"}}},"{\"value\":{\"amount\":\"+520\",\"unit\":\"http:\\\/\\\/www.wikidata.org\\\/entity\\\/Q355198\"},\"type\":\"quantity\"}":{"text\/html":{"en":{"P2049":"520
pixel<\/span>"}},"text\/plain":{"en":{"P2049":"520 pixel"}}}}" class="wbmi-entityview-statementsGroup wbmi-entityview-statementsGroup-P2049 oo-ui-layout oo-ui-panelLayout oo-ui-panelLayout-framed"> checksum<\/a>"}},"text\/plain":{"en":{"":"checksum"}}},"{\"value\":\"80e2618911371d2da8252d8edc5d36cf8c929c94\",\"type\":\"string\"}":{"text\/html":{"en":{"P4092":"80e2618911371d2da8252d8edc5d36cf8c929c94"}},"text\/plain":{"en":{"P4092":"80e2618911371d2da8252d8edc5d36cf8c929c94"}}},"{\"value\":{\"entity-type\":\"property\",\"numeric-id\":459,\"id\":\"P459\"},\"type\":\"wikibase-entityid\"}":{"text\/html":{"en":{"":"
determination method or standard<\/a>"}},"text\/plain":{"en":{"":"determination method or standard"}}},"{\"value\":{\"entity-type\":\"item\",\"numeric-id\":13414952,\"id\":\"Q13414952\"},\"type\":\"wikibase-entityid\"}":{"text\/html":{"en":{"P459":" SHA-1<\/a>"}},"text\/plain":{"en":{"P459":"SHA-1"}}}}" class="wbmi-entityview-statementsGroup wbmi-entityview-statementsGroup-P4092 oo-ui-layout oo-ui-panelLayout oo-ui-panelLayout-framed">
80e2618911371d2da8252d8edc5d36cf8c929c94