How to change text size using picker in swiftui - iphone

I am a beginner level in swiftui. I begin a bible app as a starter's project. I create a Setting and from that setting, I want to change my font size by using a picker. It's been 4 days that I am searching online for a solution, and I couldn't figure out what should I do.
Question 1: I don't know how to update the font size based on the picker selection. Some say to use .onChange, but I don't know how to do it. So, I tried using a switch case method, but still don't know how to update the text. Also, I tried using custom modifiers to replace .font(.footnote) something like that. But still, I don't know how to update it and EnvironmentalObject doesn't helpful at all. Please guide me on how to solve the issue.
Question 2: Every time I play the canvas, the picker selection always starts from the default index which makes sense. But in the actual app, does it always starts with the default index after the user selected a different index or what should I do in order to keep the preselected index.
Here is my code:
import SwiftUI
struct Setting: View {
#State private var fontSizeIndex = 3
#State private var fontIndex = 1
var body: some View {
NavigationView {
ScrollView {
// Text Settings
Form {
// Font Size Picker
Section(header: Text("Text Settings")) {
Picker(selection: $fontSizeIndex, label: Text("Font Size"),
content: {
Text("Extra Small").tag(1)
Text("Small").tag(2)
Text("Medium").tag(3)
Text("Large").tag(4)
Text("Extra Large").tag(5)
})
// Font Picker
// I plan to make custom fonts if I know how to update my
// selection
Picker(selection: $fontIndex, label: Text("Font"), content: {
Text("Font1").tag(1)
Text("Font2").tag(2)
Text("Font3").tag(3)
Text("Font4").tag(4)
Text("Font5").tag(5)
Text("Font6").tag(6)
Text("Font7").tag(7)
})
}
}
.frame(height:280)
}
}
}
This is my Text or Scripture() which is in another view
import SwiftUI
struct Scripture: View {
//#EnvironmentObject var fsc: FontSizeChanging
var body: some View {
ScrollView {
Text("Hih in Zeisu Khazih khang ciamtehna ahi hi. Amah in David tapa hi a, David in Abraham tapa ahi hi. 2 Abraham tapa Isaac, Isaac tapa Jacob, Jacob tapa Judah le a sanggam pasal teng ahi hi. 3 Judah in a zi Tamar tawh a neih a tapa Perez le Zerah, Perez tapa Hezron, Hezron tapa Ram, 4 Ram tapa Amminadab, Amminadab tapa Nahshon, Nahshon tapa Salmon, 5 Salmon in a zi Rahab tawh a neih a tapa Boaz, Boaz in a zi Ruth tawh a neih a tapa Obed, Obed tapa Jesse, 6 Jesse tapa kumpipa David ahi hi. David in Uriah zi tawh a neih a tapa Solomon, 7 Solomon tapa Rehoboam, Rehoboam tapa Abijah, Abijah tapa Asa, 8 Asa tapa Jehoshaphat, Jehoshaphat tapa Joram, Joram tapa Uzziah, 9 Uzziah tapa Jotham, Jotham tapa Ahaz, Ahaz tapa Hezekiah, 10 Hezekiah tapa Manasseh, Manasseh tapa Amon, Amon tapa Josiah ahi hi. 11 Jeconiah le a sanggam pasal tengin Babylon gamah sala a kipaipih madeuh in a suak Josiah tate ahi uh hi. 12 Babylon gama saltan khit ciangin Jeconiah in a neih a tapa Shealtiel, Shealtiel tapa Zerubbabel, 13 Zerubbabel tapa Abiud, Abiud tapa Eliakim, Eliakim tapa Azor, 14 Azor tapa Zadok, Zadok tapa Achim, Achim tapa Eliud, 15 Eliud tapa Eleazar, Eleazar tapa Matthan, Matthan tapa Jacob, 16 Jacob tapa Joseph hi a, Joseph in Khazih a kici Zeisu a hong suahna Mary pasal ahi hi. 17 Tua hi a, Abraham khang panin David khang ciang a vekin khang sawm le khang li, David khang panin Babylon gama saltang dinga a kimat hun ciang khang sawm le khang li, Babylon gama saltan hun pan Khazih khang ciang khang sawm le khang li mah ahi hi. 18 Zeisu Khazih a suahzia hih bang ahi hi. A nu Mary pen Joseph zi dingin zuthawl kipiasa hi a, a kiteenma un Kha Siangtho hangin gai hi ci in kithei hi. 19 A lawmpa Joseph in mi lungsim hoih hi a, a lawmnu Mary min daisak nuamlo ahih manin maksim dingin a ngaihsun hi.")
//.font(fsc.fontSize)
.foregroundColor(.primary)
//.font(Setting(fontSizeIndex: self.$fontSizeIndex))
.multilineTextAlignment(.leading) // test .center here
.lineSpacing(5)
.padding()
}
}
}
struct Scripture_Previews: PreviewProvider {
static var previews: some View {
Scripture()
}
}

The following should work.
I added a gear icon on the top right of the screen to make navigation between the Settings and Scripture easier. This will allow you to change the font size with ease.
My approach uses #AppStorage. This saves the data, so when the user launches the app, their font size choice will remain. You can use this anywhere you have to edit the font size.
To change the font sizes, just update the values within the .tag() inside your picker. I picked a random set of numbers. This is where you want to enter the desired font sizes.
import SwiftUI
struct Setting: View {
#State private var fontSizeIndex = 3
#State private var fontIndex = 1
#AppStorage("fontSize") var fontSize = 50
var body: some View {
NavigationView {
ScrollView {
// Text Settings
Form {
// Font Size Picker
Section(header: Text("Text Settings")) {
Picker(selection: $fontSize, label: Text("Font Size"),
content: {
Text("Extra Small").tag(10)
Text("Small").tag(15)
Text("Medium").tag(20)
Text("Large").tag(25)
Text("Extra Large").tag(50)
})
// Font Picker
// I plan to make custom fonts if I know how to update my
// selection
Picker(selection: $fontIndex, label: Text("Font"), content: {
Text("Font1").tag(1)
Text("Font2").tag(2)
Text("Font3").tag(3)
Text("Font4").tag(4)
Text("Font5").tag(5)
Text("Font6").tag(6)
Text("Font7").tag(7)
})
}
}
.frame(height:280)
}
}
}
}
struct Scripture: View {
//#EnvironmentObject var fsc: FontSizeChanging
#AppStorage("fontSize") var fontSize = 50
var body: some View {
NavigationView {
ScrollView {
Text("Hih in Zeisu Khazih khang ciamtehna ahi hi. Amah in David tapa hi a, David in Abraham tapa ahi hi. 2 Abraham tapa Isaac, Isaac tapa Jacob, Jacob tapa Judah le a sanggam pasal teng ahi hi. 3 Judah in a zi Tamar tawh a neih a tapa Perez le Zerah, Perez tapa Hezron, Hezron tapa Ram, 4 Ram tapa Amminadab, Amminadab tapa Nahshon, Nahshon tapa Salmon, 5 Salmon in a zi Rahab tawh a neih a tapa Boaz, Boaz in a zi Ruth tawh a neih a tapa Obed, Obed tapa Jesse, 6 Jesse tapa kumpipa David ahi hi. David in Uriah zi tawh a neih a tapa Solomon, 7 Solomon tapa Rehoboam, Rehoboam tapa Abijah, Abijah tapa Asa, 8 Asa tapa Jehoshaphat, Jehoshaphat tapa Joram, Joram tapa Uzziah, 9 Uzziah tapa Jotham, Jotham tapa Ahaz, Ahaz tapa Hezekiah, 10 Hezekiah tapa Manasseh, Manasseh tapa Amon, Amon tapa Josiah ahi hi. 11 Jeconiah le a sanggam pasal tengin Babylon gamah sala a kipaipih madeuh in a suak Josiah tate ahi uh hi. 12 Babylon gama saltan khit ciangin Jeconiah in a neih a tapa Shealtiel, Shealtiel tapa Zerubbabel, 13 Zerubbabel tapa Abiud, Abiud tapa Eliakim, Eliakim tapa Azor, 14 Azor tapa Zadok, Zadok tapa Achim, Achim tapa Eliud, 15 Eliud tapa Eleazar, Eleazar tapa Matthan, Matthan tapa Jacob, 16 Jacob tapa Joseph hi a, Joseph in Khazih a kici Zeisu a hong suahna Mary pasal ahi hi. 17 Tua hi a, Abraham khang panin David khang ciang a vekin khang sawm le khang li, David khang panin Babylon gama saltang dinga a kimat hun ciang khang sawm le khang li, Babylon gama saltan hun pan Khazih khang ciang khang sawm le khang li mah ahi hi. 18 Zeisu Khazih a suahzia hih bang ahi hi. A nu Mary pen Joseph zi dingin zuthawl kipiasa hi a, a kiteenma un Kha Siangtho hangin gai hi ci in kithei hi. 19 A lawmpa Joseph in mi lungsim hoih hi a, a lawmnu Mary min daisak nuamlo ahih manin maksim dingin a ngaihsun hi.")
//.font(fsc.fontSize)
.font(.system(size: CGFloat(fontSize)))
.foregroundColor(.primary)
//.font(Setting(fontSizeIndex: self.$fontSizeIndex))
.multilineTextAlignment(.leading) // test .center here
.lineSpacing(5)
.padding()
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
HStack {
NavigationLink(destination: Setting(), label: {
Image(systemName: "gearshape")
})
}
}
}
}
}
}
struct Scripture_Previews: PreviewProvider {
static var previews: some View {
Scripture()
}
}

Related

Copy the elements

I am trying to copy the elements if an atray.
I have written the code below which returns the values stored in src in inverse and I can't find a way to return the elements in dest in the same order:
0 1 2 3 4 5 6 7 8 9
9 8 7 6 5 4 3 2 1 0
Here is my code:
.data
n: .word 10
src: .word 0 1 2 3 4 5 6 7 8 9
dest: .space 40
i: .word 0
space: .asciiz " "
.text
main:
la $t0, src
lw $t1, i
la $t2, dest
lw $t4, n
jal Function_CopytoStack
jal Function_copyfrom_Stack_to_Dest
###############################################
Function_CopytoStack:
################################################
###################
The second half works by (a) popping one item off the stack, then (b) storing that into an pointer, which starts at the beginning of the destination and advances forward.
Do the (b) part backwards, to accomplish a double reversal, which will cancel out the first reversal from the stack use.

Reading .txt. data in Matlab

I have a very basic table
Alcohol Tobacco
6.47 4.03
6.13 3.76
6.19 3.77
4.89 3.34
5.63 3.47
4.52 2.92
5.89 3.20
4.79 2.71
5.27 3.53
6.08 4.51
4.02 4.56
I have tried reading it in using textscan but get blank.
fileID = fopen('TabaccoAlcohol.txt');
C_text = textscan(fileID,'%n',2);
It would be nice in the program using the headings as objects, e.g. Alcohol would be all 11 rows of data. I know Matlab can do this but I can't make it work. Please help.
Use readtable:
>> t = readtable('data.txt')
t =
Alcohol Tobacco
_______ _______
6.47 4.03
6.13 3.76
6.19 3.77
4.89 3.34
5.63 3.47
4.52 2.92
5.89 3.2
4.79 2.71
5.27 3.53
6.08 4.51
4.02 4.56
>> t.Alcohol
ans =
6.4700
6.1300
6.1900
4.8900
5.6300
4.5200
5.8900
4.7900
5.2700
6.0800
4.0200
You can change your code with this code is given below
fileID = fopen('read.txt');
C_text = textscan(fileID,' %f %f');
fclose(fileID);

PostgreSQL: Summing info from Two Aggregated Tables

There is something wrong with my method or my logic here.
I am trying to sum all the data from both tables. If the two correspond, add them up, if either doesn't correspond, still show the individual query total, ending up with estimates per year in sequence.
I have tried LEFT JOINS, FULL JOINS, (UNIONS). Nothing comes close to just summing where possible and supplying the data otherwise.
The key point here is pb and th_year information are years when the results are needed.
The error must be obvious in my code.
The separate aggregate queries produce the correct results.
Its the combining of the two queries where I am going wrong.
Would appreciate advice on this.
I thought it would be simple.
I think it probably is simple. Just stupidity on my side.
CREATE VIEW public.cf_th_data_totals_by_year_by_wc_2
AS SELECT
a.owner,
a.region,
a.district,
a.plantation,
b.th_year,
a.pb,
a.wc,
sum(a.tcf_calcarea + b.tth_calcarea) AS area,
sum(a.tcf_total + b.tth_total) AS total,
sum(a.tcf_ws + b.tth_ws) AS ws,
sum(a.tcf_util + b.tth_util) AS util,
sum(a.tcf_s + b.tth_s) AS s,
sum(a.tcf_a + b.tth_a) AS a,
sum(a.tcf_b + b.tth_b) AS b,
sum(a.tcf_c + b.tth_c) AS c,
sum(a.tcf_d + b.tth_d) AS d
FROM
(SELECT
cfdata.owner,
cfdata.region,
cfdata.district,
cfdata.plantation,
cfdata.pb,
cfdata.wc,
sum(cfdata.calcarea)AS tcf_calcarea,
sum(cfdata._ba) AS tcf_ba,
sum(cfdata._total) AS tcf_total,
sum( cfdata._ws) AS tcf_ws,
sum( cfdata._util) AS tcf_util,
sum( cfdata._s) AS tcf_s,
sum( cfdata._a) AS tcf_a,
sum( cfdata._b) AS tcf_b,
sum( cfdata._c) AS tcf_c,
sum( cfdata._d) AS tcf_d
FROM cfdata
GROUP BY cfdata.owner, cfdata.region, cfdata.district, cfdata.plantation, cfdata.pb, cfdata.wc
ORDER BY cfdata.owner, cfdata.region, cfdata.district, cfdata.plantation, cfdata.pb, cfdata.wc) a
JOIN
(SELECT
thdata.owner,
thdata.region,
thdata.district,
thdata.plantation,
thdata.th_year,
thdata.wc,
sum(thdata.calcarea)AS tth_calcarea,
sum(thdata.th_ba) AS tth_ba,
sum(thdata.th_total) AS tth_total,
sum(thdata.th_ws) AS tth_ws,
sum(thdata.th_util) AS tth_util,
sum(thdata.th_s) AS tth_s,
sum(thdata.th_a) AS tth_a,
sum(thdata.th_b) AS tth_b,
sum(thdata.th_c) AS tth_c,
sum(thdata.th_d) AS tth_d
FROM thdata
GROUP BY thdata.owner, thdata.region, thdata.district, thdata.plantation, thdata.th_year, thdata.wc
ORDER BY thdata.owner, thdata.region, thdata.district, thdata.plantation, thdata.th_year, thdata.wc) b
ON a.owner = b.owner AND a.region = b.region AND a.district = b.district and a.plantation = b.plantation AND a.pb = b.th_year AND a.wc = b.wc
GROUP BY a.owner, a.region, a.district, a.plantation, a.pb, b.th_year, a.wc
ORDER BY a.owner, a.region, a.district, a.plantation, a.pb, b.th_year, a.wc
thdata sample:
owner region district plantation compartment calcarea wc plantdate th_year th_age th_dbh th_ht th_vtree th_sph th_ba th_total th_ws th_util th_s th_a th_b th_c th_d thdata_id
KeyProjects Northern Marshlands River Glen A27 14.02 PFN 01/08/2009 2017 8 12.3 7.3 0.0289 179 28 70 14 56 42 14 0 0 0 1
KeyProjects Northern Marshlands River Glen A28 2.1 ESN 01/12/2010 2012 2 4.5 4.2 0 479 2 0 0 0 0 0 0 0 0 2
KeyProjects Northern Marshlands River Glen A28 2.1 ESN 01/12/2010 2014 4 10.2 9.6 0.0188 250 4 11 0 8 4 6 0 0 0 3
KeyProjects Northern Marshlands River Glen A29 2.71 ESN 01/08/2009 2011 2 4.5 4.2 0 479 3 0 0 0 0 0 0 0 0 4
KeyProjects Northern Marshlands River Glen A29 2.71 ESN 01/08/2009 2013 4 10.2 9.6 0.0188 250 5 14 0 11 5 8 0 0 0 5
thdata sample:
owner region district plantation compartment wc pb calcarea cfage dbh ht vtree sph _ba _total _ws _util _s _a _b _c _d tmai umai smai cfdata_id
KeyProjects Northern Marshlands River Glen A01 EF1 2021 5.27 10 14.5 20.4 0.1109 1004 90 585 21 564 84 401 79 0 0 11.1 10.7 1.5 1
KeyProjects Northern Marshlands River Glen A02 EF1 2021 36.1 10 14.5 20.4 0.1109 1004 614 4007 144 3863 578 2744 542 0 0 11.1 10.7 1.5 2
KeyProjects Northern Marshlands River Glen A03 EF1 2021 5.5 10 14.5 20.4 0.1109 1004 94 611 22 589 88 418 83 0 0 11.1 10.7 1.5 3
KeyProjects Northern Marshlands River Glen A04 EF1 2021 11.91 10 14.5 20.4 0.1109 1004 202 1322 48 1274 191 905 179 0 0 11.1 10.7 1.5 4
KeyProjects Northern Marshlands River Glen A05 EF1 2022 39.17 11 14.9 21.8 0.1286 1000 705 5053 157 4857 666 3486 744 0 0 11.7 11.3 1.7 5
expected result:
owner region district plantation th_year pb wc area total ws util s a b c d
KeyProjects Northern Marshlands River Glen 2008 2008 EF1 620.49 44176 1788 42389 7562 31953 2852 0 0
KeyProjects Northern Marshlands River Glen 2009 2009 EF1 635.65 44319 1778 42476 7634 31993 2852 0 0
KeyProjects Northern Marshlands River Glen 2010 2010 EF1 1202.31 87980 3453 84487 14906 63883 5704 0 0
KeyProjects Northern Marshlands River Glen 2011 2011 EF1 1948.37 132378 5275 127104 22662 95895 8556 0 0
KeyProjects Northern Marshlands River Glen 2012 2012 EF1 1378.61 87928 3429 84477 14878 63922 5704 0 0
Ok, you have a few issues with your query:
In the main query, do not use sum(a.tcf_calcarea + b.tth_calcarea) AS area. You can simply add but you should make sure to substitute any NULL values with 0 first: write coalesce(a.tcf_calcarea, 0) + coalesce(b.tth_calcarea, 0) AS area instead, for all sum()s. This also means you are not aggregating anymore at this level, so you should drop the final GROUP BY clause.
Now make a FULL OUTER JOIN between the two sub-queries. This means you get all rows from both sub-queries joined and where a corresponding row does not exist for either side, there are NULLs for column values.
It makes no sense to ORDER BY in a sub-query, the planner will process the row set in the way it sees best. You should order at the outer level only.
By definition (join condition) b.th_year = a.pb so you can drop one of the two columns.
Some syntactical pointers:
Your sub-queries use only one table so there is no need to work with table aliases, saves you a lot a typing.
More savings: Use positional parameters in your GROUP BY clause, so you can write GROUP BY 1, 2, 3, 4, 5, 6. Same with ORDER BY.
On the JOIN clause you can write USING (owner, region, district, plantation, wc) and then add WHERE a.pb = b.th_year. Other than that being shorter, you do not need sub-query aliases in the main query anymore for any of the USING columns. However, the fact that one join condition does not have corresponding column names does make things slightly more confused; up to you.
All in all, this is what you get:
CREATE VIEW public.cf_th_data_totals_by_year_by_wc_2 AS
SELECT owner, region, district, plantation, b.th_year, wc,
coalesce(a.tcf_calcarea, 0) + coalesce(b.tth_calcarea, 0) AS area,
...
FROM (
SELECT owner, region, district, plantation, pb, wc,
sum(calcarea) AS tcf_calcarea,
...
FROM cfdata
GROUP BY 1, 2, 3, 4, 5, 6) a
FULL JOIN (
SELECT owner, region, district, plantation, th_year, wc,
sum(calcarea) AS tth_calcarea,
...
FROM thdata
GROUP BY 1, 2, 3, 4, 5, 6) b
USING (owner, region, district, plantation, wc)
WHERE a.pb = b.th_year
ORDER BY 1, 2, 3, 4, 5, 6;

Edit text columns

I have a text file (the first two lines are character spacings):
1 2 3 4 5 6 7 8
12345678901234567890123456789012345678901234567890123456789012345678901234567890
ATOM 1 N1 SPINA 3 30.616 29.799 14.979 1.00 20.00 S N
ATOM 2 N1 SPINA 3 28.146 28.381 13.950 1.00 20.00 S N
ATOM 3 N1 SPINA 3 27.605 28.239 14.037 1.00 20.00 S N
ATOM 4 N1 SPINA 3 30.333 29.182 15.464 1.00 20.00 S N
ATOM 5 N1 SPINA 3 29.608 29.434 14.333 1.00 20.00 S N
ATOM 6 N1 SPINA 3 29.303 29.830 13.317 1.00 20.00 S N
ATOM 7 N1 SPINA 3 28.963 31.116 13.472 1.00 20.00 S N
ATOM 8 N1 SPINA 3 28.859 28.743 13.828 1.00 20.00 S N
ATOM 9 N1 SPINA 3 29.699 30.575 14.564 1.00 20.00 S N
ATOM 10 N1 SPINA 3 29.518 29.194 15.301 1.00 20.00 S N
I want to edit it and make it like:
1 2 3 4 5 6 7 8
12345678901234567890123456789012345678901234567890123456789012345678901234567890
ATOM 1 N001 SPINA 3 30.616 29.799 14.979 1.00 20.00 S N
ATOM 2 N002 SPINA 3 28.146 28.381 13.950 1.00 20.00 S N
ATOM 3 N003 SPINA 3 27.605 28.239 14.037 1.00 20.00 S N
ATOM 4 N004 SPINA 3 30.333 29.182 15.464 1.00 20.00 S N
ATOM 5 N005 SPINA 3 29.608 29.434 14.333 1.00 20.00 S N
ATOM 6 N006 SPINA 3 29.303 29.830 13.317 1.00 20.00 S N
ATOM 7 N007 SPINA 3 28.963 31.116 13.472 1.00 20.00 S N
ATOM 8 N008 SPINA 3 28.859 28.743 13.828 1.00 20.00 S N
ATOM 9 N009 SPINA 3 29.699 30.575 14.564 1.00 20.00 S N
ATOM 10 N010 SPINA 3 29.518 29.194 15.301 1.00 20.00 S N
The number of spaces between each column are important and the list of atoms needs to go up to 190 (N001-N190). Thus I would like to replace characters 13-16 (" N1 ") in file 1 with ("N001") and keep the remainder of the file in the original spacing.
You don't need 10 long lines of sample input to demonstrate the problem or the solution:
$ cat file
ATOM 1 N1 SPINA 3
ATOM 2 N1 SPINA 3
ATOM 10 N1 SPINA 3
$ awk '{print substr($0,1,12) sprintf("N%03d",$2) substr($0,17)}' file
ATOM 1 N001 SPINA 3
ATOM 2 N002 SPINA 3
ATOM 10 N010 SPINA 3
I'm assuming we could use $2 as the numeric part of the 3rd field. It seems to increment sequentially with your line numbers. Using NR might be an alternative. If neither of those is actually what you want, post some more representative sample input/output.
Also, note that any solution that involves assigning to a field (e.g. $3=...) WILL cause awk to recompile the line using the value of OFS as the field separator and so will change your spacing.
Oh, and if those 2 initial lines of character spacings are really present in your files, this is the tweak:
$ cat file
1 2
12345678901234567890123456
ATOM 1 N1 SPINA 3
ATOM 2 N1 SPINA 3
ATOM 10 N1 SPINA 3
$ awk 'NR>2{$0 = substr($0,1,12) sprintf("N%03d",$2) substr($0,17)} 1' file
1 2
12345678901234567890123456
ATOM 1 N001 SPINA 3
ATOM 2 N002 SPINA 3
ATOM 10 N010 SPINA 3
Try :
$ awk '{$3=substr($3,1,1) sprintf("%03d",$2)}1' OFS=\\t file
Note : OFS will be tab
If you want to try this on a Solaris/SunOS system, change awk to /usr/xpg4/bin/awk , /usr/xpg6/bin/awk , or nawk
--edit--
if you want to increment with line
$ awk '{$3=substr($3,1,1) sprintf("%03d",NR)}1' OFS=\\t file
Here is yet another way:
awk 'sub(/.$/,sprintf("%03d",NR),$3)' OFS='\t' file
Output:
$ awk 'sub(/.$/,sprintf("%03d",NR),$3)' OFS='\t' file
ATOM 1 N001 SPINA 3 30.616 29.799 14.979 1.00 20.00 S N
ATOM 2 N002 SPINA 3 28.146 28.381 13.950 1.00 20.00 S N
ATOM 3 N003 SPINA 3 27.605 28.239 14.037 1.00 20.00 S N
ATOM 4 N004 SPINA 3 30.333 29.182 15.464 1.00 20.00 S N
ATOM 5 N005 SPINA 3 29.608 29.434 14.333 1.00 20.00 S N
ATOM 6 N006 SPINA 3 29.303 29.830 13.317 1.00 20.00 S N
ATOM 7 N007 SPINA 3 28.963 31.116 13.472 1.00 20.00 S N
ATOM 8 N008 SPINA 3 28.859 28.743 13.828 1.00 20.00 S N
ATOM 9 N009 SPINA 3 29.699 30.575 14.564 1.00 20.00 S N
ATOM 10 N010 SPINA 3 29.518 29.194 15.301 1.00 20.00 S N
If you are interesting to resolve it with pure shell, here is the code:
while IFS="\n" read -r line
do
n=${line:9:3}
printf "%sN%03d%s\n" "${line:0:12}" $n "${line:16}"
done < file
awk '$3="N"sprintf("%03d",$2)' OFS='\t' infile.txt
Result
ATOM 1 N001 SPINA 3 30.616 29.799 14.979 1.00 20.00SN
ATOM 2 N002 SPINA 3 28.146 28.381 13.950 1.00 20.00SN
ATOM 3 N003 SPINA 3 27.605 28.239 14.037 1.00 20.00SN
ATOM 4 N004 SPINA 3 30.333 29.182 15.464 1.00 20.00SN
ATOM 5 N005 SPINA 3 29.608 29.434 14.333 1.00 20.00SN
ATOM 6 N006 SPINA 3 29.303 29.830 13.317 1.00 20.00SN
ATOM 7 N007 SPINA 3 28.963 31.116 13.472 1.00 20.00SN
ATOM 8 N008 SPINA 3 28.859 28.743 13.828 1.00 20.00SN
ATOM 9 N009 SPINA 3 29.699 30.575 14.564 1.00 20.00SN
ATOM 10 N010 SPINA 3 29.518 29.194 15.301 1.00 20.00SN

Perspective projection of a 3D model to a 2D plane

I'm trying to project a 3D model to a 2D plane and I found I should use the projection equation C*((R*X)+T) to do so. C, which is the camera calibration matrix is calculated as follows:
C =[f 0 px;
0 f py;
0 0 1];
First, I want to ask about the focal length f used in the camera calibration matrix. Should I use it with the value in pixels or mm? If in mm how can I get it?
Second I don't really know what the px and py variables stand for I got some information about the data I'm working on bye the exifread function in MATLAB and these are the information I got:
Sharpness: 0
Contrast: 0
SceneCaptureType: 0
FocalLengthIn35mmFilm: 27
DigitalZoomRatio: 1
WhiteBalance: 0
ExposureMode: 0
SceneType: 1
FileSource: 3
SensingMethod: 2
PixelYDimension: 3000
PixelXDimension: 4000
ColorSpace: 1
FlashpixVersion: '0100'
FocalLength: 4.9000
Flash: 1
LightSource: 0
MeteringMode: 4
MaxApertureValue: 3.6150
ExposureBiasValue: 0
ApertureValue: 3.6150
ShutterSpeedValue: 2.3220
CompressedBitsPerPixel: 2.8149
ComponentsConfiguration: [1 2 3 0]
DateTimeDigitized: '2011:06:26 16:55:08'
DateTimeOriginal: '2011:06:26 16:55:08'
ExifVersion: '0221'
ISOSpeedRatings: 100
ExposureProgram: 2
FNumber: 3.5000
ExposureTime: 0.2000
Copyright: 'Copyright 2010'
YCbCrPositioning: 2
DateTime: '2011:06:26 16:55:08'
Software: ' 0.8913'
ResolutionUnit: 2
YResolution: 96
XResolution: 96
Orientation: 1
Model: 'SAMSUNG ES30/VLUU ES30'
Make: 'SAMSUNG'
Thumbnail: [1x1 struct]
Do px and py refer to any of them?
px and py are the coordinates of the principal point. On an ideal camera that would be the center of the image, so you can use width/2, height/2 for a start. For actual values you should use a calibration algorithm.
f should be in pixels.